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. 动态地增加或撤销功能。

  • 相关阅读:
    wepy根据下标对数组中的某个对象的元素进行赋值
    wepy中的this.$apply()在什么时候使用
    wepy的安装与卸载
    vue-cli4.0更新后怎样将eslint关闭
    vue报错error 'projectName' is defined but never used no-unused-vars
    js数组对象去重(同时判断对象中的每一个属性,若其对应的属性值都相同,则去重)
    数字金额变为大写
    通过navigator.userAgent判断浏览器类型
    js获取iframe中的元素以及在iframe中获取父级的元素(包括iframe中不存在name和id的情况)
    html转成pdf,下载(html2canvas 和 jsPDF)
  • 原文地址:https://www.cnblogs.com/chenxkang/p/6758427.html
Copyright © 2011-2022 走看看