集合模式
集合模式基于集合,用于在不改变现有结构的情况下,由访问单一对象升级为可访问一组对象,特别适用于代码重构过程中。它一般与观察者模式结合使用。主要应用于重构过程中将混乱的代码或者用别的不适用的模式写的代码升级为观察者模式之后,解决大量繁索的调用细节,将关联关系由一对一升级为一对多。对于类似事件处理的流程最为适用。
考虑一个简单的日志处理系统。所有的业务逻辑类Logic都持有一个日志类Logger,Logger统一控制日志信息的去向,这样的系统已经非常灵活了,并且可以很容易地扩展Logger类来将日志存放到不同的介质中,甚至显示到不同的屏幕上。然而新的需求出现了,系统中产生的所有日志要同时出现在多个地方,比如在显示到屏幕的同时上传到网络上的其它设备中。
解决方案之一创建一个同时将日志放到两个不同地方的Logger,然后将此类型的对象交给Logic。然而,每出现一种不同的需求,或者任意两个需要显示日志的需求全在一起,就要产生一个新的Logger子类。如果目前有N种处理日志的方式,隐含的要新创建的Logger子类就有N*N个! 显然这种设计不太实用。
另一种方案是将Logic中所有写日志的地方都改成集合形式,这样灵活度和可扩展性都比较好。但面临的问题是要修改所有的Logic子类,并且还要在每一个地方处理诸如对象不为空等等的重复逻辑。工作量无疑非常大。
集合模式正适合这种情况。它首先创建一个带有AddLogger、RemoveLogger集合接口的Logger子类LoggerCollection,并且持有一个数组(或者其它容量类的对象),每个元素都保存一个Logger,然后这样实现所有Logger接口的方法:对Logger的任何一个调用,都将其转换为对集合中每一个Logger对象的同样一个调用。在使用时他分为两步,第一是创建LoggerCollection类的对象,然后为每个需要处理日志的需求创建一个对应的Logger子类对象,并将所有这些Logger子类对象通过AddLogger方法添加到LoggerCollection对象中。第二就是用LoggerCollection对象代替原来的Logger子类对象,将它们交给所有的Logic。
集合模式的优点是不改变现有的类,改动最小,但带来的灵活性却是最大的。很明显,以后可以很方便地将日志放到两个任意不同的地方,同时还不止两个,可以同时将日志放到任意N个不同的地方,而都无需任何修改,只需简单地创建每一个Logger,然后将它Add到LoggerCollection中。