通过使用修饰模式,可以在运行时扩充一个类的功能。原理是:增加一个修饰类包裹原来的类,包裹的方式一般是通过在将原来的对象作为修饰类的构造函数的参数。装饰类实现新的功能,但是,在不需要用到新功能的地方,它可以直接调用原来的类中的方法。修饰类必须和原来的类有相同的接口。
修饰模式是类继承的另外一种选择。类继承在编译时候增加行为,而装饰模式是在运行时增加行为。
当有几个相互独立的功能需要扩充时,这个区别就变得很重要。在有些面向对象的编程语言中,类不能在运行时被创建,通常在设计的时候也不能预测到有哪几种功能组合。这就意味着要为每一种组合创建一个新类。相反,修饰模式是面向运行时候的对象实例的,这样就可以在运行时根据需要进行组合。
举个例子好比一个一岁的小孩高兴时他只能通过笑来表达,两岁的孩子呢,不仅通过笑来表达自己很高兴,还会跳,三岁的小孩除了笑和跳还会说我好高兴啊。
按照这种结构最后设计的类图如下:
首先需要顶一个Kid类,它是个抽象类,它包含一个抽象方法来显示孩子获得的奖励。
然后是一个基本的类GoodKid来继承Kid类并实例化那个抽象的奖励方法;
然后是创建一个抽象的类作为基本协议类:
最后出来的使具体的那些装饰类:
还有个例子:
最终的客户端实现代码: