装饰器模式
定义
在不改变原有对象的基础之上,将功能附加到对象上;
提供了比继承更有弹性的替代方案(扩展原有对象功能)
适用场景
- 扩展一个类的功能或给一个类添加附加职责
- 动态的给一个对象添加功能,这些功能可以再动态的撤销
优点和缺点
优点
- 继承的有力补充,比继承灵活,不改变原有对象的情况下给一个对象扩展功能;
- 通过使用不同装饰类以及这些装饰类的排列组合,可以试想不同效果;
- 符合开闭原则。
缺点
- 会出现更多的代码,更多的类,增加程序复杂性;
- 动态装饰时,多层装饰时会更复杂。
结构
- 抽象构件角色: 定义一个抽象接口以规范准备接收附加责任的对象。
- 具体构件角色: 实现抽象构件,通过装饰角色为其添加一些职责。
- 抽象装饰角色: 继承抽象构件,并包含具体构件的实例,可以通过其子类扩展具体构件的功能。
- 具体装饰角色: 实现抽象装饰的相关方法,并给具体构件对象添加附加的责任。
代码实现
假设我们去买煎饼,一个煎饼8元钱,可以加鸡蛋和香肠,以传统方式来实现,如果用户只是买一个煎饼,我们建一个煎饼类即可实现,如果用户想要加一个鸡蛋,可以新建一个类继承煎饼类来实现,但是如果用户想再加香肠呢?再鸡蛋呢?两个、三个…
很明显,如果再以简单的继承来去实现,我们的类会爆炸式的增加,所以我们可以引入装饰者模式,把鸡蛋和香肠作为装饰,可以动态添加。
首先创建一个抽象构件角色:(煎饼以及作为装饰的抽象类)
1 | public abstract class APancakes { |
具体构件角色:(具体煎饼类,可以有多种煎饼)
1 | public class Pancakes extends APancakes{ |
抽象装饰角色:(具体装饰角色的抽象类,也可以使用对象类,具体根据业务情况决定)
1 | public class AbstractDecorator extends APancakes{ |
具体装饰角色:(装饰角色的具体实现)
鸡蛋实现:
1 | public class EggDecorator extends AbstractDecorator { |
香肠实现:
1 | public class SausageDecorator extends AbstractDecorator { |
具体调用:
1 | public class Test { |
如代码所示,想要加几个鸡蛋或者香肠,可以动态的去实现
结果:
1 | 煎饼 加一个鸡蛋 加一个鸡蛋 加一根香肠 12 |