设计模式系列11-组合模式解析

COMPOSITE

今天为大家带来死磕设计模式系列的第11个模式,属于结构型模式的–组合模式

带着问题出发

  1. 什么是组合模式?
  2. 组合模式解决了什么问题?
  3. 适用场景是什么?

定义

将对象组合成树形结构以表示“部分-整体”的层次结构。Composite 使得用户对单个对象和组合对象的使用具有一致性。

如果业务中需要定义复杂的数据结构,可以用树形嵌套来表示,那么组合模式就有用武之地了。

动机

比如在绘图编辑器中,用户可以使用简单的组件创建复杂的图表。用户可以组合多个简单组件以形成一些较大的组件,这些组件又可以组合成更大的组件。

然后这种方法存在一个问题:使用这些类的代码必须区别对待这些不同的组件,而实际上大多数用户认为他们是一样的。 Composite 模式描述了如何使用递归组合,使得用户不必对这些类进行区别。

类图

在这里插入图片描述

Composite 模式的关键是一个抽象类(这里接口也属于抽象类范围,自由使用),它既可以表示叶节点,也可以表示容器,即图中的 Component,它声明了对象相关的操作。

适用性

以下情况适用 Composite 模式:

  1. 组合模式为你提供了两种共享公共接口的基本元素类型: 简单叶节点和复杂容器。 容器中可以包含叶节点和其他容器。 这使得你可以构建树状嵌套递归对象结构。
  2. 你希望用户忽略组合对象与单个对象之间的不同,用户将统一地使用组合结构中的所有对象。

协作

用户使用 Component 类接口与组合结构中的对象进行交互。如果接收者是一个叶节点,则直接处理请求。如果接收者是 Composite ,它通常将请求发送给它的子部件,在转发请求之前或之后执行一些辅助操作。

解决了什么问题

  1. 定义了包含基本对象和组合对象和类层次结构。 基本对象可以被组合成更复杂的组合对象,而这个组合又可以被组合,这样不断的递归下去。客户代码中,任何用到基本对象的地方都可以使用组合对象。
  2. 简化客户代码。 客户可以一致性的使用组合和单个对象,通常用户不知道也不关心处理的是一个叶节点还是一个组合容器。
  3. 使得更容易增加新类型的组件。 新定义的 Composite 或者 Leaf 子类自动与已有结构和客户代码一起工作。

具体实现

在这里插入图片描述

这个实现有一个点是需要注意的,就是我们的 Composite 中声明了对子部件管理的操作,add()、remove() ,问题在于:这些操作应该定义在哪一个类层次中。我们是应该在 Component(图中Graph) 中声明使其对 Leaf 类有意义呢?还是只应该在 Composite(图中CompoundGraphic) 和它的子类中声明并定义这些操作呢?

这需要在安全性和透明性之间做出权衡。

  • 在类层次结构根部定义可以具有良好的透明性,因为你可以一致地使用所有组件,但是损失了安全性,因为客户有可能做一些无意义的操作,比如 Leaf 中增加和删除对象。
  • 在 Composite 类中定义管理子部件的方法具有良好的安全性,因为像Java这种静态语言中,在编译时就可以发现,但是又损失了透明性,因为Leaf和Composite具有不同的方法。

一般在 组合模式 中,相对于安全性我们更强调 透明性


看到这里的朋友恭喜你,在通往模式大师的路上又进了一步,技能库中收入了我们的组合模式,希望你可以多思考去实践掌握。

本文全!fighting

猜你喜欢

转载自blog.csdn.net/taurus_7c/article/details/107870010
今日推荐