GOF23设计模式之装饰模式(decorator)

一、装饰模式概述

  (1)动态的为一个对象增加新的功能。

  (2)装饰模式是一种用于代替继承的技术,无需通过继承增加子类就能扩展对象的新功能。

      使用对象的关联关系代替继承关系,更加灵活,同时避免类型体系的快速膨胀。

二、装饰模式实现细节

  (1)Componen 抽象构件角色:

      真实对象和装饰对象有相同的接口。这样,客户端就能够以真实对象相同的方式同装饰对象交互。

  (2)ConcreteComponent 具体构件角色(真是角色):

      IO 流中的FileInputStream、FileOutputStream

  (3)Decorator 装饰角色:

      持有一个抽象构件的引用。装饰对象接受所有客户端的请求,并把这些请求转发给真实的对象,这样就能在真实对象调用前后增加新的功能。

三、装饰模式情景导入

  场景:设计一款可以增加任意功能的汽车,除了陆地上跑以外,还可以随意增加天上飞、水上游、自动驾驶等功能。

  1 /**
  2  * Component抽象构件角色
  3  * @author CL
  4  *
  5  */
  6 public interface ICar {
  7     void move();
  8 }
  9 
 10 /**
 11  * ConcreteComponent具体构件角色(真实角色)
 12  * @author CL
 13  *
 14  */
 15 class Car implements ICar {
 16 
 17     @Override
 18     public void move() {
 19         System.out.println("陆地上跑!");
 20     }
 21     
 22 }
 23 
 24 /**
 25  * Decorator装饰角色
 26  * @author CL
 27  *
 28  */
 29 class SuperCar implements ICar {
 30     protected ICar car;
 31 
 32     public SuperCar(ICar car) {
 33         this.car = car;
 34     }
 35     
 36     @Override
 37     public void move() {
 38         car.move();
 39     }
 40 }
 41 
 42 /**
 43  * ConcreteDecorator具体装饰角色
 44  *     新增新的功能:天上飞
 45  * @author CL
 46  *
 47  */
 48 class FlyCar extends SuperCar {
 49 
 50     public FlyCar(ICar car) {
 51         super(car);
 52     }
 53     
 54     public void fly() {
 55         System.out.println("天上飞!");
 56     }
 57     
 58     @Override
 59     public void move() {
 60         super.move();
 61         fly();
 62     }
 63     
 64 }
 65 
 66 /**
 67  * ConcreteDecorator具体装饰角色
 68  *     新增新的功能:水上游
 69  * @author CL
 70  *
 71  */
 72 class WaterCar extends SuperCar {
 73 
 74     public WaterCar(ICar car) {
 75         super(car);
 76     }
 77     
 78     public void swim() {
 79         System.out.println("水上游!");
 80     }
 81     
 82     @Override
 83     public void move() {
 84         super.move();
 85         swim();
 86     }
 87     
 88 }
 89 
 90 /**
 91  * ConcreteDecorator具体装饰角色
 92  *     新增新的功能:人工智能  自动驾驶
 93  * @author CL
 94  *
 95  */
 96 class AICar extends SuperCar {
 97 
 98     public AICar(ICar car) {
 99         super(car);
100     }
101     
102     public void autoMove() {
103         System.out.println("自动驾驶!");
104     }
105     
106     @Override
107     public void move() {
108         super.move();
109         autoMove();
110     }
111     
112 }

  测试:

 1 /**
 2  * 测试装饰模式
 3  * @author CL
 4  *
 5  */
 6 public class Client {
 7     
 8     public static void main(String[] args) {
 9         System.out.println("基本功能,陆地上跑-->");
10         Car car = new Car();
11         car.move();
12         
13         System.out.println("\n增加新的功能,天上飞-->");
14         FlyCar flyCar = new FlyCar(car);
15         flyCar.move();
16         
17         System.out.println("\n增加新的功能,水上游-->");
18         WaterCar waterCar = new WaterCar(car);
19         waterCar.move();
20         
21         System.out.println("\n增加新的功能,水上游, 自动驾驶-->");
22         AICar aCar = new AICar(new WaterCar(car));
23         aCar.move();
24         
25         System.out.println("\n增加新的功能,天上飞,水上游, 自动驾驶-->");
26         AICar c = new AICar(
27                     new WaterCar(
28                         new FlyCar(car)));
29         c.move();
30     }
31 
32 }

  控制台输出:

基本功能,陆地上跑-->
陆地上跑!

增加新的功能,天上飞-->
陆地上跑!
天上飞!

增加新的功能,水上游-->
陆地上跑!
水上游!

增加新的功能,水上游, 自动驾驶-->
陆地上跑!
水上游!
自动驾驶!

增加新的功能,天上飞,水上游, 自动驾驶-->
陆地上跑!
天上飞!
水上游!
自动驾驶!

四、装饰模式总结

  装饰模式(Decorator)也叫做包装器模式(Wrapper)

  装饰模式降低系统的耦合度,可以动态的增加或删除对象的职责,并使得需要装饰的具体构建类和具体装饰类可以独立变化,以便增加新的具体构建类和具体装饰类。

  优点:

    a. 扩展对象功能,比继承灵活,不会导致类个数急剧增加;

    b. 可以对一个对象进行多次装饰,创造出不同行为的组合,得到功能更加强大的对象;

    c. 具体构建类和具体装饰类可以独立变化,用户可以根据需要自己增加新的具体构件子类和具体装饰子类。

  缺点:

    a. 产生很多小对象,大量小对象占据内存,一定程度上影响性能;

    b. 装饰模式易于出错,调试排查比较麻烦。

五、装饰模式实际开发应用场景

  (1)IO 中输入流和输出流的设计

      a. Componen 抽象构件角色:

       IO 流中的InputStream、OutputStream、Reader、Writer

      b. ConcreteComponen 具体构件角色:

       IO 流中的FileInputStream、FileOutputStream

      c. Decorator 装饰角色:

       持有一个抽象构件的引用:IO 流中的FileInputStream、FileOutputStream

      d. ConcreteDecorator 具体装饰角色:

       负责给构件对象增加新的责任,IO 流中的BufferedInputStream、BufferedOutputStream

  (2)Swing 包中图形界面构件功能;

  (3)Servlet API 中提供了一个 request 对象的Decorator 设计模式的默认实现类,增强了 request 对象的功能;

  (4)Struts2 中,request、response、session 对象的处理; 

  (5)…………

posted @ 2018-01-18 17:33  C3Stones  阅读(285)  评论(0编辑  收藏  举报