什么是装饰模式(Decorator):
装饰模式是为已有功能动态的添加更多功能的一种方式;在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象;
装饰模式由4种角色组成:
抽象构件(Component)角色:给出一个抽象接口,以规范准备接收附加职责的对象;
具体构件(Concrete Component)角色:定义一个将要接收附加职责的类;
装饰(Decorator)角色:持有一个构件(Component)对象的实例,并实现一个与抽象构件接口一致的接口,从外类来扩展Component类的功能,但对于Component类来说,是无需知道Decorato的存在的;
具体装饰(Concrete Decorator)角色:负责给构件对象添加上附加的职责;
装饰模式的优点:
1.把类中的装饰功能从类中搬移出去,这样可以简化原有的类;
2.有效的把类的核心职责和装饰功能分开,而且可以去除相关类中重复的装饰逻辑;
3.装饰模式与继承关系的目的都是要扩展对象的功能,但是装饰模式可以提供比继承更多的灵活性;
4.通过使用不同的具体装饰类以及这些装饰类的排列组合,设计师可以创造出很多不同行为的组合;
装饰模式的应用场景,以下引自百度百科:
1. 需要扩展一个类的功能,或给一个类添加附加职责;
2. 需要动态的给一个对象添加功能,这些功能可以再动态的撤销;
3. 需要增加由一些基本功能的排列组合而产生的非常大量的功能,从而使继承关系变的不现实;
4. 当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类;
模式简化
如果只有一个Concrete Component类而没有抽象的Component接口时,可以让Decorator继承Concrete Component;
如果只有一个Concrete Decorator类时,可以将Decorator和Concrete Decorator合并;
UML类图
Demo 来自《大话设计模式》:写一个可以给人搭配不同服饰的系统(简化版的装饰模式)
Person类(ConcreteComponent)
public class Person { public Person(){} String name; public Person(String name){ this.name = name; } public void show(){ System.out.println(name); } }
具体的服饰类(ConcreteDecorator)
/** * 穿垮裤 */ public class WearTrouser extends Finery { @Override public void show() { super.show(); System.out.println("BigTrouser"); } }
/** * T恤 */ public class WearTshirt extends Finery { @Override public void show() { super.show(); System.out.println("Tshirt"); } }
Finery类(Decorator)
/** * 服饰类 */ public abstract class Finery extends Person { protected Person person; public void setPerson(Person person) { this.person = person; } @Override public void show() { if(person != null) person.show(); } }
/** * 装饰模式 * @ClassName: DecoratorPattern */ public class DecoratorPattern { public static void main(String[] args) { Person p = new Person("猴子:"); WearTshirt a = new WearTshirt(); WearTrouser b = new WearTrouser(); a.setPerson(p); b.setPerson(a); b.show(); } }