标签: 设计模式初涉
描述性文字
组合模式,又称为 部分整体模式,把具有相似的一组对象
当做一个对象处理,用一种树状的结构来组合对象,再提供统一
的方法去访问相似的对象,以此忽略掉对象与对象容器间的差别。
举个简单例子,菜单和菜品,同样是以小猪的奶茶店为例子:
假设这两类需求如下:
菜单:菜单名,描述信息,添加,添加删除子菜单或菜品
递归打印出所有的子菜单与菜品!
菜品:菜名,描述信息,价格,打印信息
好的,先试试不用组合模式,要怎么写~
不使用组合模式写菜单
1.先把四个菜品都创建出来,一样的结构,名称,描述,价格,打印:
2.创建菜单类,名称,描述信息,可以增删菜品,子菜单,遍历打印:
3.客户端调用
4.打印结果
好的,没毛病,但是问题来了,如果增删菜品或者子菜单,原有代码
都要进行相应的修改,扩展性差,如果引入组合模式会又会如何?
使用组合模式写菜单
1.抽象出即可代表菜单又可代表菜品的类,这里我们只需要一个
add,get,getString三个抽象方法,让菜单和菜品去继承,菜品
只需完成getString方法重写,菜单需要重写add和get方法。
2.四个照葫芦画瓢的菜品类
3.菜单类
4.客户端调用
5.打印结果
使用了合并模式,如果此时我们要新增一个菜品,只需继承抽象构建类,
无需改动其他类,显得更加方便。
概念与总结
三个角色
上面也说了合并模式是用一种树状的结构来组合对象,三个名词
根节点,枝结点,叶子结点,类比上面那个菜单的图,
根节点是菜单,枝结点是饮料菜单和小吃菜单,
叶子结点是奶茶,果汁,手抓饼和鱼蛋!
-
Component:抽象组件,为组合中的对象声明接口,让客户端
可以通过这个接口来访问和管理整个对象结构,可以在里面为定义的
功能提供缺省的实现,比如上面的AbstractMenu类。 -
Composite:容器组件,继承抽象组件,实现抽象组件中与
叶子组件相关的操作,比如上面的Menu类重写了get,set方法。 -
Leaf:叶子组件,定义和实现叶子对象的行为,不再包含其它
的子节点对象,比如上面的MilkTea,Juice,HandCake,FishBall。
UML类图:
使用情景
- 如果你想表示对象的部分-整体层次结构,可以选用组合模式,
把整体和部分的操作统一起来,使得层次结构实现更简单,从外
部来使用这个层次结构也简单; - 如果你希望统一的使用组合结构中的所有对象,可以选用组合
模式,这正是组合模式提供的主要功能;
优缺点
优点:
让客户端更加简单,客户端不需要再操心面对的是组合对象还是叶节点
对象,所以不需要写一大堆if语句来保证他们对正确的对象调用了正确
的方法。通常,他们只需要对整个结构调用一个方法并执行操作就可以了。
缺点:
容易增加新的组件也会带来一些问题,比如很难限制组合中的组件类型。
这在需要检测组件类型的时候,使得我们不能依靠编译期的类型约束来
完成,必须在运行期间动态检测。
本节代码:
https://github.com/coder-pig/DesignPatternsExample/tree/master/8.Composite%20Pattern