设计模式系列仍旧没结束,让我们继续吧..
装饰者模式是我个人比较喜欢的一个设计模式,为什么这么说呢,使用装饰者模式给我们的程序提供了一种动态扩展的功能,我们可以在不动原有的类的情况下添加新功能,这样,我们甚至能一层套一层最后装饰了好多层,增加了很多功能,而这些功能却能够灵活扩展.
定义
装饰者模式动态地给一个对象添加一些额外的职责。注意:动态的给一个对象,而不是对整个类添加额外职责,说明此模式将采用的结构是组合而不是继承;要给一个对象添加职责,通常可以使用其类的派生类对象替换当前对象,但这显得不够灵活.我们的装饰模式能够更加灵活
应用场景
我们在Android中的主要应用有: 给滚动列表动态添加头部试图啊, 给Adapter动态添加指定动画啊, 拦截一些接口数据等.
在我们代码中,常见的Wrapper
,Decorator
类基本上都是装饰模式的应用.
应用思路
我们以一个人的赚钱功能来举例,我们定义一个赚钱性质的接口,其提供获取金额和增加金额两个方法
接口
interface Money {
int getMoney();
void addMoney(int num);
}
我们生成一个实现类,这个是初始化状态,每个人有100块钱,
class PersonImp implements Money {
int money = 100;
public int getMoney() {
return money;
}
public void addMoney(int num) {
money += num;
}
}
再写一个基础装饰类
abstract class PersonWrapper implements Money {
Money person;
public PersonWrapper(Money money) {
person = money;
}
}
好了,假设现在我们需要让一个Person收益翻倍,代码如下.
class DoublePersonWrapper extends PersonWrapper {
public DoublePersonWrapper(Money money) {
super(money);
}
public int getMoney() {
return person.getMoney();
}
public void addMoney(int num) {
person.addMoney(num * 2);
}
}
那么在应用时:
public static void main(String[] args) {
// 初始化一个有100块钱的小明对象
Money xiaoming = new PersonImp();
xiaoming.addMoney(10);
System.out.println("xiaoming: " + xiaoming.getMoney());
// 小明拥有收益翻倍功能
xiaoming = new DoublePersonWrapper(xiaoming);
xiaoming.addMoney(10);
System.out.println("xiaoming: " + xiaoming.getMoney());
}
xiaoming: 110
xiaoming: 130
实际应用场景
-
Context是Android中对装饰模式的经典应用,具体见另一篇博文深入Context
-
对Adapter进行扩展,对RecyclerView进行扩展,见KeepGank加载更多组件
-
对接口进行拦截扩展 以下是我项目中的一个应用,使用该类的时候会传进来一个接口.我需要在不改变调用方以及接收方逻辑的情况下拦截数据做一些UI逻辑处理,即可这么写.记得一年前我是通过父类提供通知方法通知子类的形式实现的,实在是太挫了. ``` java private class TtsListenerWrapper implements TtsListener { private TtsListener mTtsListener;
public TtsListenerWrapper(TtsListener ttsListener) { mTtsListener = ttsListener; } @Override public void onBegin(int requestId) { mTtsListener.onBegin(requestId); String text = mTtsMap.get(requestId); if (!TextUtils.isEmpty(text)) { showSubtitile(text); mTtsMap.remove(requestId); } } @Override public void onError(int requestId) { mTtsListener.onError(requestId); removeTextWindow(); } @Override public void onEnd(int requestId) { mTtsListener.onEnd(requestId); removeTextWindow(); } }
```
作者:Anderson大码渣,欢迎关注我的简书: Anderson大码渣