设计模式之美:Composite(组合)
索引
意图
将对象组合成树形结构以表示 “部分-整体” 的层次结构。
Composite 使得用户对于单个对象和组合对象的使用具有一致性。
Compose objects into tree structures to represent part-whole hierarchies.
Composite lets clients treat individual objects and compositions of objects uniformly.
结构

典型的 Composite 对象结构:

参与者
Component
- 为组合中的对象声明接口。
- 在适当的情况下,实现所有类共有接口的缺省行为
- 声明一个接口用于访问和管理 Component 的子组件。
- 在递归结构中定义一个接口,用于访问一个父部件,并在合适的情况下实现它。
Leaf
- 在组合中表示叶节点对象,叶节点没有子节点。
- 在组合中定义图元对象的行为。
Composite
- 定义有子部件的那些部件的行为。
- 在 Composite 接口中实现与子部件有关的操作。
Client
- 通过 Component 接口操纵组合部件的对象。
适用性
在以下情况下可以使用 Composite 模式:
- 你想表示对象的 “部分-整体” 层次结构。
- 你希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。
缺点
- 与类层次结构设计原则冲突
Composite 模式的目的之一是使得用户不知道它们正在使用具体的 Leaf 和 Composite 类。
为达到这一目的,Component 需要为 Leaf 和 Composite 定义一些公共操作,并提供缺省的实现,而 Leaf 和 Composite 子类可以对它们进行重定义。
然而,这个目标会与类层次结构设计原则冲突,该原则规定:一个类只能定义那些对它的子类有意义的操作。
效果
- 定义了包含基本对象和组合对象的类层次结构。
- 简化客户代码。
- 使得更容易增加新类型的组件。
- 使你的设计变得更加一般化。
相关模式
- Command 模式描述了如何用一个 MacroCommand Composite 类组成一些 Command 对象,并对它们进行排序。
- 通常 “部件-父部件” 连接用于 Responsibility of Chain 模式。
- Decorator 模式经常与 Composite 模式一起使用。它们通常有一个公共的父类。
- Flyweight 让你共享组件,但不再能引用它们的父部件。
- Iterator 可以用来遍历 Composite。
- Visitor 将本来应该分布在 Composite 和 Leaf 类中的操作和行为局部化。
实现
实现方式(一):在 Component 中定义公共接口以保持透明性但损失安全性。
在 Component 中定义 Add 和 Remove 操作需要考虑安全性和透明性。
在类层次结构的根部定义子节点管理接口的方法具有良好的透明性,但是这一方法是以安全性为代价的,因为客户有可能会做一些无意义的事情,例如在 Leaf 中 Add 对象等。
在 Composite 类中定义管理子部件的方法具有良好的安全性,但是这又损失了透明性,因为 Leaf 和 Composite 具有不同的接口。
namespace CompositePattern.Implementation1
{
public abstract class Component
{
protected List<Component> _children = new List<Component>(); public abstract void Operation(); public virtual void Add(Component component)
{
_children.Add(component);
} public virtual void Remove(Component component)
{
_children.Remove(component);
} public virtual IEnumerable<Component> GetChildren()
{
return _children;
}
} public class Leaf : Component
{
public override void Operation()
{
// do something
} public override void Add(Component component)
{
throw new InvalidOperationException();
} public override void Remove(Component component)
{
throw new InvalidOperationException();
} public override IEnumerable<Component> GetChildren()
{
throw new InvalidOperationException();
}
} public class Composite : Component
{
public override void Operation()
{
foreach (var child in _children)
{
child.Operation();
}
// may do something
}
} public class Client
{
public void TestCase1()
{
Component component1 = new Leaf();
Component component2 = new Composite(); component2.Add(component1); component1.Operation();
component2.Operation();
}
}
}
《设计模式之美》为 Dennis Gao 发布于博客园的系列文章,任何未经作者本人同意的人为或爬虫转载均为耍流氓。
设计模式之美:Composite(组合)的更多相关文章
- 设计模式08: Composite 组合模式(结构型模式)
Composite 组合模式(结构型模式) 对象容器的问题在面向对象系统中,我们常会遇到一类具有“容器”特征的对象——即他们在充当对象的同时,又是其他对象的容器. public interface I ...
- 设计模式学习笔记——Composite 组合模式
用于描述无限层级的复杂对象,类似于描述资源管理器,抽象出每一个层级的共同特点(文件夹和文件,展开事件) 以前描述一个对象,是将整个对象的全部数据都描述清楚,而组合模式通过在对象中定义自己,描述自己的下 ...
- 设计模式(七)组合模式Composite(结构型)
设计模式(七)组合模式Composite(结构型) 1. 概述 在数据结构里面,树结构是很重要,我们可以把树的结构应用到设计模式里面. 例子1:就是多级树形菜单. 例子2:文件和文件夹目录 2.问题 ...
- Ruby设计模式透析之 —— 组合(Composite)
转载请注明出处:http://blog.csdn.net/sinyu890807/article/details/9153761 此为Java设计模式透析的拷贝版,专门为Ruby爱好者提供的,不熟悉R ...
- Java设计模式(8)组合模式(Composite模式)
Composite定义:将对象以树形结构组织起来,以达成“部分-整体” 的层次结构,使得客户端对单个对象和组合对象的使用具有一致性. Composite比较容易理解,想到Composite就应该想到树 ...
- 一天一个设计模式——Composite组合模式
一.模式说明 能够使容器与内容物具有一致性,创造出递归结构的模式就是Composite组合模式. 举个例子:计算机中的文件系统中有文件和文件夹的概念,我们知道,文件夹可以包含文件,也可以包含子文件夹, ...
- C++设计模式-Composite组合模式
Composite组合模式作用:将对象组合成树形结构以表示“部分-整体”的层次结构.Composite使得用户对单个对象和组合对象的使用具有一致性. UML图如下: 在Component中声明所有用来 ...
- 设计模式之美:Structural Patterns(结构型模式)
结构型模式涉及到如何组合类和对象以获得更大的结构. 结构型类模式采用继承机制来组合接口实现. 结构型对象模式不是对接口和实现进行组合,而是描述了如何对一些对象进行组合,从而实现新功能的一些方法. 因为 ...
- 设计模式之美:Prototype(原型)
索引 别名 意图 结构 参与者 适用性 缺点 效果 相关模式 命名约定 实现 实现方式(一):使用一个原型管理器. 实现方式(二):使用浅拷贝实现克隆(Clone)操作. 实现方式(三):使用深拷贝实 ...
随机推荐
- linux网络完全与防护
7.1 网络封包联机进入主机的流程 7.1.1 封包进入主机的流程 1.经过防火墙的分析 iptables 主要功能是封包过滤 主要分析TCP/IP的封包表头来进行过滤的机制 分析的是OSI的第二 ...
- RegExp 对象的三个方法:compile()、exec()、test()
这三个都是RegExp对象下的三个方法,使用方法是一致得. 使用方法:RegExpObject.方法() 方法解析:其实就是根据定义好的正则对象,调用对应的方法. 1.RegExpObject.com ...
- 循序渐进之Spring AOP(6) - 使用@Aspect注解
前面几节的示例看起来让人沮丧,要记忆如此多的接口.类和继承关系,做各种复杂的配置.好在这些只是一种相对过时的实现方式,现在只需要使用@Aspect注解及表达式就可以轻松的使用POJO来定义切面,设计精 ...
- 实现textarea限制输入字数(包含中文只能输入10个,全ASCII码能够输入20个)
document.getElementById("<%=textBox1.ClientID %>").value 实现textarea限制输入字数(包含中文只能输入10 ...
- CSS-页面布局
介绍 几个实现多栏布局的方法.主要介绍使用内部div来创建浮动的栏. 多栏布局有三种基本的实现方案:固定宽度.流动.弹性. 固定宽度布局的大小是随用户调整浏览器窗口大小而变化,一般是900至1100像 ...
- SQL镜像资料
使用数据库镜像端点证书 (Transact-SQL):https://msdn.microsoft.com/zh-cn/library/ms191477.aspx 允许数据库镜像端点将证书用于入站连接 ...
- decimalFormat("#","##0.00") java
importjava.text.DecimalFormat; publicclassTestNumberFormat{ publicstaticvoidmain(String[]args){ doub ...
- php插入排序
//php版插入排序 $arr=array('','5','3','7','6','4','8','2'); for($i=2;$i<count($arr);$i++) { ...
- c#开发Mongo笔记第八篇
到今天为止,Mongo开发的权限管理系统功能就做完了,剩下的就是完善构架,优化结构,只是现在c#操作Mongo的各种操作基本都掌握了 说到权限管理系统,其实再简单不过了,在关系型数据的是时代,我们通常 ...
- 触动——beyond歌词
1.一霎那,仿佛,若有所失的感觉 2.远路无法看的清 3.无悔这一生