Decorator(装饰器模式)
目的:
动态地给一个对象添加一些额外的职责。
适用性:
在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
简单解释
当有一个已经完成的系统,其中类和对象的关系的错综复杂的,此时若想给某类对象添加一些额外的属性或方法(状态或职责),可能会引起其他地方的报错。
因此就需要在目标类的同一层级,新增一个与目标类继承同一父类的抽象修饰器类(方便向上转型),并且在其中包含有父类类型的一个引用(方便接收目标对象)。
修饰器下一层的具体实现类 ConcreteDecorator 继承 Decorator,并负责具体的职责添加,可以选择添加状态(属性) addedState 或者添加行为(方法) AddedBehavior()。
而在使用中,由于 ConcreteDecorator 继承了 Decorator, Decorator 又继承自 Component ,因此对于 ConcreteDecorator 可以直接向上转型到 Component。
目标对象 ConcreteComponent 也可以向上转型到 Component,此时两者类型相同,可直接进行 “=” 操作,实现了目标对象的“职责更新”。
(但其实此时,实现更新后的新对象其结构已经不是左边的单一层级了,而是右边的修饰器的多层级了。在内存中已经是两个不同地址的引用了)
代码示例
假设原有结构有 抽象类Person ,具体实现类 Student,其职责 Operation() 为学习。
package decorator;public class DecoratorDemo {public static void main(String[] args) {Person zhangsan = new Student("张三");zhangsan.Operation();}
}abstract class Person{ // Componentprotected String name;abstract public void Operation(); // 职责
}class Student extends Person{ // ConcreteComponentpublic Student(String name) {this.name = name;}@Overridepublic void Operation() {System.out.println(name + "的职责是:学习");}
}
- 输出:张三的职责是:学习
现在要新增职责 “读书”,使用修饰器实现:
package decorator;public class DecoratorDemo {public static void main(String[] args) {Person zhangsan = new Student("张三");zhangsan.Operation();System.out.println("\n------------------");// Decorator DecoratorA = new DecoratorA(zhangsan); //向上转型到Decorator// Person DecoratorA = new DecoratorA(zhangsan); //向上转型到Personzhangsan = new DecoratorA(zhangsan); // Person类型相同,可以直接赋值zhangsan.Operation();System.out.println("\n------------------");zhangsan = new DecoratorB(zhangsan); // 继修饰器A添加“读书”后,在用修饰器B添加“写作业”zhangsan.Operation();}
}abstract class Decorator extends Person{ // 与目标类 Student 继承统一父类 Personprotected Person person; // 包含有父类类型的引用
}class DecoratorA extends Decorator{public DecoratorA(Person person) { // 构造函数接收目标对象this.person = person;}@Overridepublic void Operation() {person.Operation(); // 原有的职责System.out.print("读书 "); // 新增职责}
}class DecoratorB extends Decorator{public DecoratorB(Person person) { // 构造函数接收目标对象this.person = person;}@Overridepublic void Operation() {person.Operation(); // 原有的职责System.out.print("写作业"); // 新增职责}
}abstract class Person{ // Componentprotected String name;abstract public void Operation(); // 职责
}class Student extends Person{ // ConcreteComponentpublic Student(String name) {this.name = name;}@Overridepublic void Operation() {System.out.print(name + "的职责是:学习 ");}
}
输出:
张三的职责是:学习
------------------
张三的职责是:学习 读书
------------------
张三的职责是:学习 读书 写作业
参考
B站 zst_2001 软考设计模式