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

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

标签: 设计模式初涉


描述性文字

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

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

假设这两类需求如下:

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

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

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


不使用组合模式写菜单

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


  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值