介绍
装饰模式(Decorator Pattern)也称为包装模式(Wrapper),结构模式之一,其使用一种对客户端透明的方式来动态的扩展对象的功能,同时也是继承关系的一种替代方案之一。
定义
动态给一个对象添加一些额外的职责,就增加功能来说,装饰模式相比生成子类更为灵活。
使用场景
需要透明且动态地扩展类的功能时。
UML类图
角色介绍
- Component:抽象组件
可以是一个接口或者抽象类,其充当的就是被装饰的原始对象。
- ConcreteComponent:组件具体实现类
该类是Component类的基本实现,也是我们装饰的具体对象。
- Decorator:抽象装饰者
其承担的职责就是为了装饰我们的组件对象,其内部一定要有一个指向组件对象的引用。在大多数情况下,该类为抽象类,需要根据不同的装饰逻辑实现不同的具体子类。当然,如果装饰逻辑单一,只有一个的情况下我们可以省略该类直接作为具体的装饰者。
- ConcreteDecoratorA:装饰者具体实现类
只是对抽象装饰者作出具体的实现。
示例代码
Component
public interface Student {
void study();
}
ConcreteComponent
public class SecondaryStudent implements Student {
@Override
public void study() {
System.out.println("学生的职责是学习");
}
}
Decorator
public class DecoratorStudent extends SecondaryStudent {
Student student;
public DecoratorStudent(Student student) {
this.student = student;
}
@Override
public void study() {
student.study();
}
}
ConcreteDecoratorA
public class StudentA extends DecoratorStudent {
public StudentA(Student student) {
super(student);
}
@Override
public void study() {
super.study();
studyChinese();
studyArt();
}
public void studyChinese() {
System.out.println("我是艺术生,学习语文");
}
public void studyArt() {
System.out.println("我是艺术生,学习美术");
}
}
public class StudentB extends DecoratorStudent {
public StudentB(Student student) {
super(student);
}
@Override
public void study() {
super.study();
studyComprehensive();
}
public void studyComprehensive() {
System.out.println("我是艺术生,学习理综");
}
}
Test
public class TestDecoratorPattern {
public static void main(String[] args) {
Student stu = new SecondaryStudent();
DecoratorStudent stuA = new StudentA(stu);
stuA.study();
System.out.println("----------------------");
DecoratorStudent stuB = new StudentB(stu);
stuB.study();
}
}
运行结果
学生的职责是学习
我是艺术生,学习语文
我是艺术生,学习美术
-------------------
学生的职责是学习
我是艺术生,学习理综
问题及解决
用装饰者实例化组件时,将增加代码的复杂度,一旦应用了装饰者模式,不只需要实例化组件,还要把组件包装进装饰者,而这样的装饰者有多少个是不确定的。这里可以应用工厂模式来实例化组件来简化操作。