zoukankan      html  css  js  c++  java
  • 设计模式(九)装饰器模式

    职责:动态的为一个对象增加新的功能

       装饰器模式是一种用于代替继承的技术,无需通过继承增加子类就能扩展对象的新功能。使用对象的关联关系代替继承关系,更加灵活,同时避免类型体系的快速膨胀。


    实现细节:

    ——Component抽象构件角色:真实对象和装饰对象有相同的接口。这样,客户端对象就能够以与真实对象相同的方式同装饰对象交互。

    ——ConcreteComponent具体构件角色(真实对象):io流中的FileInputStream、    FileOutputStream

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

    ——ConcreteDecorator具体装饰角色:负责给构件对象增加新的责任。


     开发中的使用场景:

      IO中输入流和输出流的设计

      Swing包中图形界面构件功能

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

      Struts2中,request,response,session对象的处理


    1. 创建一个抽象组件ICar接口,并创建具体构建角色以及各个具体装饰角色

     1 package com.ztq.decorator;
     2 
     3 /***
     4  * 抽象组件
     5  * @author ZTQ
     6  *
     7  */
     8 public interface ICar {
     9     void move();
    10 }
    11 
    12 //ConcreteComponent 具体构件角色(真实对象)
    13 class Car implements ICar{
    14 
    15     @Override
    16     public void move() {
    17         System.out.println("陆地上跑!");
    18     }
    19     
    20 }
    21 
    22 class SuperCar implements ICar{
    23     private ICar car;
    24     public SuperCar(ICar car){
    25         this.car = car;
    26     }
    27     
    28     @Override
    29     public void move() {
    30         car.move();
    31     }
    32     
    33 }
    34 
    35 //ConcreteDecorator具体装饰角色
    36 class FlyCar extends SuperCar{
    37 
    38     public FlyCar(ICar car) {
    39         super(car);
    40     }
    41     
    42     public void fly(){
    43         System.out.println("天上飞");
    44     }
    45     
    46     @Override
    47     public void move() {
    48         super.move();
    49         fly();
    50     }
    51 }
    52 
    53 //ConcreteDecorator具体装饰角色
    54 class WaterCar extends SuperCar{
    55 
    56     public WaterCar(ICar car) {
    57         super(car);
    58     }
    59     
    60     public void swim(){
    61         System.out.println("水里游");
    62     }
    63     
    64     @Override
    65     public void move() {
    66         super.move();
    67         swim();
    68     }
    69 }
    70 
    71 //ConcreteDecorator具体装饰角色
    72 class AICar extends SuperCar{
    73 
    74     public AICar(ICar car) {
    75         super(car);
    76     }
    77     
    78     public void autoMove(){
    79         System.out.println("自动跑");
    80     }
    81     
    82     @Override
    83     public void move() {
    84         super.move();
    85         autoMove();
    86     }
    87 }

    2. 创建测试类Client

     1 package com.ztq.decorator;
     2 
     3 public class Client {
     4     public static void main(String[] args) {
     5         Car car = new Car();
     6         car.move();
     7         
     8         System.out.println("增加新的功能:飞行");
     9         FlyCar flycar = new FlyCar(car);
    10         flycar.move();
    11         
    12         System.out.println("增加新的功能:水里游");
    13         WaterCar waterCar = new WaterCar(car);
    14         waterCar.move();
    15         
    16         System.out.println("增加两个新的功能,飞行,水里游");
    17         WaterCar waterCar2 = new WaterCar(new FlyCar(car));
    18         waterCar2.move();
    19     }
    20 }

    结果:

    陆地上跑!
    增加新的功能:飞行
    陆地上跑!
    天上飞
    增加新的功能:水里游
    陆地上跑!
    水里游
    增加两个新的功能,飞行,水里游
    陆地上跑!
    天上飞
    水里游

    UML图:


    总结:

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

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

      优点:

    • 扩展对象功能,比继承灵活,不会导致类个数急剧增加
    • 可以对一个对象进行多次装饰,创造出不同行为的组合,得到功能更加强大的对象
    • 具体构建类和具体装饰类可以独立变化,用户可以根据需要自己增加新的具体构件子类和具体装饰子类

      缺点:

    • 产生很多小对象。大量小对象占据内存,一定程度上影响性能
    • 装饰模式易于出错,调试排查比较麻烦

    装饰模式和桥接模式的区别:

    两个模式都是为了解决过多子类对象问题。但他们的诱因不一样。桥接模式是对象自身现有机制沿着多个维度变化,是既有部分不稳定。装饰模式是为了增加新的功能。

  • 相关阅读:
    CF G. Running Competition (NTT, 思维)
    ABC 177 F
    牛客练习赛68 D.牛牛的粉丝 (期望DP,矩阵快速幂)
    CF E
    HDU 6761 Minimum Index (字符串--Lyndon分解)
    D. GameGame (思维、博弈)
    P2533 最小圆覆盖
    P4049 [JSOI2007]合金
    P2510 [HAOI2008]下落的圆盘
    P3205 [HNOI2010]合唱队
  • 原文地址:https://www.cnblogs.com/zhangtianq/p/6091047.html
Copyright © 2011-2022 走看看