设计模式之组合模式
设想一个场景,你老爸让你去拿碗盛饭,碗肯定有大有小,家里人多,你得抱一摞碗过来,小碗放在大碗里,大腕放在更大的碗里(当然, 如果你喜欢看着碗做自由落体运动,可以倒过来放),碗拿来了,你老爸命令你盛饭,你肯定一个碗一个碗开始盛饭直到最后一个!你不会傻到在盛饭之前,让你老爸告诉你,你手里的碗里面是否还有小碗,因为这样问,会招来你老爸的一阵训斥!很简单,你老爸得看报纸,他没空去理会你这些琐事!判断碗里是否还套着其他小碗,他认为去你应该完成的事情! 好,说到这里可以看到组合模式的影子了,组合模式就是解决客户端程序对容器对象的内部结构过度依赖的情况! 上面说的那个例子,其中碗就是一个容器对象,为什么称为容器对象了,因为碗本身也是个对象,继承了碗的接口,可以盛东西,同时又是一个容器,可以放比他小的碗,老爸这个角色就相当于组合模式中的客户端,他要碗盛饭,只想要结果,不需要他在自己去看着碗是否套着小碗,他不关心也不需要去如何判断! 那判断大腕是否包括小碗,并且让小碗先去盛饭,再去盛饭的操作是谁负责了? 在组合模式中,这些功能都有容器对象自己来完成,不需要客户端去使用递归方法挨个查询碗是否容器对象还是叶子对象(什么是叶子对象,还是用碗作比喻,就是最小的一个碗,里面不能再放其他小碗了), 容器对象和叶子对象都继承同一接口,他们对于客户端都是透明的,客户端根本不需要区别他们,甚至不知道有容器存在,客户端只需了解如何通过这些对象来实现它们想要的功能! 说到容器,肯定得有方法来添加和删除对象,关于这些方法放在共同的接口里还是放在容器对象类里,会有不同的结果! 关于安全性和透明性不可两全性的结果,如果放在接口中,则有安全性的问题,因为在叶子对象中,没有再包括对象,但还要实现添加删除对象和获取对象的方法,在客户端使用中容易导致出错!但是却是完全透明的,因为接口一致! 但是如果放在容器对象中,则不是完全透明,客户端需要知道只在容器对象中存在这些方法!在叶子对象中没有这些方法,则是安全的! 以上就是关于组合模式的一个解决方案,它是比较容易理解的!目的明显,就是降低客户端和容器对象内部结构的偶合性! |