定义:动态地给一个对象添加一些额外的职责。
就增加功能来说, 装饰模式相比生成子类更为灵活。
装饰模式的优点
● 装饰类和被装饰类可以独立发展, 而不会相互耦合。 换句话说, Component类无须知
道Decorator类, Decorator类是从外部来扩展Component类的功能, 而Decorator也不用知道具
体的构件。
● 装饰模式是继承关系的一个替代方案。 我们看装饰类Decorator, 不管装饰多少层, 返
回的对象还是Component, 实现的还是is-a的关系。
● 装饰模式可以动态地扩展一个实现类的功能, 这不需要多说, 装饰模式的定义就是如
此。
装饰模式的缺点
对于装饰模式记住一点就足够了: 多层的装饰是比较复杂的。 为什么会复杂呢? 你想想
看, 就像剥洋葱一样, 你剥到了最后才发现是最里层的装饰出现了问题, 想象一下工作量
吧, 因此, 尽量减少装饰类的数量, 以便降低系统的复杂度。
装饰模式的使用场景
● 需要扩展一个类的功能, 或给一个类增加附加功能。
● 需要动态地给一个对象增加功能, 这些功能可以再动态地撤销。
● 需要为一批的兄弟类进行改装或加装功能, 当然是首选装饰模式。
最佳实践
装饰模式是对继承的有力补充。 你要知道继承不是万能的, 继承可以解决实际的问题,
但是在项目中你要考虑诸如易维护、 易扩展、 易复用等, 而且在一些情况下( 比如上面那个
成绩单例子) 你要是用继承就会增加很多子类, 而且灵活性非常差, 那当然维护也不容易
了, 也就是说装饰模式可以替代继承, 解决我们类膨胀的问题。 同时, 你还要知道继承是静
态地给类增加功能, 而装饰模式则是动态地增加功能, 在上面的那个例子中, 我不想要
SortDecorator这层的封装也很简单, 于是直接在Father中去掉就可以了, 如果你用继承就必须
修改程序。
装饰模式还有一个非常好的优点: 扩展性非常好。 在一个项目中, 你会有非常多的因素
考虑不到, 特别是业务的变更, 不时地冒出一个需求, 尤其是提出一个令项目大量延迟的需
求时, 那种心情是相当的难受! 装饰模式可以给我们很好的帮助, 通过装饰模式重新封装一
个类, 而不是通过继承来完成, 简单点说, 三个继承关系Father、 Son、 GrandSon三个类, 我
要在Son类上增强一些功能怎么办? 我想你会坚决地顶回去! 不允许, 对了, 为什么呢? 你
增强的功能是修改Son类中的方法吗? 增加方法吗? 对GrandSon的影响呢? 特别是GrandSon
有多个的情况, 你会怎么办? 这个评估的工作量就够你受的, 所以这是不允许的, 那还是要
解决问题的呀, 怎么办? 通过建立SonDecorator类来修饰Son, 相当于创建了一个新的类, 这
个对原有程序没有变更, 通过扩展很好地完成了这次变更。
package cn.yang.test.controller.DesignPattern;
/**
* Created by Dev_yang on 2016/3/1.
*/
public class 装饰模式 {
public static void main(String[] args) {
ConcreteComponont concreteComponont = new ConcreteComponont();
ConcreteDecorator1 concreteDecorator1 = new ConcreteDecorator1(concreteComponont);
ConcreteDecorator2 concreteDecorator2 = new ConcreteDecorator2(concreteDecorator1);
concreteDecorator2.operate();
}
}
abstract class Componont{
public abstract void operate();
}
class ConcreteComponont extends Componont{
@Override
public void operate() {
System.out.println("被装饰者最终被执行了!!");
}
}
abstract class Decorator extends Componont{
private Componont componont;
public Decorator(Componont componont) {
this.componont = componont;
}
@Override
final public void operate() {
decorateMethod();
componont.operate();
}
protected abstract void decorateMethod();
}
class ConcreteDecorator1 extends Decorator{
public ConcreteDecorator1(Componont componont) {
super(componont);
}
@Override
protected void decorateMethod() {
System.out.println("被ConcreteDecorator1装饰了");
}
}
class ConcreteDecorator2 extends Decorator{
public ConcreteDecorator2(Componont componont) {
super(componont);
}
@Override
protected void decorateMethod() {
System.out.println("被ConcreteDecorator2装饰了");
}
}
/**
执行结果:
被ConcreteDecorator2装饰了
被ConcreteDecorator1装饰了
被装饰者最终被执行了!!
**/