装饰器设计模式
也叫包装设计模式,属于结构型模式,它是作为现有的类的一个包装,允许向一个现有的对象添加新的功能,同时又不改变其结构
给对象增加功能,一般两种方式 继承或关联组合,将一个类的对象嵌入另一个对象中,由另一个对象来决定是否调用嵌入对象的行为来增强功能,这个就是装饰器模式,比继承模式更加灵活。
角色(装饰者和被装饰者有相同的超类(Component))
- 抽象组件(Component)
- 定义装饰方法的规范,最初的自行车,仅仅定义了自行车的API;
- 被装饰者(ConcreteComponent)
- Component的具体实现,也就是我们要装饰的具体对象
- 实现了核心角色的具体自行车
- 装饰者组件(Decorator)
- 定义具体装饰者的行为规范, 和Component角色有相同的接口,持有组件(Component)对象的实例引用
- 自行车组件 都有 名称和价格
- 具体装饰物(ConcreteDecorator)
- 负责给构件对象装饰附加的功能
- 比如 喇叭,防爆胎
编码实战
顶层抽象组件:
public interface Bike {
String getDescription();
int getPrice();
}
被装饰者,大小号自行车
/**
* 被装饰着_大号自行车
* @author cv大魔王
* @version 1.0
* @date 2021/7/13 13:49
*/
public class BigBack implements Bike {
private String description = "大号自行车";
@Override
public String getDescription() {
return this.description;
}
@Override
public int getPrice() {
return 200;
}
}
/**
* 被装饰着_小号自行车
* @author cv大魔王
* @version 1.0
* @date 2021/7/13 13:49
*/
public class SmallBack implements Bike {
private String description = "小号自行车";
@Override
public String getDescription() {
return this.description;
}
@Override
public int getPrice() {
return 100;
}
}
装饰器
public class BikeDecorator implements Bike{
private String description = "装饰器——无意义,由子类进行传递";
@Override
public String getDescription() {
return description;
}
@Override
public int getPrice() {
return 0;
}
}
装饰器实现类——具体的实现类,自行车的组件“防爆胎”和“喇叭”
/**
* 具体的装饰器——防爆胎
* @author cv大魔王
* @version 1.0
* @date 2021/7/13 13:59
*/
public class RSCBickDecorator extends BikeDecorator{
private String description = "增加一个防爆胎";
private Bike bike;
public RSCBickDecorator(Bike bike) {
this.bike = bike;
}
@Override
public String getDescription() {
return bike.getDescription() + "," + description;
}
@Override
public int getPrice() {
// 100元是防爆胎的价格
return bike.getPrice() + 100;
}
}
/**
* 具体的装饰器——唢呐
* @author cv大魔王
* @version 1.0
* @date 2021/7/13 13:59
*/
public class SuonaBickDecorator extends BikeDecorator{
private String description = "增加一个喇叭";
private Bike bike;
public SuonaBickDecorator(Bike bike) {
this.bike = bike;
}
@Override
public String getDescription() {
return bike.getDescription() + "," + description;
}
@Override
public int getPrice() {
// 50元是喇叭的价格
return bike.getPrice() + 50;
}
}
使用:
public static void main(String[] args) {
// 选个自行车
Bike bike = new BigBack();
// 给自行车加一个喇叭
bike = new SuonaBickDecorator(bike);
// 给自行车再加上两个防爆胎
bike = new RSCBickDecorator(bike);
bike = new RSCBickDecorator(bike);
// 查看配置
System.out.println(bike.getDescription());
// 结算价格
System.out.println(bike.getPrice());
}
输出:
大号自行车,增加一个喇叭,增加一个防爆胎,增加一个防爆胎
450
小结
优点
- 装饰模式与继承关系的目的都是要扩展对象的功能,但装饰模式可以提供比继承更多的灵活性。
- 使用不同的具体装饰类以及这些装饰类的排列组合,可以创造出很多不同行为的组合,原有代码无须改变,符合“开闭原则”
缺点
- 装饰模式增加了许多子类,如果过度使用会使程序变得很复杂 (多层包装)
- 增加系统的复杂度,加大学习与理解的难度
装饰器模式和桥接模式对比
-
相同点都是通过封装其他对象达到设计的目的,和对象适配器也类似,有时也叫半装饰设计模式
-
没有装饰者和被装饰者的主次区别,桥接和被桥接者是平等的,桥接可以互换,不用继承自同一个父类
比如例子里面的,可以是Phone持有Color,也可以是Color持有Phone