如何让孩子爱上设计模式 ——9.组合模式(Composite Pattern)

标签: 设计模式初涉

描述性文字

组合模式,又称为 部分整体模式,把具有相似的一组对象
当做一个对象处理,用一种树状的结构来组合对象,再提供统一
的方法去访问相似的对象,以此忽略掉对象与对象容器间的差别。

举个简单例子,菜单和菜品,同样是以小猪的奶茶店为例子:

《如何让孩子爱上设计模式 ——9.组合模式(Composite Pattern)》

假设这两类需求如下:

菜单:菜单名,描述信息,添加,添加删除子菜单或菜品
递归打印出所有的子菜单与菜品!

菜品:菜名,描述信息,价格,打印信息

好的,先试试不用组合模式,要怎么写~

不使用组合模式写菜单

1.先把四个菜品都创建出来,一样的结构,名称,描述,价格,打印:

《如何让孩子爱上设计模式 ——9.组合模式(Composite Pattern)》
《如何让孩子爱上设计模式 ——9.组合模式(Composite Pattern)》
《如何让孩子爱上设计模式 ——9.组合模式(Composite Pattern)》
《如何让孩子爱上设计模式 ——9.组合模式(Composite Pattern)》

2.创建菜单类,名称,描述信息,可以增删菜品,子菜单,遍历打印:

《如何让孩子爱上设计模式 ——9.组合模式(Composite Pattern)》

3.客户端调用

《如何让孩子爱上设计模式 ——9.组合模式(Composite Pattern)》

4.打印结果

《如何让孩子爱上设计模式 ——9.组合模式(Composite Pattern)》

好的,没毛病,但是问题来了,如果增删菜品或者子菜单,原有代码
都要进行相应的修改,扩展性差,如果引入组合模式会又会如何?

使用组合模式写菜单

1.抽象出即可代表菜单又可代表菜品的类,这里我们只需要一个
add,get,getString三个抽象方法,让菜单和菜品去继承,菜品
只需完成getString方法重写,菜单需要重写add和get方法。

《如何让孩子爱上设计模式 ——9.组合模式(Composite Pattern)》

2.四个照葫芦画瓢的菜品类

《如何让孩子爱上设计模式 ——9.组合模式(Composite Pattern)》
《如何让孩子爱上设计模式 ——9.组合模式(Composite Pattern)》
《如何让孩子爱上设计模式 ——9.组合模式(Composite Pattern)》
《如何让孩子爱上设计模式 ——9.组合模式(Composite Pattern)》

3.菜单类

《如何让孩子爱上设计模式 ——9.组合模式(Composite Pattern)》

4.客户端调用

《如何让孩子爱上设计模式 ——9.组合模式(Composite Pattern)》

5.打印结果

《如何让孩子爱上设计模式 ——9.组合模式(Composite Pattern)》

使用了合并模式,如果此时我们要新增一个菜品,只需继承抽象构建类,
无需改动其他类,显得更加方便。

概念与总结

三个角色

上面也说了合并模式是用一种树状的结构来组合对象,三个名词
根节点枝结点叶子结点,类比上面那个菜单的图,
根节点是菜单,枝结点是饮料菜单和小吃菜单,
叶子结点是奶茶,果汁,手抓饼和鱼蛋!

  • Component抽象组件,为组合中的对象声明接口,让客户端
    可以通过这个接口来访问和管理整个对象结构,可以在里面为定义的
    功能提供缺省的实现,比如上面的AbstractMenu类。
  • Composite容器组件,继承抽象组件,实现抽象组件中与
    叶子组件相关的操作,比如上面的Menu类重写了get,set方法。
  • Leaf叶子组件,定义和实现叶子对象的行为,不再包含其它
    的子节点对象,比如上面的MilkTea,Juice,HandCake,FishBall。

UML类图

《如何让孩子爱上设计模式 ——9.组合模式(Composite Pattern)》

使用情景

  • 如果你想表示对象的部分-整体层次结构,可以选用组合模式,
    把整体和部分的操作统一起来,使得层次结构实现更简单,从外
    部来使用这个层次结构也简单;
  • 如果你希望统一的使用组合结构中的所有对象,可以选用组合
    模式,这正是组合模式提供的主要功能;

优缺点

优点

让客户端更加简单,客户端不需要再操心面对的是组合对象还是叶节点
对象,所以不需要写一大堆if语句来保证他们对正确的对象调用了正确
的方法。通常,他们只需要对整个结构调用一个方法并执行操作就可以了。

缺点

容易增加新的组件也会带来一些问题,比如很难限制组合中的组件类型。
这在需要检测组件类型的时候,使得我们不能依靠编译期的类型约束来
完成,必须在运行期间动态检测。

本节代码

https://github.com/coder-pig/DesignPatternsExample/tree/master/8.Composite%20Pattern

    原文作者:架构
    原文地址: https://www.jianshu.com/p/4e9a951415d2
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞