概述
装饰模式(Decorator)也称为包装模式(Wrapper Pattern),是结构型设计模式之一.
其使用一种对客户端透明的方式来动态地扩展对象的功能,同时他也是继承关系的一种替代方案.客户端并不需要知道对象在装饰前和装饰后有什么不同.装饰模式可以在不创建更多子类的情况下将对象的功能加以扩展.
定义
动态的给一个对象添加一些额外的职责.就增加功能来说,装饰模式相比生成子类更为灵活.
使用场景
需要透明且动态的扩展类的功能时.
UML
其中涉及到的角色有:
Component
: 抽象组件,可以是一个接口或抽象类,其充当的就是被装饰的原始对象.ConcreteComponent
: 组件具体实现类,该类是我们装饰的具体对象.Decorator
: 抽象装饰者,担当装饰我们组件对象的责任,内部持有指向组件对象的引用,大多数情况下是抽象类ConcreteDecorator
: 装饰者具体实现类,继承与Decorator
实例
这里模拟一下人穿衣服的场景,没钱的穿便宜衣服,有钱的穿贵衣服
首先定义人的抽象类
- Component
public abstract class Person {
//穿着的抽象方法
public abstract void dressed();
}
- ConcreteComponent,要装饰的对象
public class Boy extends Person {
private static final String TAG = "Boy";
@Override public void dressed() {
Log.d(TAG, "dressed: --->"+"穿了内衣内裤");
}
}
- Decorator
public class PersonCloth extends Person {
protected Person mPerson;
public PersonCloth(Person _person) {
mPerson = _person;
}
@Override public void dressed() {
mPerson.dressed();
}
}
- ConcreteDecorator
// 没钱穿便宜衣服
public class CheapCloth extends PersonCloth {
private static final String TAG = "CheapCloth";
public CheapCloth(Person _person) {
super(_person);
}
private void dressShorts() {
Log.d(TAG, "dressShorts: -->" + "穿条短裤");
}
@Override public void dressed() {
super.dressed();
dressShorts();
}
}
//有钱穿贵衣服
public class ExpensiveCloth extends PersonCloth {
private static final String TAG = "ExpensiveCloth";
public ExpensiveCloth(Person _person) {
super(_person);
}
private void dressShirt() {
Log.d(TAG, "dressShirt: -->" + "穿件短袖");
}
private void dressLeather() {
Log.d(TAG, "dressLeather: -->" + "穿件皮衣");
}
private void dressJean() {
Log.d(TAG, "dressJean: -->" + "穿件牛仔裤");
}
@Override public void dressed() {
super.dressed();
dressShirt();
dressLeather();
dressJean();
}
}
- 客户端调用方法
Person person = new Boy();
//便宜的穿法
PersonCloth clothCheap = new CheapCloth(person);
clothCheap.dressed();
//变有钱了,该穿好点了...
PersonCloth clothExpensive = new ExpensiveCloth(person);
clothExpensive.dressed();
装饰模式特点
- 装饰和继承都可以扩展功能,但是继承是静态的,在系统运行前就决定了,装饰则是动态的扩展功能.
通过不同的装饰类或者装饰组合达到不同的功能拓展,这是继承所没法达到的.
装饰产生的对象结构都非常相似,像是一个模板,使得查错变得困难.