zoukankan      html  css  js  c++  java
  • 设计模式之装饰模式

    装饰模式(Decorate)是指在不必改变原类文件和使用继承的情况下,动态的扩展一个类的功能。它是通过创建一个包装对象,也就是装饰来包括真实的对象。包裹的方式一般是将原来的对象作为装饰类构造方法的参数,但是在不需要用到新功能的地方,它可以直接调用原来的类中的方法。装饰类必须和原来的类具有相同的接口。

    装饰模式中的角色如下:

    1.抽象构件角色(Component)

    抽象构件角色给出一个抽象接口,以规范准备接收附加责任的对象。

    2.具体构件角色(Concrete Component)

    定义一个将要接收附加责任的类。

    3.装饰角色(Decorate)

    持有一个构件对象的实例,并实现一个与抽象构件接口一致的接口。

    4.具体装饰角色(Concrete Decorate)

    负责给构件对象添加附加的责任。

    装饰模式的UML图如下:

    下面给出示例代码:

    1 public abstract class Component {
    2     protected abstract void operation();
    3 }
    1 public class ConcreteComponent extends Component {
    2     @Override
    3     protected void operation() {
    4         System.out.println("do something in concreteComponent...");
    5     }
    6 }
    1 public abstract class Decorate extends Component{
    2     protected Component component;
    3 
    4     protected void decorate(Component component){
    5         this.component = component;
    6     }
    7 }
     1 public class ConcreteDecorateA extends Decorate {
     2 
     3     @Override
     4     protected void operation() {
     5         //添加附加操作
     6         System.out.println("do something in ConcreteDecorateA...");
     7         //调用被包装类的方法
     8         component.operation();
     9     }
    10 
    11 }
     1 public class ConcreteDecorateB extends Decorate {
     2 
     3     @Override
     4     protected void operation() {
     5         //添加附加操作
     6         System.out.println("do something in ConcreteDecorateB...");
     7         //调用被包装类的方法
     8         component.operation();
     9     }
    10     
    11 }

    下面给出测试代码:

     1 public class DecorateTest {
     2 
     3     public static void main(String[] args) {
     4         Component component = new ConcreteComponent();
     5         ConcreteDecorateA decorateA = new ConcreteDecorateA();
     6         ConcreteDecorateB decorateB = new ConcreteDecorateB();
     7 
     8         //将ConcreateComponent类包装成ConcreteDecorateA
     9         decorateA.decorate(component);
    10         //将ConcreteDecorateA类包装成ConcreteDecorateB
    11         decorateB.decorate(decorateA);
    12 
    13         decorateB.operation();
    14     }
    15 
    16 }

    运行结果如下:

    总结:

    1.装饰模式的适用场景:

    (1)需要扩展一个类的功能、或者给一个类添加附加的职责时。

    (2)需要动态的给一个对象添加功能,这些功能可以再动态的撤销时。

    (3)需要增加由一些基本功能的排列组合而产生的非常大量的功能,从而使继承关系变得不现实。

    (4)当不能采用生成子类的方式进行扩充时。

    2.装饰模式的优点:

    (1)装饰模式与继承关系的目的都是要扩展对象的功能,但装饰模式可以提供比继承关系更大的灵活性。

    (2)通过使用不同的具体装饰类以及这些装饰类的排列组合,可以创造出很多不同行为的组合。

    3.装饰模式的缺点:

    (1)装饰模式比继承关系更加灵活,但意味着更加复杂。

    (2)装饰模式会导致设计中出现很多小类,如果过度使用会使程序变得很复杂。

    4.装饰模式与适配器模式的区别:

    (1)关于新职责

    适配器模式也可以再转换时增加新的功能,但主要目的是为了完成接口的兼容。装饰模式最主要的职责是给装饰类增加新的职责。

    (2)关于原接口

    适配器模式是用新接口来调用原接口,原接口对新系统来说是不可见或者不可用的。装饰模式原封不动的调用原接口,系统对装饰的对象也是通过原接口来完成使用。

    (3)关于装饰的对象

    适配器是知道被适配者的详细情况的,而装饰者只知道其接口是什么,至于什么具体类型只有在运行期间才知道。

  • 相关阅读:
    LeetCode
    算法
    GitHub
    GitHub
    git
    将博客搬家至CSDN
    base64与图片互转
    windows下mongodb数据库搭建过程遇到问题
    mongodb数据插入语句与navicat导入mongodb的json结构
    Visual C++安装失败解决:Error 0x80240017: Failed to execute MSU package.
  • 原文地址:https://www.cnblogs.com/lixiuyu/p/5920885.html
Copyright © 2011-2022 走看看