zoukankan      html  css  js  c++  java
  • 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("
    增加新的功能,天上飞-->");
    14         FlyCar flyCar = new FlyCar(car);
    15         flyCar.move();
    16         
    17         System.out.println("
    增加新的功能,水上游-->");
    18         WaterCar waterCar = new WaterCar(car);
    19         waterCar.move();
    20         
    21         System.out.println("
    增加新的功能,水上游, 自动驾驶-->");
    22         AICar aCar = new AICar(new WaterCar(car));
    23         aCar.move();
    24         
    25         System.out.println("
    增加新的功能,天上飞,水上游, 自动驾驶-->");
    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)…………

  • 相关阅读:
    通过另外一个应用程序给多个文本框赋值, 模拟单击事件
    AngularJS
    九章算法
    实现继承
    二分查找
    NET Core依赖注入解读&使用Autofac替代实现
    NET SignalR 与 LayIM2.0
    WebVR
    依赖注入
    如何实现配置与源文件的同步
  • 原文地址:https://www.cnblogs.com/cao-lei/p/8311421.html
Copyright © 2011-2022 走看看