装饰着模式,顾名思义,就是将某个类重新装扮一下,使得它比原来更“漂亮”,或者在功能上更强大,这就是装饰器模式所要达到的目的。但是作为原来的这个类的使用者还不应该感受到装饰前与装饰后有什么不同,即用法不变,否则就破坏了原有类的结构了,所以装饰器模式要做到对被装饰类的使用者透明,这是对装饰器模式的一个基本要求。
设计原则:类应该对扩展开放,对修改关闭。
装饰者模式:动态的将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。
Component(组件) | 为统一接口,也是装饰类和被装饰类的基本类型。 |
ConcreteComponent (具体组件、被装饰者) | 为具体实现类,也是被装饰类,他本身是个具有一些功能的完整的类。 |
Decorator(装饰者类) | 是装饰类(装饰者共同实现的接口,也可以是抽象类),实现了Component接口的同时还在内部维护了一个ConcreteComponent的实例,并可以通过构造函数初始化。而Decorator本身,通常采用默认实现,他的存在仅仅是一个声明:我要生产出一些用于装饰的子类了。而其子类才是赋有具体装饰效果的装饰产品类。
必须让Decorator 能够取代Component,所以将Decorator扩展自 Component。 |
ConcreteDecorator(装饰者) | 是具体的装饰产品类,每一种装饰产品都具有特定的装饰效果。可以通过构造器声明装饰哪种类型的ConcreteComponent,从而对其进行装饰(扩展)。
要让ConcreteDecorator能够引用一个Component,做法如下: (1)用一个实例变量记录ConcreteDecorator,也就是被装饰者 (2)想办法让被装饰者(ConcreteDecorator)被记录到实例变量中。 把ConcreteDecorator当作构造器的参数,再由构造器将此ConcreteDecorator记录在实例变量中。 |
//基础接口
public interface Component {
public void title();
}
//具体实现类
public class ConcretComponent implements Component {
public void title() {
System.out.println("公告内容如下");
}
}
//装饰类
public class Decorator implements Component {
public Component component;
public Decorator(Component component) {
this.component = component;
}
@Override
public void title() {
this.component.title();
}
}
//具体装饰类
public class TjHospitalDecorator extends Decorator {
public ConcreteDecorator(Component component) {
super(component);
}
@Override
public void title() {
System.out.println("Tjhospital 将于 ... ");
this.component.title();
}
}
装饰器模式的特点是: 透明的给一个对象添加一些职责。比如spring
中的aop
,比如express
的中间件、redux
的中间件、vuex
的中间件等,都是一些装饰模式的思想。