装饰模式
装饰模式,又称之为包装器,顾名思义,把一个东西拿过来包装一下然后变成一个新的东西;但装饰模式又不是如此简单,包装过后的新东西不能变成其他的东西,还得是原来得东西,只是功能或是外观有所变化而已。如果借用初中化学的一句话来说,就是包装应该是物理变化而不能是化学变化。
还是说说实现吧,采用装饰模式至少要有四个类:原型类、实型类、装饰基类、装饰派生类;其实嘛,装饰基类和装饰派生类可以作为一个类,但是想想,如果仅仅需要添加一个功能,装饰一次,何必还要采用装饰模式呢,直接采用实型类的派生类不是更简单更方便,所以通常把装饰类分为基类和派生类。
原型类通常为抽象类,规定了类成员和类的所有方法;原型类也是所有其他类的基类(当然不一定都具有直接继承关系)。实型类就是拿出来使用的类,设计它时可以不用考虑所有的功能,只优先考虑那些暂时需要的功能;等到使用了一段时间以后,可能会发现,哦,怎么回事,我当初怎么没想到还有这个功能没做啊?这时候,也不用急,把它装饰一下,增添一些新的功能不就得了;如果使用了一段时间,发觉还是不行,还要添加功能,怎么办?继续装饰亚。下面该说,装饰类了,显然装饰类就是装饰原型类的,也就是添加功能的。
说说编码吧。实型类继承自原型类、实现里面的虚拟函数;装饰类也是继承自原型类,在重载原型类中的虚拟函数时装饰实型类,且装饰类一般而言,会比原型类和实型类多一个成员变量:类型为原型类的成员;至于这个成员变量是放在基类中还是放在派生类中就无所谓了,最好是放在基类中,可以省些代码,需要注意的是,如果放在基类中,需要将该变量声明为protected或是public;说了这么多,关键的地方其实才说了一点:就是添加成员变量。下面该说说关联实型类和装饰派生类了;通常有两种关联方式:一是采用构造函数,在构造函数中初始化类型为原型类的成员变量为实型类;二是采用方法,设置类型为原型类的成员变量为实型类;无论采用那种方式,目的只有一个:将原型类和装饰类关联;关联好两者以后,就可以开始添加功能了,功能添加在哪呢?自然是那些在原型类中声明,而在装饰类中重载的方法了,在具体一点,就是那个实型类要运行的功能不够的方法(自然该方法装饰类自然也会有)。在该方法中可以添加一些具体功能,怎么添加功能嘛,就不说了,写几行代码,或是写个函数然后调用该函数,都可以的呢。
当装饰好实型类后,执行装饰类的构造函数或是新添的方法将实型类和装饰类关联好以后,就可以执行装饰类的方法来代替实型类的方法了,通常实型类提供的功能也是要执行的,怎么办呢?也好办,在装饰类的方法中添加执行实型类的方法这样一条语句就可以了,怎么添加就不用我说了吧,so simple吧,不要忘记了装饰类有个成员变量就是实型类。
如果要添加多个功能,采用多个装饰,该怎么办?也容易啊,装饰嵌套嘛,不说了,也是很简单的事;记得看代理模式的时候,好像也用过代理嵌套的,嵌套还真是个好东东。