1.定义: 动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活.
2.UML类图:
Component是定义一个对象接口,可以给这些对象动态地添加职责,ConcreteComponent是定义了一个具体的对象,也可以给这个对象添加一些职责.Decorator,装饰抽象类,继承了Component,从外类来扩展Component类的功能,但对于Component来说,是无需知道Decorator的存在的.至于ConcreteDecorator就是具体的装饰对象,起到给Component添加职责的功能.
装饰者模式是利用SetComponent来对对象进行包装的. 这样每个装饰对象的实现就和如何使用这个对象分离开了,每个装饰对象只关心自己的功能,不需要关心如何被添加到对象链当中.
如果只有一个ConcreteComponent类而没有抽象的Component类,那么Decorator类可以是ConcreteComponent的一个子类.同样道理,如果只有一个ConcreteDecorator类,那么就没有必要建立一个单独的Decorator类,而可以把Decorator和ConcreteDecorator的责任合并成一个类
3.优点:
(1). Decorator模式与继承关系的目的都是要扩展对象的功能,但是Decorator可以提供比继承更多的灵活性。
(2). 通过使用不同的具体装饰类以及这些装饰类的排列组合,设计师可以创造出很多不同行为的组合。
4.缺点:
(1). 这种比继承更加灵活机动的特性,也同时意味着更加多的复杂性。
(2). 装饰模式会导致设计中出现许多小类,如果过度使用,会使程序变得很复杂。
(3). 装饰模式是针对抽象组件(Component)类型编程。但是,如果你要针对具体组件编程时,就应该重新思考你的应用架构,以及装饰者是否合适。当然也可以改变Component接口,增加新的公开的行为,实现“半透明”的装饰者模式。在实际项目中要做出最佳选择。
5, 使用场景:以前当系统需要新功能的时候,是向旧的类中添加新的代码.这些新加的代码通常装饰了原有类的核心职责或主要行为,在主类中加入了新的字段,新的方法和新的逻辑,从而增加了主类的复杂度,而这些新加入的东西仅仅是为了满足一些只在某种特定情况下才会执行的特殊行为的需要.装饰者模式却提供了一个非常好的解决方案,它把每个要装饰的功能放在单独的类中,并让这个类包装它所要装饰的对象,因此,当需要执行特殊行为时,客户代码就可以在运行时根据需要有选择地、按顺序地使用装饰功能包装对象了.
6. 具体实现:
1 /** 2 * @author liuboren 3 * @Title:组件类 4 * @Description: 装饰者模式被装饰的类 5 * @date 2018/5/12 13:44 6 */ 7 public interface Component { 8 9 void operation(); 10 }
1 /** 2 * @author liuboren 3 * @Title:具体的组件类 4 * @Description: 5 * @date 2018/5/12 13:45 6 */ 7 public class ConcreteComponent implements Component { 8 9 @Override 10 public void operation() { 11 System.out.println("这是具体的ConcreteComponent的operation方法"); 12 } 13 }
1 /** 2 * @author liuboren 3 * @Title:装饰者类 4 * @Description: 5 * @date 2018/5/12 13:48 6 */ 7 public abstract class Decorator implements Component { 8 protected Component component; 9 10 public void setComponent(Component component){ 11 this.component = component; 12 } 13 14 @Override 15 public void operation(){ 16 this.component.operation(); 17 } 18 19 }
1 /** 2 * @author liuboren 3 * @Title:具体的装饰者类 4 * @Description: 5 * @date 2018/5/12 13:51 6 */ 7 public class ConcreteDecorator extends Decorator { 8 9 @Override 10 public void operation(){ 11 //之所以能在之前的功能上添加新的功能,全靠这两句话 12 super.operation(); 13 System.out.println("这是具体的装饰者类"); 14 } 15 }
1 /** 2 * @author liuboren 3 * @Title:测试类 4 * @Description: 5 * @date 2018/5/12 13:52 6 */ 7 public class Test { 8 public static void main(String [] args){ 9 Decorator decorator = new ConcreteDecorator(); 10 decorator.setComponent(new ConcreteComponent()); 11 decorator.operation(); 12 } 13 }
测试结果:
github地址: https://github.com/liuboren0617/designpatterns/tree/master/src/decorator