装饰器模式(Decorator Pattern)
一、概念
装饰器模式(Decorator Pattern)指在不改变原有对象结构的基础之上,将功能附加到对象上,提供了比继承更有弹性的替代方案(扩展原有对象的功能)。符合开闭原则,对拓展开发,对修改关闭
模式动机:一般有2种方式
可以实现给一个类或对象增加行为(方法)
-
继承
:通过继承一个现有类可以使得子类在拥有自身方法的同时还拥有父类的方法。但是这种方法是静态的,用户不能控制增加行为的方式和时机。 关联
,即将一个类的对象嵌入另一个对象中,由另一个对象来决定是否调用嵌入对象的行为,以便扩展自己的行为,我们称这个嵌入的对象为装饰器(Decorator)
-
- 继承可以扩展类,但会破坏了原类的封装性,而装饰者模式提供了一种
新的类扩展方式(继承关系的一个替代方案)
,不会破坏原类的封装性。可以在不需要创造更多子类的情况下,将对象的功能加以扩展。这就是装饰器模式的模式动机。
- 继承可以扩展类,但会破坏了原类的封装性,而装饰者模式提供了一种
二、适用场景
- 用于扩展一个类的功能或给一个类添加附加职责。
- 动态的给一个对象添加功能,这些功能可以再动态的撤销。
三、参与者
-
抽象组件(Component):
需要装饰的抽象对象
。 装饰者模式必须要有这样一个抽象的组件,被装饰者ConcreteComponent 和装饰者Decorator 都是这个抽象的具体实现
。定义我们最核心、最基本的方法。 - 具体组件/被装饰者/真实对象(ConcreteComponent):是我们需要装饰的对象。
- 抽象装饰类(Decorator):持有
Component的引用
及装饰者共有的方法(即继承Component类 或者实现Component接口)
。 - 具体装饰类(ConcreteDecorator) :被装饰的对象, 继承抽象装饰类Decorator,负责给Component附加新的功能。
- Client 用户
四、代码例子
Cake是抽象鸡蛋灌饼接口,OriginalCake是不加任何配料的原味鸡蛋灌饼,Decorator是抽象装饰器,EggAddCake 是给当前饼再加一个鸡蛋,SausageAddCake 是给当前饼再加一个香肠,我们在买鸡蛋灌饼时可以选择什么都不加,或加一个蛋,加多个蛋,加肠,加多个肠,同时加蛋和肠的情况
抽象组件(Component):Cake
具体组件(ConcreteComponent):OriginalCake
抽象装饰类(Decorator):Decorator
具体装饰类(ConcreteDecorator) :EggAddCake 和 SausageAddCake
五、UML图
六、优缺点
(一)优点
- 装饰者模式是
继承的补充
,一种类的拓展方式
,比继承灵活,不改变原有对象的情况下动态地给一个对象 扩展功能
,即插即用。 - 通过使用不同装饰类以及这些装饰类的排列组合,得到功能更加强大的对象。
- 装饰者完全遵守开闭原则
(二)缺点
- 会出现更多的代码,更多的类,出错后调试排查比较麻烦,增加程序复杂性。
- 动态装饰以及多层装饰时会更加复杂。
- 产生大量小对象占据内存,一定程度上影响性能。