嘀嘀嘀~~~  页面这在飞快的跑来 . . .

设计模式之装饰者模式


装饰者模式

定义

《Head First》

The Decorator Pattern attaches additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.

装饰者模式,动态的将责任附加到对象上,若要扩展功能,装饰者提供了比继承更有弹性的替代方案

使用场景

  • 需要扩展一个类的功能, 或给一个类增加附加功能;
  • 需要动态地给一个对象增加功能, 这些功能可以再动态地撤销
  • 需要为一批的兄弟类进行改装或加装功能

结构

  • Component:抽象角色,给出一个个抽象接口,以规范准备接收附加责任的对象,是被装饰类和装饰类的父接口
  • Concrete Compont:具体角色,定义一个要接受附加责任的类,即被装饰的类
  • Decorator: 装饰角色,装饰者,持有一个Component(抽象角色)对象的引用,并定义一个与抽象角色接口一直的接口
  • Concrete Decorator: 具体装饰角色,具体装饰者,负责给抽象角色附加责任即扩展功能

类图

实际案例

  • 我们吃面,我们肚子很饿,吃一碗不够,我们还想加蛋,加青菜,加…但是最后出货也都是面条,就算是鸡蛋面,青菜面最后也都是面。这就是装饰者模式在不改变原有对象的基础之上,将功能附加到对象上。

  • 某人要出门约会,你肯定是要决定好你要穿什么样的衣服出门,用衣服来装饰下自己,让自己拥有一个完美的约会。比如,你会穿一件衬衫,然后穿一件西服裤,最后穿皮鞋出门。

  • 一家甜品店,出售蛋糕,除了蛋糕外,还可以在蛋糕上布置水果,蜡烛等,但是水果和蜡烛需要额外收费。

  • 咖啡店里咖啡中可以加不同的配料:摩卡、牛奶、糖、奶泡;不同的饮品加上不同的配料有不同的价钱。

例子

去买冰淇淋,可以买普通的冰淇淋和选择加糖或者加坚果的冰淇淋为例来实现

类图

Icecream类

public interface Icecream {

    public abstract String makeIcecream();

}

SimpleIcecream类

实现冰淇淋接口,并可以生产普通冰淇淋

public class SimpleIcecream implements Icecream {

    public String makeIcecream() {
        return "生产了一个普通的冰淇淋";
    }

}

IcecreamDecorator类

装饰角色,后面的附加坚果,糖等其他东西的类需要继承他

public class IcecreamDecorator implements Icecream {

    private Icecream specialIcecream;

    public String makeIcecream() {
        return specialIcecream.makeIcecream();
    }

    public IcecreamDecorator(Icecream specialIcecream) {
        this.specialIcecream=specialIcecream;
    }

}

HoneyDecorator类

public class HoneyDecorator extends IcecreamDecorator {

    public HoneyDecorator(Icecream specialIcecream) {
          super(specialIcecream);
    }

    public String makeIcercream() {
        return "生产了一个"+this.addHoney()+"的特殊冰淇淋";
    }

    private String addHoney() {
        return "加糖";
    }

}

NuttyDecorator类

public class NuttyDecorator extends IcecreamDecorator {

    public NuttyDecorator(Icecream specialIcecream) {
      super(specialIcecream);
    }

    public String makeIcecream( ) {
        return "生产了一个"+this.addNuts()+"的特殊冰淇淋";
    }

    private String addNuts( ) {
        return "加坚果";
    }

}

Client

写出测试类进行验证

public class Test {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
       Icecream simpleIcecream=new SimpleIcecream();
       System.out.println(simpleIcecream.makeIcecream());
       Icecream nutttIcecream=new NuttyDecorator(simpleIcecream);
       System.out.println(nutttIcecream.makeIcecream());
       System.out.println(new  HoneyDecorator(simpleIcecream).makeIcercream());   
    }
}

输出结果

生产了一个普通的冰淇淋
生产了一个加坚果的特殊冰淇淋
生产了一个加糖的特殊冰淇淋

总结

优点

  • 目的在于扩展对象的功能。装饰者模式提供比继承更好的灵活性。装饰是动态的,运行时可以修改的
  • 继承是静态的,编译期便已确定好。通过使用不同的装饰类及对它们的排列组合,可以创造出许多不同行为的组合

缺点

  • 利用装饰者模式,常常造成设计中有大量的小类,数量太多,会造成使用此API的人带来困扰,不容易理解。
  • 采用装饰者在实例化组件时,将增加代码复杂度。一旦使用装饰者,不仅要实例化组件,同时要将组件实例包装进装饰者。

文章作者: HaiLin Zhou
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 HaiLin Zhou !
评论
 上一篇
设计模式之外观模式 设计模式之外观模式
The Facade Pattern provides a unified interface to a set of interfaces in subsystem. Facade defines a higher-level interface that makes the subsystem easier to use.
2020-04-24
下一篇 
设计模式之模板方法模式 设计模式之模板方法模式
The Template Method Pattern defines the skeleton of an algorithm in a method, deferring some steps to subclasses. Template Method lets subclass redefine certain steps of an algorithm without changing the algorithm's structure.
2020-04-22
  目录