组合模式
Posted 花火灬流年
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了组合模式相关的知识,希望对你有一定的参考价值。
1、定义
将对象组合成树形结构以表示“部分——整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
类比理解:复制文件时,可以一个一个单独复制,也可以一次将整个文件夹复制了;再比如文本编辑,可以给单个字进行加粗、变色、改字体,也可以对整段文字进行同样的操作。这个问题实际上就是要求“整体与部分可以被一致对待”。
2、理论类比(Component-细胞,Leaf-叶子,Composite-树枝)
- Component-细胞
- 抽象基类,定义所有组件需要的共有接口,在适当的情况下实现所有类共有接口的默认行为;所有的叶子对象和树枝对象都继承细胞(即由细胞组成)
- Leaf-叶子
- 叶节点:其上不能再有分支,即叶子没有子节点
- 因为叶子没有子节点,所以它的Add和Remove方法没有意义;但是仍然要求叶子对象也继承细胞,这样就可以消除叶子和树枝在抽象层次的区别,使他们具备完全一致的接口,方便操作组合模式下的任意对象
- Composite-树枝
- 树枝:定义有枝节点的行为,用来存储子部件;在内部建立一个对象集合,用来存储其下属的子节点
- 可以有子节点(叶子或者树枝),在细胞接口中实现与子部件有关的操作;
- 客户端:通过Component-细胞的接口来操作组合部件的对象,包括建立、移除节点,执行部件的自有方法
- 注:树枝和叶子属于基本对象,这些基本对象可以被组合成更复杂的组合对象,这样不断递归下去,客户端的代码中,任何用到基本对象的地方就可以使用组合对象了;用户就不需要再去关心到底是处理一个叶子对象还是一个组合对象,避免了为组合对象专门写一些选择判断语句。一句话:组合模式可以让用户一致的使用单个对象和组合结构。
3、关于“透明方式”与“安全方式”
- 来源:上面叶子节点中,由于其不能再有子节点,因此叶子对象的Add和Remove方法是没有意义的,而树枝可以有子节点(叶子或树枝);但是在一般情况下依然要求叶子和树枝都要继承自Component-细胞
- 解释:透明方式与安全方式
- 透明方式:在基类中声明所有用来管理子对象的方法,这样继承该基类的所有子类都具备了相同的接口;这样做就使得叶子和树枝对于外界没有区别,但是也有问题,即叶子对象本身不具备子节点,所以实现Add和Remove方法是没有意义的;
- 安全方式:在基类中不去声明Add和Remove方法,这时叶子对象就不需要实现这些接口,而在树枝对象中声明用来管理子节点的方法,这样做就避免了‘透明方式’的问题;但是由于叶子和树枝具有不同的接口,客户端的调用就需要单独判断,又带来了不便。
- 两者各有好处,需要在使用时进行具体判断。
4、使用时机
当你发现需求中体现部分与整体的层次结构时,以及你希望用户可以忽略组合对象与单个对象的不同,统一的使用所有组合结构中的所有对象时,就应该考虑使用组合模式。
但是也并不是所有的树枝都是需要部分和整体共用的,可能只是树枝上的某两个叶子在整个树结构中是共用的。以公司结构为例,总公司下辖地区公司,地区公司下辖每个省的办事处;那么在这整个结构中人力资源部和财务部就是需要共用的例子,而树枝(比如华东分公司,南京办事处)除了这些共用的叶子外,也有自己独有的部门,这是就需要使用具体的树枝对象来调用其独有的部门。组合模式所描述的就是说,当操作整个树结构共有的叶子或树枝对象的某些方法时,组合模式可以达到忽略该方法到底是属于总公司还是分公司还是最底层的办事处。
以上是关于组合模式的主要内容,如果未能解决你的问题,请参考以下文章