组合模式:是一种结构型设计模式,组合多个对象形成树形结构以表示“部分-整体”的结构层次。组合模式对单个对象(即叶子对象)和组合对象(即容器对象)的使用具有一致性
组合模式优点:
- 可以清楚地定义分层次的复杂对象,表示对象的全部或部分层次,让客户端忽略了层次的差异,方便对整个层次结构进行控制
- 客户端可以一致地使用一个组合结构或其中单个对象,不必关心处理的是单个对象还是整个组合结构,简化了客户端代码
- 增加新的容器构件和叶子构件都很方便,符合开闭原则
- 为树形结构的面向对象实现提供了一种灵活的解决方案
组合模式缺点:在增加新构件时很难对容器中的构件类型进行限制
组合模式适用场景:
- 在具有整体和部分的层次结构中,希望通过一种方式忽略整体与部分的差异,客户端可以一致地对待它们
- 在一个使用面向对象语言开发的系统中需要处理一个树形结构
- 在一个系统中能够分离出叶子对象和容器对象,而且它们的类型不固定,需要增加一些新的类型
组合模式包含以下角色:
Component(抽象构件):定义组合中对象的通用接口,可以是抽象类或接口,声明了管理子对象的方法和属性。
Leaf(叶子构件):表示组合中的叶子节点对象,不具有子对象。
Composite(容器构件):表示组合中的容器节点对象,可以包含子对象,实现了管理子对象的方法和属性。
透明组合模式:
- 抽象构件Component中声明了所有用于管理成员对象的方法,包括add()、remove(),以及getChild()等方法
- 在客户端看来,叶子对象与容器对象所提供的方法是一致的,客户端可以一致地对待所有的对象
- 缺点是不够安全,因为叶子对象和容器对象在本质上是有区别的
安全组合模式:
- 抽象构件Component中没有声明任何用于管理成员对象的方法,而是在Composite类中声明并实现这些方法
- 对于叶子对象,客户端不可能调用到这些方法
- 缺点是不够透明,客户端不能完全针对抽象编程,必须有区别地对待叶子构件和容器构件
透明组合模式实现水果盘例子,其中水果盘包含了水果和子盘:
首先定义一个抽象类FruitPlateComponent
,作为水果盘和水果的抽象类,其中包含了添加、删除和显示的方法:
1 | public abstract class FruitPlateComponent { |
然后定义一个具体水果类Fruit
,继承自FruitPlateComponent
,实现添加、删除和显示的方法:
1 | public class Fruit extends FruitPlateComponent { |
再定义一个具体水果盘类FruitPlate
,继承自FruitPlateComponent
,实现添加、删除和显示的方法:
1 | public class FruitPlate extends FruitPlateComponent { |
最后,我们可以使用组合模式来创建一个水果盘,其中包含了苹果和橘子两种水果,以及一个子盘,子盘里面包含了香蕉和草莓两种水果:
1 | public class Client { |
输出结果如下:
1 | 水果盘:水果盘 |
- 本文作者: zzr
- 本文链接: http://zzruei.github.io/2023/044380da32.html
- 版权声明: 本博客所有文章除特别声明外,均采用 Apache License 2.0 许可协议。转载请注明出处!