1.定义
1)可以在不改动原有对象代码的情况下扩展对象的功能,通过聚合的方式相较于继承更加灵活。
2)UML图
2.示例
汽车有很多装饰可选,如座椅、音响、轮胎等都可以进行自定义组装
1)抽象汽车对象
public interface Vehicle {
/**
* 产品名称
*/
String productName();
/**
* 价格
*
* @return
*/
double price();
}
2)具体汽车对象
public class BMWVehicle implements Vehicle {
private final String vehicleName = "宝马X7";
@Override
public String productName() {
return vehicleName;
}
@Override
public double price() {
return Math.pow(10, 6);
}
}
3)汽车装饰对象
public class VehicleDecorator implements Vehicle {
// 聚合
private Vehicle vehicle;
public VehicleDecorator(Vehicle vehicle) {
this.vehicle = vehicle;
}
@Override
public String productName() {
return vehicle.productName();
}
@Override
public double price() {
return vehicle.price();
}
}
4)座椅装饰对象
public class SeatDecorator extends VehicleDecorator {
public SeatDecorator(Vehicle vehicle) {
super(vehicle);
}
@Override
public String productName() {
return super.productName() + "+" + "真皮座椅*4";
}
@Override
public double price() {
return super.price() + Math.pow(10, 5);
}
}
5)音响装饰对象
public class SoundDecorator extends VehicleDecorator {
public SoundDecorator(Vehicle vehicle) {
super(vehicle);
}
@Override
public String productName() {
return super.productName() + "+" + "雅马哈音响*4";
}
@Override
public double price() {
return super.price() + Math.pow(10, 4);
}
}
运行结果
public class Main {
public static void main(String[] args) {
Vehicle myCar = new BMWVehicle();
// 音响装饰
myCar = new SoundDecorator(myCar);
// 座椅装饰
myCar = new SeatDecorator(myCar);
System.out.println("配置:" + myCar.productName());
System.out.println("价格:" + myCar.price());
}
}
3.应用场景
JDK中的IO流设计中就使用到了该模式。
// 配置缓冲流
InputStream in = new BufferedInputStream(new FileInputStream(""););
InputStream
:抽象组件类
FileInputStream
:被装饰类
FilterInputStream
:装饰抽象类
BufferedInputStream
:具体装饰类型
4.总结
1)优点
- 扩展功能不必修改原有代码,符合开闭原则
- 较继承方式更为灵活
2)缺点
- 会构建较多子类,代码编写变的复杂,增加了系统的复杂度与运维理解难度