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

      装饰者模式属于结构型设计模式,它是作为现有的类的一个包装。

      定义:在不必改变原类文件和使用继承的情况下,动态地给一个对象添加一些额外的功能。

      问题描述:在软件系统中,有时候我们会使用继承来扩展对象的功能,但是由于继承为类型引入的静态特质,使得这种扩展方式缺乏灵活性,并且随着子类的增多,各种子类的组合会导致更多子类的膨胀,系统将不易维护。

      解决方案:使用装饰者模式,在不改变原有代码的情况下,创建一个装饰类来包装原有的类,提供一些额外的功能。

      结构图

      说明:

      1. Component:抽象构件角色,一般是一个接口,以规范准备接受附加责任的对象;

      2. ConcreteComponent:具体构件角色,实现或重写了Component中的方法。

      3. Decorator:装饰角色,一般是一个抽象类,持有一个Component对象的实例,并实现一个与抽象构件接口一致的接口。

      4. ConcreteDecorator:具体装饰角色,继承父类Decorator,并重写父类中的方法,负责给构件对象添加附加的责任。

      举个栗子:讲一个插花的故事。。。

      我们现有一个白色的花瓶,十分好看,我们将要对它进行装饰,可以插入一些红玫瑰,也可以插入一些黄菊。于是在代码的世界里,我们要有一个抽象接口Vase和一个实现了Vase接口的花瓶类FlowerVase,一个持有Vase对象实例的装饰者类(接口或抽象类)FlowerVaseDecorator和两个负责给花瓶对象添加附加功能的具体装饰类,一个负责插入红玫瑰RoseFlowerVase,另一个负责插入黄菊AnthemisFlowerVase。具体实现方式如下:

      1. 新建一个抽象接口Vase,花瓶和抽象装饰者都将实现这个接口,接口中定义了将要被实现的业务方法。代码如下:

          

      2. 新建一个花瓶类FlowerVase,实现Vase接口中的方法。代码如下:

          

      3. 新建一个抽象装饰者类FlowerVaseDecorator,它实现了Vase接口,并持有一个抽象接口Vase对象的引用,它只是简单地调用了成员变量的方法,具体职能的增加放入到了子类当中去实现。代码如下:

          

      4. 新建一个负责插入红玫瑰的具体装饰类RoseFlowerVase和一个负责插入黄菊的具体装饰类AnthemisFlowerVase,两者均继承抽象装饰者类并重写其中的业务方法,在业务方法中加入新的职能---插花。代码如下:

          

          

      5.  在类DecoratorFragment中使用FlowerVaseDecorator来装饰Vase对象。核心代码如下:

             

      6. 运行后的效果,如图所示:

         

      综上,我们并没有改变被装饰者---花瓶类,只是通过装饰者类对其进行了包装,然后提供了新的额外的功能,这样就避免了因为使用子类继承而导致类的个数急剧增加,且被装饰者和装饰者可以独立变化,方便扩展,符合开闭原则。

      优点

      1. 可以动态地为类添加新的功能,且可以多次装饰,使用不同的装饰类进行组合可以实现复杂的功能;

      2. 具体的被装饰类和装饰类可以独立变化,扩展方便。

      缺点:多层装饰比较复杂。

      适用场景

      1. 在不影响原有类的情况下,扩展一个类的功能;

      2. 动态地增加或撤销功能。

  • 相关阅读:
    第二十七节(多线程、线程的创建和启动、生命周期、调度、控制、同步)
    第二十六节(对象流,File类)
    第二十五节(转换流,打印流)
    第二十四节(Java文件流,缓冲流)
    第二十三节(String,StringBuffer,基础类型对应的 8 个包装类,日期相关类、 Random 数字 ,Enum枚举)下
    【转】perl如何避免脚本在windows中闪一下就关闭
    计算机基础(二)
    计算机基础(一)
    04 数据结构
    03 逻辑与结构
  • 原文地址:https://www.cnblogs.com/chenxkang/p/6758427.html
Copyright © 2011-2022 走看看