1、介绍
装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。
这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能
①、要点:
- 不改变原类文件
- 不使用继承
- 动态扩展
②、使用场景:
- 扩展一个类的功能
- 动态增加功能,动态撤销
在不想增加很多子类的情况下扩展类。
③、优点:
装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。
2、类图(经典)
在装饰模式中的角色有:
- 抽象构件(Component)角色:给出一个抽象接口,以规范准备接收附加责任的对象
- 具体构件(ConcreteComponent)角色:定义一个将要接收附加责任的类
- 装饰(Decorator)角色:持有一个构件(Component)对象的实例,并定义一个与抽象构件接口一致的接口
- 具体装饰(ConcreteDecorator)角色:负责给构件对象“贴上”附加的责任。
类图的结构可以变化的地方:
- Component接口可以是接口也可以是抽象类,甚至是一个普通的父类(这个强烈不推荐,普通的类作为继承体系的超级父类不易于维护)
- 装饰器的抽象父类Decorator并不是必须的。
3、代码示例
抽象构件角色
1 | public interface Component { |
具体的接口实现类,也就是俗称的原始对象,或者说待装饰对象
1 | public class ConcreteComponent implements Component { |
抽象装饰器父类,它主要是为装饰器定义了我们需要装饰的目标是什么,并对Component进行了基础的装饰
1 | public class Decorator implements Component { |
具体装饰角色
1 | public class ConcreteDecoratorA extends Decorator { |
1 | public class ConcreteDecoratorB extends Decorator { |
测试类
1 | public class TestDecoratorPattern { |
4、装饰模式的简化类图
如果只有一个ConcreteComponent类,那么可以考虑去掉抽象的Component类(接口),把Decorator作为一个ConcreteComponent子类。如下图所示:
如果只有一个ConcreteDecorator类,那么就没有必要建立一个单独的Decorator类,而可以把Decorator和ConcreteDecorator的责任合并成一个类。甚至在只有两个ConcreteDecorator类的情况下,都可以这样做。如下图所示: