1. 定义
- 也叫包装模式
- 动态的给一个对象添加一下额外的职责,就增加功能来说,装饰模式相比生成子类更为灵活
- 使用一种对客户端透明的方式来动态的扩展对象的功能,也是继承关系的一种替代方案
- 与代理模式的区别:装饰模式是为所装饰的对象增强功能;代理模式则是对代理的对象施加控,,但不对对象本身的功能进行增强;
2. 使用场景
- 需要透明且动态的扩张类的功能时
- 动态增加,动态撤销
3. 优缺点
- 优点:动态扩展一个实现类的功能,装饰类和被装饰类可以独立发展,不会相互耦合
- 缺点:多层装饰比较复杂
4. Android源码中的使用
在Android中有以下继承关系,Context是抽象类,而下面三者这可以看作其装饰类
- Activity-->ContextThemeWrapper-->ContextWrapper-->Context
- Service-->ContextWrapper-->Context
- Application-->ContextWrapper-->Context
5. 实例演示
以人们穿衣服为例
- 创建一个People类,只有一个通用的方法--穿内裤
public class People {
//穿着
public void dressed() {
LjyLogUtil.i("穿了内裤哦");
}
}
- 创建一个装饰器基类
public abstract class PeopleCloth extends People {
//持有一个people的引用
protected People mPeople;
public PeopleCloth(People people) {
mPeople = people;
}
@Override
public void dressed() {
mPeople.dressed();
}
}
- 创建装饰器的实现类,一个土豪装饰器,一个乞者装饰器
//土豪装饰器
public class RichCloth extends PeopleCloth {
public RichCloth(People people) {
super(people);
}
//穿T恤
private void dressShirt() {
LjyLogUtil.i("穿件T恤");
}
//穿皮衣
private void dressLeather() {
LjyLogUtil.i("穿皮衣");
}
//穿牛仔裤
private void dressJean() {
LjyLogUtil.i("穿牛仔裤");
}
@Override
public void dressed() {
super.dressed();
dressShirt();
dressLeather();
dressJean();
}
}
//乞者装饰器
public class PoorCloth extends PeopleCloth {
public PoorCloth(People people) {
super(people);
}
//穿短裤
private void dressShorts() {
LjyLogUtil.i("穿短裤");
}
@Override
public void dressed() {
super.dressed();
dressShorts();
}
}
- 创建people实例,并分别用不同的装饰器装饰
private void methodDecoratorPattern() {
People people = new People();
LjyLogUtil.i("PoorCloth:");
PeopleCloth clothPoor = new PoorCloth(people);
clothPoor.dressed();
LjyLogUtil.i("RichCloth:");
PeopleCloth clothRich = new RichCloth(people);
clothRich.dressed();
}
这样同一个实例对象可以自由的切换装饰器,对其穿着进行不同的扩展,耦合性很低,而且不会影响people类本身的继承体系,people可以继续衍生出其他子类,如程序员,产品经理等,还可以复用上面的装饰器进行装饰
网友评论