装饰器模式用于在动态修改现有对象的功能。 同一类的其他实例将不会受到修改的影响,只有单个对象获得修改后的行为。
装饰器模式允许向现有的对象添加新功能,同时又不改变其结构。它是对现有类的一个包装。
这种模式创建了一个装饰类,并在保持类方法签名完整性的前提下提供额外的功能。
假设我们想要实现不同类型的汽车 - 我们可以创建一个汽车的接口定义一些方法,之后创建一个基础的汽车抽象类,然后定义集成这个基础汽车类创建具体类型的汽车:Sports Car和Luxury Car。
但是如果我们想要在动态获得一辆兼具Sports Car和Luxury Car功能的汽车,那么实现将会复杂。如果我们还想指定哪些功能应该首先添加,那么它变得更加复杂。 现在想象一下,如果我们有十种不同类型的汽车,那么使用继承和组合的实现逻辑将无法管理。 为了解决这种编程情况,我们在java中应用装饰器模式。
我们需要一下类型来实现装饰器模式。
Component Interface
抽象组件,用接口或者抽象类定义我们将要实现的方法。
public interface Car{
//组装
public void assemble();
}
Component Implementation
具体组件
public class BasicCar implements Car{
@Override
public void assemble(){
System.out.println("Basic Car.");
}
}
Decorator
抽象装饰器类实现组件接口,并且它与组件接口具有HAS-A关系。组件变量应该可以被子装饰器类访问,所以我们将使这个变量受到保护。
public abstract class CarDecorator implements Car{
protected Car car;
public CarDecorator(Car c){
this.car =c;
}
@Override
public void assemble(){
this.car.assemble();
}
}
Concrete Decorators
具体装饰器,集成基本装饰器的功能并相应的修改组件的行为. 我们可以创建具体的装饰器类LuxuryCar和SportsCar.
public class SportsCar extends CarDecorator{
public SportsCar(Car c){
super(c);
}
@Override
public void assemble(){
super.assemble();
System.out.print("Adding features of Sports Car.");
}
}
public class LuxuryCar extends CarDecorator{
public LuxuryCar(Car c){
super(c);
}
@Override
public void assemble(){
super.assemble();
System.out.print("Adding features of Luxury Car.");
}
}
Decorator Design Pattern Test Program
public class DecoratorPatternTest {
public static void main(String[] args) {
Car sportsCar = new SportsCar(new BasicCar());
sportsCar.assemble();
System.out.println("\n*****");
Car sportsLuxuryCar = new SportsCar(new LuxuryCar(new BasicCar()));
sportsLuxuryCar.assemble();
}
}
Decorator Design Pattern – Important Points
- 装饰模式提供动态修改的能力,因此更加灵活。易于维护和扩展。
- 装饰器模式的缺点是它使用了许多相似的对象(装饰器)。
- 装饰器模式被大量用于JAVA IO类,例如FileReader, BufferedReader等。
总结
优点:
- 扩展一个类的功能。
- 动态增加功能,动态撤销。
缺点:
- 多层装饰比较复杂。