定义:装饰模式是一种用于代替继承的技术,无须通过继承增加子类就能扩展对象的新功能。使用对象的关联关系代替继承关系,更加灵活,同时避免类型体系的快速膨胀。那么装饰器的职责就是动态地为一个对象增加新的功能。
装饰器的构造:
1、抽象构件角色 ICar
2、具体的构件角色 Car
3、装饰器角色 SuperCar
4、具体的装饰器角色 FlyCar、WaterCar、AICar
代码实现:
基础接口
public interface ICar {
void run();
}
具体实现类
public class Car implements ICar {
public void run() {
System.out.println("滴滴滴,跑起来");
}
}
装饰器角色
public class SuperCar implements ICar {
private ICar car;
public SuperCar(ICar car){
this.car = car;
}
public void run() {
car.run();
}
}
具体装饰器角色
public class FlyCar extends SuperCar {
public FlyCar(ICar car) {
super(car);
}
@Override
public void run() {
super.run();
fly();
}
public void fly(){
System.out.println("插上翅膀,自由飞翔");
}
}
public class AICar extends SuperCar {
public AICar(ICar car) {
super(car);
}
@Override
public void run(){
super.run();
autoDrive();
}
public void autoDrive(){
System.out.println("AI自动驾驶");
}
}
public class WaterCar extends SuperCar {
public WaterCar(ICar car) {
super(car);
}
@Override
public void run() {
super.run();
water();
}
public void water(){
System.out.println("装上气垫,水上漂");
}
}
Test
public class DecorateTest {
public static void main(String[] args) {
ICar car = new Car();
car.run();
System.out.println("\n赋予汽车新的技能");
AICar aiCar = new AICar(car);
aiCar.run();
System.out.println("\n再次赋予汽车新的技能");
FlyCar flyCar = new FlyCar(car);
flyCar.run();
System.out.println("\n再再次赋予汽车新的技能");
WaterCar waterCar = new WaterCar(car);
waterCar.run();
System.out.println("\n以上代码可以简写为:");
FlyCar flyCar1 = new FlyCar(new AICar(new Car()));
flyCar1.run();
System.out.println("\n随意组合");
WaterCar waterCar1 = new WaterCar(new AICar(new FlyCar(new Car())));
waterCar1.run();
}
}
运行结果
滴滴滴,跑起来
赋予汽车新的技能
滴滴滴,跑起来
AI自动驾驶
再次赋予汽车新的技能
滴滴滴,跑起来
插上翅膀,自由飞翔
再再次赋予汽车新的技能
滴滴滴,跑起来
装上气垫,水上漂
以上代码可以简写为:
滴滴滴,跑起来
AI自动驾驶
插上翅膀,自由飞翔
随意组合
滴滴滴,跑起来
插上翅膀,自由飞翔
AI自动驾驶
装上气垫,水上漂
这就是装饰器模式,当你想要增加功能的时候只需要里面装饰一个具体的其他装饰器类型就可以,这样就可以避免新增多个子类。
总结
一个设计模式的出现一定有他特殊的价值。
1、装饰器的价值在于装饰,他并不影响被装饰类本身的核心功能。在一个继承的体系中,子类通常是互斥的。比如一辆车,品牌只能要么是奥迪、要么是宝马,不可能同时属于奥迪和宝马,而品牌也是一辆车本身的重要属性特征。但当你想要给汽车喷漆,换坐垫,或者更换音响时,这些功能是互相可能兼容的,并且他们的存在不会影响车的核心属性:那就是他是一辆什么车。这时你就可以定义一个装饰器:喷了漆的车。不管他装饰的车是宝马还是奥迪,他的喷漆效果都可以实现。
2、再回到这个例子中,我们看到的仅仅是一个Car类。在复杂的大型项目中,同一级下的兄弟类通常有很多。当你有五个甚至十个Car时,再想要为每个类都加上 “滴滴滴” 的效果,就要写出五个子类了。毫无疑问这是不合理的。装饰器模式在不影响各个Car核心价值的同时,添加了他特有的装饰效果,具备非常好的通用性,这也是他存在的最大价值。