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";@Overridepublic String productName() {return vehicleName;}@Overridepublic double price() {return Math.pow(10, 6);}
}
3)汽车装饰对象
public class VehicleDecorator implements Vehicle {// 聚合private Vehicle vehicle;public VehicleDecorator(Vehicle vehicle) {this.vehicle = vehicle;}@Overridepublic String productName() {return vehicle.productName();}@Overridepublic double price() {return vehicle.price();}
}
4)座椅装饰对象
public class SeatDecorator extends VehicleDecorator {public SeatDecorator(Vehicle vehicle) {super(vehicle);}@Overridepublic String productName() {return super.productName() + "+" + "真皮座椅*4";}@Overridepublic double price() {return super.price() + Math.pow(10, 5);}
}
5)音响装饰对象
public class SoundDecorator extends VehicleDecorator {public SoundDecorator(Vehicle vehicle) {super(vehicle);}@Overridepublic String productName() {return super.productName() + "+" + "雅马哈音响*4";}@Overridepublic 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)缺点
- 会构建较多子类,代码编写变的复杂,增加了系统的复杂度与运维理解难度