一、装饰器模式的定义:
装饰器模式:就是对已经存在的某些类进行装饰,以此来扩展一些功能。
二、模式解释:
Component(抽象构件角色):真实对象和装饰对象有相同的接口。这样,客户端对象就能够以与真实对象相同的方式同装饰对象交互。
ConcreteComponent(具体构件角色):真实对象,实现Component接口。
Decorator(装饰角色):持有一个抽象构件的引用。装饰对象接受所有客户端的请求,并把这些请求转发给真实的对象。这样,就能在真实对象调用前后增加新的功能。
ConcreteDecorator(具体装饰角色):负责给构件对象增加新的责任。
三、为什么使用装饰器模式:
装饰器模式是一种用于代替继承的技术,无需通过继承增加子类就能扩展对象的新功能。使用对象的关联关系代替继承关系,更加灵活,同时避免类型体系的快速膨胀。
四、示例代码:
先创建一个抽象组件CarComponent
/**
* <pre>
* @author : orange
* @e-mail : 495314527@qq.com
* @time : 2018/9/30 17:09
* @desc : 抽象构件角色:真实对象和装饰对象有相同的接口
* @version: 1.0
* </pre>
*/
public interface CarComponent {
void run();
}
再创建一个具体的角色,实现CarComponent接口(真是对象)
/**
* <pre>
* @author : orange
* @e-mail : 495314527@qq.com
* @time : 2018/9/30 17:11
* @desc : 具体构件角色(真实对象)
* @version: 1.0
* </pre>
*/
public class ConcreteCarComponent implements CarComponent {
@Override
public void run() {
System.out.println("在陆地上跑!");
}
}
装饰类:
/**
* <pre>
* @author : orange
* @e-mail : 495314527@qq.com
* @time : 2018/9/30 17:12
* @desc : 装饰类
* @version: 1.0
* </pre>
*/
public class Decorator implements CarComponent {
public CarComponent component;
public Decorator(CarComponent component){
this.component = component;
}
@Override
public void run() {
component.run();
}
}
具体装饰类:
/**
* <pre>
* @author : orange
* @e-mail : 495314527@qq.com
* @time : 2018/9/30 17:15
* @desc :
* @version: 1.0
* </pre>
*/
public class ConcreteDecorator extends Decorator {
public ConcreteDecorator(CarComponent component) {
super(component);
}
public void run(){
super.run();
System.out.println("在水上跑!");
}
}
客户端测试:
/**
* <pre>
* @author : orange
* @e-mail : 495314527@qq.com
* @time : 2018/9/30 17:34
* @desc :
* @version: 1.0
* </pre>
*/
public class Client {
public static void main(String[] args){
ConcreteDecorator decorator = new ConcreteDecorator(new ConcreteCarComponent());
decorator.run();
}
}
总结:
一个设计模式的出现一定有他特殊的价值。仅仅看见上面的结构图你可能会想,为何要兜这么一圈来实现?仅仅是想要多一行输出,我直接继承ConcretCarComponent,或者直接在另一个Component的实现类中实现不是一样吗?
回到这个例子中,我们看到的仅仅是一个ConcretCarComponent类。在复杂的大型项目中,同一级下的子类通常有很多。当你有五个甚至十个ConcretCarComponent时,再想要为每个类都加上类似“在水上跑”的功能效果,就要写出五个子类了。毫无疑问这是不合理的。装饰器模式在不影响各个ConcretCarComponent同时,添加了他特有的装饰效果,具备非常好的通用性,这也是他存在的最大价值。