GoF原文
Attach additional responsibilities to an object dynamically keeping the same interface. Decorators provide a flexible alternative to subclassing for extending functionality.
装饰器设计模式用于在运行时修改对象的功能,单个对象将获得修改后的行为,同一类的其他实例将不受此影响。
装饰器模式提供了比继承更有弹性的替代方案(扩展原有对象的功能)将功能附加到对象上。因此,装饰器模式的核心是功能扩展。使用装饰器模式可以透明且动态地扩展类的功能。
装饰器模式的应用场景来看这样一个场景
煎饼中可以加鸡蛋,也可以加香肠,但是不管怎么“加码”,都还是一个煎饼。
再比如,给蛋糕加上一些水果,给房子装修,都是装饰器模式。
装饰器模式在代码程序中适用于以下应用场景。
(1)用于扩展一个类的功能,或者给一个类添加附加职责。
(2)动态地给一个对象添加功能,这些功能可以再动态地被撤销。
(3)需要为一批平行的兄弟类进行改装或加装功能。
1. Component Interface
– The interface or abstract class defining the methods that will be implemented.
public interface ICar {
public void assemble();
}
2. Component Implementation
– The basic implementation of the component interface.
public class BasicCar implements ICar {
public BasicCar() {
System.out.println("A2_BasicCar 构造方法");
}
@Override
public void assemble() {
System.out.println("Basic Car.");
}
}
3. Decorator
– Decorator class implements the component interface and it has a HAS-A relationship with the component interface.
The component variable should be accessible to the child decorator classes, so we will make this variable protected.
public class CarDecorator implements ICar {
protected ICar car;
public CarDecorator(ICar c) {
this.car = c;
System.out.println("CarDecorator 构造方法");
}
@Override
public void assemble() {
System.out.println("Decorator 被调用前 记录一下.");
this.car.assemble();
System.out.println("Decorator 被调用后 记录一下.");
}
}
4. Concrete Decorators
– Extending the base decorator functionality and modifying the component behavior accordingly.
public class LuxuryCar extends CarDecorator {
public LuxuryCar(ICar c) {
super(c);
System.out.println("LuxuryCar 构造方法");
}
@Override
public void assemble(){
super.assemble();
System.out.println("Adding features of Luxury Car.");
}
}
public class SportsCar extends CarDecorator {
public SportsCar(ICar c) {
super(c);
System.out.println("SportsCar 构造方法");
}
@Override
public void assemble() {
super.assemble();
System.out.println("Adding features of Sports Car.");
}
}
测试
ICar sportsCar = new SportsCar(new BasicCar());
sportsCar.assemble();
BasicCar 构造方法
CarDecorator 构造方法
SportsCar 构造方法
Decorator 被调用前 记录一下.
Basic Car.
Decorator 被调用后 记录一下.
Adding features of Sports Car.
ICar luxuryCar = new LuxuryCar(new BasicCar());
luxuryCar.assemble();
BasicCar 构造方法
CarDecorator 构造方法
LuxuryCar 构造方法
Decorator 被调用前 记录一下.
Basic Car.
Decorator 被调用后 记录一下.
Adding features of Luxury Car.
ICar sportsLuxuryCar = new SportsCar(new LuxuryCar(new BasicCar()));
sportsLuxuryCar.assemble();
BasicCar 构造方法
CarDecorator 构造方法
LuxuryCar 构造方法
CarDecorator 构造方法
SportsCar 构造方法
Decorator 被调用前 记录一下.
Decorator 被调用前 记录一下.
Basic Car.
Decorator 被调用后 记录一下.
Adding features of Luxury Car.
Decorator 被调用后 记录一下.
Adding features of Sports Car.
Important Points
- Decorator design pattern is helpful in providing runtime modification abilities and hence more flexible. Its easy to maintain and extend when the number of choices are more.
- The disadvantage of decorator design pattern is that it uses a lot of similar kind of objects (decorators).
- Decorator pattern is used a lot in Java IO classes, such as FileReader, BufferedReader etc.
装饰器模式在JDK源码中的应用
装饰器模式在源码中应用得非常多,在JDK中体现最明显的类就是与I/O相关的类,如BufferedReader、InputStream、OutputStream,看一下常用的InputStream的类图,如下图所示。