前言
其实,在学习装饰者模式之前,我们也学了代理模式,下面看装饰器模式的类图
是不是跟代理模式的类图特像呢。。不过他们各有侧重点。
- 代理模式,专注于被代理对象的访问
- 装饰器模式,则专注于被装饰对象的附加额外功能
装饰器实现修饰对象(Component)的接口,所有请求都转发给它处理,在转发请求之前/之后增加额外功能。使用步骤是:
- 用一个Decorator实现/继承需要修饰的对象Component;
- 在Decorator中增加一个Component的引用;
- 在Decorator的构造器中,增加一个Component参数来初始化Component;
- 在Decorator类中,使用Component的引用,将所有请求转发至Component的相应方法;
- ConcreteDecorator中所有Override自Component的方法做相应调整
适用场景
运行时,你需要动态地为对象增加额外职责时;
当你需要一个能够代替子类的类,借助它提供额外方法时
代码实现
比如,我现在买一部比亚迪唐的丐版汽车,标准的价格是20W RMB,现在我要加360全景影像,需要1WRMB, 再加一套真皮座椅需要0.5WRMB,这就可以通过装饰器模式实现
首先,我们定义一个汽车接口
/**
* Author dengcs
* date 2020-06-26
* comment 汽车接口
*/
public interface Car {
//获取价格
public double getPrice();
//获取配置
public String getConfigure();
}
写一个装饰器类,同样实现汽车Car的接口,并引用Car,通过构造函数进行初始化。并将getPrice()和getConfigure()方法转发给被装饰对象。
/**
* Author dengcs
* date 2020-06-26
* comment 汽车的装饰类,可以对被装饰器类添加各种配置
*/
public class CarDecorator implements Car {
protected final Car decoratorCar;
//构造函数进行初始化
public CarDecorator(Car car) {
this.decoratorCar = car;
}
@Override
public double getPrice() {
return decoratorCar.getPrice();
}
@Override
public String getConfigure() {
return decoratorCar.getConfigure();
}
}
现在实现一个唐的丐版类,价格20W,配置只有标准的配置,如下
/**
* Author dengcs
* date 2020-06-26
* comment 唐的标准版
*/
public class TangCar implements Car {
@Override
public double getPrice() {
return 200000d;
}
@Override
public String getConfigure() {
return "标准配置";
}
}
具体加360全景影像类,如下
/**
* Author dengcs
* date 2020-06-26
* comment 360全景影像类
*/
public class RoundCar extends CarDecorator{
public RoundCar(Car car) {
super(car);
}
@Override
public double getPrice() {
double addPrice = 10000d;
return super.getPrice()+addPrice;
}
@Override
public String getConfigure() {
return super.getConfigure()+";360全景影像";
}
}
最后,添加真皮座椅的装饰器类,原理一样
/**
* Author dengcs
* date 2020-06-26
* comment 真皮座椅装饰器类
*/
public class ZhenpiCar extends CarDecorator{
public ZhenpiCar(Car car) {
super(car);
}
@Override
public double getPrice() {
double addPrice = 5000d;
return super.getPrice()+addPrice;
}
@Override
public String getConfigure() {
return super.getConfigure()+";真皮座椅";
}
}
测试
测试代码DecoratorTest类,进行测试
/**
* Author dengcs
* date 2020-06-26
* comment 测试
*/
public class DecoratorTest {
private static void print(Car car){
System.out.println("花费了:"+car.getPrice());
System.out.println("配置:"+car.getConfigure());
System.out.println("====================");
}
public static void main(String[] args){
//标准配置
Car car = new TangCar();
print(car);
//增加360全景影像
car = new RoundCar(car);
print(car);
//增加真皮座椅
car = new ZhenpiCar(car);
print(car);
}
}
测试结果如下
写在最后
从上个例子可以看出,装饰器模式的结构很像代理模式,装饰器模式的请求转发过程很像责任链模式,只不过:
职责链模式在转发请求过程中,最多只有一个对象会处理请求,而装饰器模式则有多个对象处一个请求。
装饰器模式是代替增加子类的一种解决方案,体现了聚合/合成复用原则的思想,尽量使用组合的方式来扩展功能,这样就把基本功能和扩展功能解耦了,使得代码可复用,可维护,灵活。关键点在于装饰器模式可以动态地为对象增加扩展功能。
相应了解更多的设计模式,请关注我哦O(∩_∩)O哈哈~