装饰模式:
动态地将额外的责任附加到对象上。装饰器提供了一个灵活的子类扩展功能的替代方法。
2.要解决的问题
子类化是在编译时静态扩展类功能(向类添加职责)的标准方法。实例化子类后,该功能将在其生命周期绑定到该实例,并且无法在运行时进行更改。
如果我们想在运行时扩展对象的功能,而不是在编译时扩展类的功能,则可以避免这种方法。
3.解决方案
定义单独的Decorator对象:
定义一个类(Decorator),该类维护对Component对象的引用,并将请求转发到该组件
定义Decorator1实现额外功能的子类,以便在请求转发之前或之后执行
此模式的关键思想是遍历Decorator“装饰器”(已添加的)对象(向其添加职责)的单独对象。装饰器Component透明地实现该接口,以便它可以充当要装饰的组件的透明外壳。“客户端通常无法告诉他们是在处理组件还是其附件”。
因为装饰器是装饰组件的透明外壳,所以它们可以递归嵌套以增加职责的开放性。更改装饰器的顺序允许添加职责的任意组合。
4.动机
在编译时扩展功能:
子类执行其他职责,实例化子类后,职责将在实例的生命周期内绑定到实例,并且无法在运行时更改。
子类的爆炸式增长:通过子类扩展功能需要为每个新功能和每个功能组合创建一个新的子类,支持大量功能及其组合将产生大量子类。
5.适用性
运行时扩展功能:
子类的灵活替代:
如何为子类提供灵活的替代方案,以便编译时扩展类的功能
重构问题:
如何重构包含连线扩展的类。
6.结构
Component(抽象构件):它是具体构件和抽象装饰类的共同父类,声明了在具体构件中实现的业务方法,它的引入可以使客户端以一致的方式处理未被装饰的对象以及装饰之后的对象,实现客户端的透明操作。
ConcreteComponent(具体构件):它是抽象构件类的子类,用于定义具体的构件对象,实现了在抽象构件中声明的方法,装饰器可以给它增加额外的职责(方法)。
Decorator(抽象装饰类):它也是抽象构件类的子类,用于给具体构件增加职责,但是具体职责在其子类中实现。它维护一个指向抽象构件对象的引用,通过该引用可以调用装饰之前构件对象的方法,并通过其子类扩展该方法,以达到装饰的目的。
ConcreteDecorator(具体装饰类):它是抽象装饰类的子类,负责向构件添加新的职责。每一个具体装饰类都定义了一些新的行为,它可以调用在抽象装饰类中定义的方法,并可以增加新的方法用以扩充对象的行为。
7.协作
8.优缺点
主要优点
装饰模式的主要优点如下:
(1) 对于扩展一个对象的功能,装饰模式比继承更加灵活性,不会导致类的个数急剧增加。
(2) 可以通过一种动态的方式来扩展一个对象的功能,通过配置文件可以在运行时选择不同的具体装饰类,从而实现不同的行为。
(3) 可以对一个对象进行多次装饰,通过使用不同的具体装饰类以及这些装饰类的排列组合,可以创造出很多不同行为的组合,得到功能更为强大的对象。
(4) 具体构件类与具体装饰类可以独立变化,用户可以根据需要增加新的具体构件类和具体装饰类,原有类库代码无须改变,符合“开闭原则”。
主要缺点
装饰模式的主要缺点如下:
(1) 使用装饰模式进行系统设计时将产生很多小对象,这些对象的区别在于它们之间相互连接的方式有所不同,而不是它们的类或者属性值有所不同,大量小对象的产生势必会占用更多的系统资源,在一定程序上影响程序的性能。
(2) 装饰模式提供了一种比继承更加灵活机动的解决方案,但同时也意味着比继承更加易于出错,排错也很困难,对于多次装饰的对象,调试时寻找错误可能需要逐级排查,较为繁琐。
9.实施
接口一致性:
装饰器的关键
10.代码:
package decorator;
public interface Component {
public String opreation();
}
package decorator;
public class Component1 implements Component{
@Override
public String opreation() {
// TODO Auto-generated method stub
return "Hello World from Component1 !";
}
}
package decorator;
public abstract class Decorator implements Component {
private Component component;
public Decorator(Component c) {
component=c;
}
public String opreation() {
return component.opreation();
}
}
package decorator;
public class Decorator1 extends Decorator{
public Decorator1(Component c) {
super(c);
// TODO Auto-generated constructor stub
}
public String opreation() {
return this.addMethod1()+super.opreation()+this.addMethod1();
}
public String addMethod1() {
return " *** ";
}
}
package decorator;
public class Decorator2 extends Decorator{
public Decorator2(Component c) {
super(c);
// TODO Auto-generated constructor stub
}
public String opreation() {
return this.addMethod2()+super.opreation()+this.addMethod2();
}
public String addMethod2() {
return " === ";
}
}
package decorator;
public class Client {
public static void main(String[] args) {
Component component=new Component1();
System.out.println("(1) "+component.opreation());
component=new Decorator1(new Decorator2(component));
System.out.println("(2) "+component.opreation());
}
}
11.结果: