七个结构模式之装饰者模式(Decorator Pattern)
定义:
使用组合的方法,动态给一个类增加一些额外的功能,避免因为使用子类继承而导致类继承结构复杂。并且可以保持和被装饰者同一个抽象接口,从而使客户端透明。
结构图:
- Component:抽象构件类,定义了具体构件和装饰者的共同父类,定义了构件中需要被实现的业务方法。其引入向客户端屏蔽了实现细节,可以统一地处理伪装是之前的具体构件和装饰者类。
- ConcreteComponent:具体构件类,实现了抽象构件类中定义的业务方法。一般其方法都是比较简单,可以在装饰者中进一步修饰和增加职能。
- Decorator:抽象装饰者类,持有了一个抽象构件类对象的引用,并且定义了抽象构建类对象的注入方法,同样在实现抽象构建类定义的业务方法时,但只是简单地调用了成员变量的方法。具体职能的增加,放入到子类中。
- ConcreteDecorator:具体装饰者类,继承了抽象继承类,并重写了其业务方法,在业务方法中加入了新的职能。
透明和半透明模式
在一些情况下装饰类中新添加的功能方法与原有的业务方法相互独立,而且客户端希望可以直接调用,因此就有两种模式。
- 透明模式:
装饰模式的标准模式,客户端完全针对抽象层编程,不应该将对象声明为具体构件类或具体装饰类,这两者没有任何区别。并且透明模式允许对象可以被多次装饰使用,来实现更复杂的功能。但透明模式并不能直接访问装饰类新增的功能。 - 半透明模式:
半透明模式中,客户端可以不用关心具体的构件,但是需要声明具体的装饰类。半透明模式增加了系统的灵活性,但是不能对对象进行多次修饰,并且需要对两种不同的构件进行区别对待。
装饰者模式与桥接模式的区别
- 桥接模式包含两个独立变化的维度,并且只在抽象层利用组合建立了桥接关系。
- 装饰者模式包含的两个维度相互依赖,装饰者所在的维度一般要依赖于具体抽象构件类的维度。并且不仅利用组合建立了连接关系,同时两个维度还同时继承了同一个抽象构建类。
注意:
- 尽量保持装饰者类与被装饰者类接口一致,从而使客户端可以透明地使用,并利用配置文件等可以灵活地扩展。
- 尽量保持被装饰者类是一个轻类,不用把太多的行为放在装饰者类中,我们可以通过装饰者类对其进行扩展。
- 如果只有一个具体构件类,可以直接让装饰者类继承该构建类。如图:
优点:
- 可以动态地为类添加功能,并且不会导致类的个数急剧增加。
- 可以对一个对象多次装饰,使用不同的装饰类进行组合可以实现复杂的功能。
- 具体构件和装饰类可以独立变化,方便扩展,符合开闭原则。
适用场景:
- 在不影响其它类的情况下,动态、透明地给单个对象增加职责。
实例: