一、前言
本篇主题为结构型模式中的第三个模式–装饰模式。上篇 Java 设计模式主题为《Java 设计模式之桥接模式(七)》。
二、简单介绍
# 2.1 定义
装饰(Decorator)模式又叫做包装模式,其功能是动态地给一个对象添加一些额外的职责。就增加功能来说,装饰模式相比生成子类更为灵活,是继承关系的一个替换方案。
# 2.2 参与角色
- Component:定义一个对象接口,可以给这些对象动态地添加职责。
- ConcreteComponent:定义一个对象,可以给这个对象添加一些职责。
- Decorator:维持一个指向 Component 对象的指针,并定义一个与 Component 接口一致的接口。
- ConcreteDecorator:向组件添加职责。
# 2.3 应用场景
- 在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
- 当不能采用生成子类的方法进行扩充时。
三、实现方式
我们以人的打扮为例。人打扮需要穿衣,穿裤,穿鞋子。代码表示如下:
Person 类:
1 | 复制代码public class Person { |
客户端:
1 | 复制代码public class Client { |
打印:
1 | 复制代码小白穿衣服 |
上述代码很简单,但是扩展性不好。当我们需要添加打领带、戴手表的行为时,需要修改 Person 类,违背了开放封闭原则。
因此,我们需要将人和打扮的行为抽离出来:
Person 类:
1 | 复制代码public class Person { |
打扮类:
1 | 复制代码public abstract class DressUp { |
客户端:
1 | 复制代码public class Client { |
执行结果与上文的一致。现在,当我们添加新的打扮行为时,只需新增 DressUp 的子类即可。
但是,上边的代码没有封装性,每打扮一次都要调用 dressup 方法一次,就感觉人是光着身在公共场合进行打扮穿衣、穿鞋。因此,我们需要一种模式将这些打扮的细节封装起来,就像建造者模式一样。
不过,此次的需求不能使用建造者模式。因为建造者模式封装过程/细节是一个固定的顺序/模式,而当前需求是人的打扮,打扮的行为是多种多样的,如:穿衣穿裤、穿衣打领带、穿鞋戴手表等。
这样就引出了本章的主题–装饰模式:
Person 接口与实现类(Component 和 ConcreteComponent):
1 | 复制代码public interface Person { |
装饰类(Decorator 和 ConcreteDecorator):
1 | 复制代码public class Decorator implements Person { |
客户端:
1 | 复制代码public class Client { |
打印:
1 | 复制代码======第一种打扮======= |
总结:装饰模式有效地把类的核心职责和装饰功能区分开来,而且去除了相关类的重复的装饰逻辑。
UML 类图表示如下:
本文转载自: 掘金