装饰模式用于处理软件组件设計中的责任划分不清晰,导致子类通过继承得到大量的冗余重复代码代码的急剧膨胀问题。装饰模式关键在于划清责任
考虑设计一个IO庫、相关流操作。其中有文件流网络流、内存流等,操作有对流的加密缓存等。
我们可以发现加密、缓冲操作是一样的,只是加密、缓冲的对象不同但加密的对象都继承自一个共同的抽象基类。代码大量重复可以进行代码重构。
各类扩展操作从继承各类流改为包含各类流的基类指针Stream*。使用组合替代继承将原先写死的FileStream::Read等改为基类指针调用Stream->Read。
Stream实质是一个多态指针当变量的声明都为某个类型的子類时,可以直接提升声明为该变量类型
编译时复用,将变化需求提升至运行时
同时为了Read等接口函数的虚性质,维护接口的规范需要繼承Stream。
最后使用时从原先的编译时装配,改为运行时装配
编译时,不存在流的加密缓存等类运行时通过多态指针将各种操作组合起來,来满足未来的需求
但到此为止,还不是最优的设计根据马丁福勒的重构理论,如果某个类的多个子类都有同样的字段应该将字段上提。
字段上提可以提升至基类也可以提升至中间类。
DecoratorStream类是中间类包含重复字段,扩展继承该类同时调用DecoratorStream里的构造器构造(基类构慥器)。
可以从继承图谱看出类的规模显著的减少,将大量的流扩展操作与各类流分离避免了对继承的不良使用,提升代码的复用性
裝饰模式的要点在于,组合基类并继承基类从经验推断,如果某类继承并组合某个基类99%的可能是使用了装饰模式。
装饰模式是为了解決因为继承的误用随着子类的增多,在静态特质下各种子类的组合会导致更多的子类急剧的膨胀。通过动态的给对象增加格外的职责来消除重复代码,减少子类个数