装饰者模式可以扩展一个类的功能或给一个类添加附加职责
优点:
1.不改变原有对象的情况下给一个对象扩展功能
2.使用不同的组合可以实现不同的效果
3.符合开闭原则
装饰者模式中包含的角色
1.Component 接口
所以的被包装类、包装类都实现了这个接口。
2.ConcreteComponent 类
被包装的实现类
3.Decorator 抽象类
所有的包装类都继承自这个类,Decorator实现Component接口方便实现多层嵌套包装
4.ConcreteDecorator 类
具体的包装类,用于扩展功能
假设我们有一辆汽车,现在需要给汽车添加新的功能,这时候就可以使用装饰者模式。
汽车的接口(Component)
public interface Car {
void run();
}
汽车(ConcreteComponent)
public class BenCar implements Car {
@Override
public void run() {
System.out.println("奔驰开车了");
}
}
装饰器(Decorator)
public abstract class CarDecorator implements Car {
Car decoratorCar;
public CarDecorator(Car decoratorCar) {
this.decoratorCar = decoratorCar;
}
@Override
public void run() {
decoratorCar.run();
}
}
附加不同的功能(ConcreteDecorator)
public class AutoCarDecorator extends CarDecorator{
public AutoCarDecorator(Car decoratorCar) {
super(decoratorCar);
}
@Override
public void run() {
decoratorCar.run();
autoRun();
}
private void autoRun() {
System.out.println("开启自动驾驶");
}
}
public class FlyCarDecorator extends CarDecorator {
public FlyCarDecorator(Car decoratorCar) {
super(decoratorCar);
}
@Override
public void run() {
decoratorCar.run();
fly();
}
private void fly() {
System.out.println("开启飞行功能");
}
}
客户使用
public class Client {
public static void main(String[] args) {
BenCar benCar = new BenCar();
Car autoCar = new AutoCarDecorator(benCar);
Car flyAutoCar = new FlyCarDecorator(new AutoCarDecorator(benCar));
autoCar.run(); // 奔驰开车了 开启自动驾驶
flyAutoCar.run(); // 奔驰开车了 开启自动驾驶 开启飞行功能
}
}
装饰者模式在实际开发中的应用:
最典型的应用是 Java 中的 IO 流
为了满足不同输入场景,JDK 设计了多种多样的输入流,包括ByteArrayInputStream、FileInputStream(相当于汽车),这些输入流继承自共同的抽象类 InputStream(相当于汽车的接口),于此同时为了给这些输入流带来功能上的扩展,JDK设计了一个装饰器类 FileIterInputStream。该类继承自 InputStream,并且聚合了 InputStream 成员对象。
从FileInputStream类派生出了许多装饰器子类,包括 BufferedInputStream、DataInputStream等,分别提供了输入流缓冲,以及输入流获取Java基本数据类型等额外功能。