-
装饰器设计模式(Decorator Pattern)
-
角色(装饰者和被装饰者有相同的超类Component)
- 抽象组件(Component)
- 定义装饰方法的规范,最初的自行车,仅仅定义了自行车的API
- InputStream
- 被装饰者(Concrete Component)
- Component的具体实现,也就是我们要装饰的具体对象
- 实现了核心角色的具体自行车
- FileInputStream、ByteArrayInputStream
- 装饰者组件(Decorator)
- 定义具体装饰者的行为规范,和Component角色有相同的接口,持有组件(Component)对象的实例应用
- 自行车组件都有名称和价格
- FilterInputStream
- 具体装饰物(Concrete Decorator)
- 负责给构件对象装饰附加的功能
- 比如喇叭、防爆胎等
- BufferedInputStream、DataInputSteam
- 抽象组件(Component)
-
代码实战示例
/*** 通用组件*/ interface Bike {String getDescription();int getPrice(); }/*** 具体的被装饰者(Concrete Component)*/ class BigBike implements Bike {private String description = "大号自行车";@Overridepublic String getDescription() {return this.description;}@Overridepublic int getPrice() {return 200;} }/*** 装饰者组件*/ class BikeDecorator implements Bike {private String description = "我只是装饰器,啥都不表示,子类帮我传递";@Overridepublic String getDescription() {return this.description;}@Overridepublic int getPrice() {return 0;} }/*** 具体装饰物:防爆胎*/ class BSCBikeDecorator extends BikeDecorator {private String description = "增加50元的防爆胎";private Bike bike;public BSCBikeDecorator(Bike bike) {this.bike = bike;}@Overridepublic String getDescription() {return bike.getDescription() + "," + this.description;}@Overridepublic int getPrice() {return bike.getPrice() + 50;} }public class Main {public static void main(String[] args) {Bike bigBike = new BigBike();bigBike = new BSCBikeDecorator(bigBike);bigBike = new BSCBikeDecorator(bigBike);System.out.println(bigBike.getDescription());System.out.println(bigBike.getPrice());} }
-
优点
- 装饰模式与继承关系的目的都是要扩展对象的功能,但装饰模式可以提供比继承更多的灵活性
- 使用不同的具体装饰类以及这些装饰类的排列组合,可以创造出很多不同行为的组合,原有代码无须改变,符合“开闭原则”
-
缺点
- 装饰模式增加了许多子类,如果过度使用会使程序变得很复杂(多层包装)
- 增加了系统的复杂度,加大学习与理解的难度
-
装饰器模式与桥接模式对比
- 相同点都是通过封装其他对象达到设计的目的,和对象适配器也类似,有时也叫半装饰设计模式
- 没有装饰者和被装饰者的主次区分,桥接和被桥接者是平等的,桥接可以互换,不用继承自同一个父类
- 桥接模式不用使用同一个接口;装饰模式用同一个接口装饰,接口在父类中定义