装饰模式:用于动态地给一个对象添加一些额外的职责。
一种为类增加功能的方式是:继承原有的类,在重载方法上添加新的职责(或业务逻辑),其实还有一种更好的方法,即为装饰模式。
《大话设计模式》中以给人穿衣服这样的过程,展示了动态穿衣的过程:
以人作为Component:
/** * 例子比较简单,未使用Component的继承 * @author guozw * */ public class Person { private String name; public void show(){ System.out.println(this.name+" wear"); } public void setName(String name) { this.name = name; } }
衣服这一抽象类,用于装饰Person:
/** * 装饰类,继承并组合了Component * @author guozw * */ public abstract class Clothes extends Person { private Person componment; /** * 进行装饰注入,形成链 * @param componmet */ public void Decorate(Person componmet){ this.componment=componmet; } @Override public void show() { componment.show(); } }
各具体子类,覆盖超类的方法。
/** * 各具体子类,覆盖超类的方法 * @author guozw * */ public class TShirt extends Clothes{ @Override public void show() { System.out.println("T-shirt"); super.show(); } } public class BigTrousers extends Clothes { @Override public void show() { System.out.println("Big Trousers"); super.show(); } }
调用的过程,展现了逐步装饰和链式调用的过程
public static void main(String[] args) { Person p = new Person(); p.setName("ABC"); TShirt t = new TShirt(); BigTrousers bt = new BigTrousers(); //逐步装饰 t.Decorate(p); bt.Decorate(t); bt.show();//链式调用 }
调用bt.show()方法将触发多态的链式调用,此例的顺序为 bt->t->person;很明显,后加入的,先被调用。
OK,给出下类图:
通过以上例子,我还想到了一些可以改变的地方:
总结:
使用的场合:当系统需要新功能时,尤其是增加在某种特定情况下才会执行的行为时,可以考虑使用装饰模式。
装饰模式将每个要装饰的功能放在单独的类中,并让这个类包装它所要装饰的对象。当需要执行特殊行为时,客户代码就可以在运行时有选择地,按顺序地使用装饰功能包装到对象。
优点:把类中的装饰功能从原有类中搬移出去,可以简化原有类,可以去除相关类中重复的装饰逻辑,可以任意组合装饰的顺序。
装饰模式最大的特征即为组合并继承某个类,这是多态威力的体现。