装饰者模式动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。
参考《Head First Design Pattern》第二版,使用其中的例子来进行时间,首先来看看 UML 图
(1)该图最上面是 Component 抽象类,是所有类基类,下面的每一个类都是它的子类
(2)左边的 ConcreteComponent 是积累的具体类,这些类是真正需要被修饰的类;
(3)右边 Decorator 是装饰器的父类,所有装饰器都需要继承这个类
(3.1)这个类需要继承 Component 基类
(3.2)同时,对 Component 类中的非抽象方法,且必须要子类重写的方法,可以在这个 Decorator 类中将其声明为抽象方法;
(4)Decorator 类下的子类就是具体的装饰器
(4.1)这些装饰器必须实现 Component 和 Decorator 类中的抽象方法
(4.2)这些类实际上也是基类 Component 的对象,只不过加了一些特殊的东西;
在《Head First Design Pattern》这本书中,实现方式是使用抽象类实现的;但是还有一种上层使用接口的方式实现的;
(1)基本类:最上层的基本类中可以有非抽象方法,该方法在基本类中实现基本的需求,但是又希望子类去重写它,而且必须重写,可以使用在装饰器的抽象类中将该方法声明为抽象方法;
(2)装饰器抽象类:该类主要是起一个规范作用,将所有装饰器需要实现的方法,而基本类中不是抽象方法的方法在此处声明;该类需要继承基本类;
(3)具体组件:这些组件是对基本类的具体实现,因为基本类是抽象类,不能实例化,真正被装饰的其实是这些子类
(4)装饰器的父类是抽象方法,在这个设计中,我们将基本类的引用放在了每个具体的装饰器中实现。
(1)最上层是一个接口,该接口中列举所有装饰器以及具体被装饰对象需要实现的方法;我将其看作是一个规范接口,通过这个接口,可以很容易看出装饰器这些类中需要实现什么方法;
(2)基本类:基本类直接实现这个接口,不是抽象类;接口方法只做简单的实现,不做任何特别的处理;
(3)被装饰对象:直接继承基本类,并且按需求实现最顶层接口中的方法;
(4)装饰器的父类:这个类直接继承基本类,在该类中定义一个最上层接口的引用或者是基本类的引用,并使用有参构造的方式为该类注入一个基本类的参数;
(5)装饰器:各个装饰器继承装饰器的父类,并且强制给出一个带参的构造器,在构造器中使用 super 调用父类构造器,注入参数;并且实现接口中的类方法,也可以按需求增加额外的方法;
装饰器就是在不改变基本类型的情况下,增加新的类别,为该类别添加一个新的属性,或者新的特性,但是从继承关系上来看,任然属于基本类,即任然还是基本类的东西;这种方式利于增加类别,并且可以根据现有的装饰类,来组合更多的不同类别;
(1)Java 中的 IO 流