索引

意图

将对象组合成树形结构以表示 “部分-整体” 的层次结构。

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(组合)的更多相关文章

  1. 设计模式08: Composite 组合模式(结构型模式)

    Composite 组合模式(结构型模式) 对象容器的问题在面向对象系统中,我们常会遇到一类具有“容器”特征的对象——即他们在充当对象的同时,又是其他对象的容器. public interface I ...

  2. 设计模式学习笔记——Composite 组合模式

    用于描述无限层级的复杂对象,类似于描述资源管理器,抽象出每一个层级的共同特点(文件夹和文件,展开事件) 以前描述一个对象,是将整个对象的全部数据都描述清楚,而组合模式通过在对象中定义自己,描述自己的下 ...

  3. 设计模式(七)组合模式Composite(结构型)

    设计模式(七)组合模式Composite(结构型) 1. 概述 在数据结构里面,树结构是很重要,我们可以把树的结构应用到设计模式里面. 例子1:就是多级树形菜单. 例子2:文件和文件夹目录 2.问题 ...

  4. Ruby设计模式透析之 —— 组合(Composite)

    转载请注明出处:http://blog.csdn.net/sinyu890807/article/details/9153761 此为Java设计模式透析的拷贝版,专门为Ruby爱好者提供的,不熟悉R ...

  5. Java设计模式(8)组合模式(Composite模式)

    Composite定义:将对象以树形结构组织起来,以达成“部分-整体” 的层次结构,使得客户端对单个对象和组合对象的使用具有一致性. Composite比较容易理解,想到Composite就应该想到树 ...

  6. 一天一个设计模式——Composite组合模式

    一.模式说明 能够使容器与内容物具有一致性,创造出递归结构的模式就是Composite组合模式. 举个例子:计算机中的文件系统中有文件和文件夹的概念,我们知道,文件夹可以包含文件,也可以包含子文件夹, ...

  7. C++设计模式-Composite组合模式

    Composite组合模式作用:将对象组合成树形结构以表示“部分-整体”的层次结构.Composite使得用户对单个对象和组合对象的使用具有一致性. UML图如下: 在Component中声明所有用来 ...

  8. 设计模式之美:Structural Patterns(结构型模式)

    结构型模式涉及到如何组合类和对象以获得更大的结构. 结构型类模式采用继承机制来组合接口实现. 结构型对象模式不是对接口和实现进行组合,而是描述了如何对一些对象进行组合,从而实现新功能的一些方法. 因为 ...

  9. 设计模式之美:Prototype(原型)

    索引 别名 意图 结构 参与者 适用性 缺点 效果 相关模式 命名约定 实现 实现方式(一):使用一个原型管理器. 实现方式(二):使用浅拷贝实现克隆(Clone)操作. 实现方式(三):使用深拷贝实 ...

随机推荐

  1. yum 介绍

    yum是一个用于管理rpm包的后台程序,用python写成,可以非常方便的解决rpm的依赖关系.在建立好yum服务器后,yum客户端可以通过 http.ftp方式获得软件包,并使用方便的命令直接管理. ...

  2. Python2和Python3在windows下共存

    Python2.7 和 Python3不兼容,两种环境可能都会用到.ubuntu14.04中已经默认安装了这两个版本,在shell中输入python会自动进入Python2.7的交互环境,输入Pyth ...

  3. 2016年 Delphi Roadmap

    2016年delphi Roadmap 发布,这也是新公司的第一次发布路线图. 虽然稍微晚点( 原来说是1月份发布路线图),至少比过去积极点.喧嚣多年的靴子终于落地. Linux 的支持终于正式公布. ...

  4. KMP算法简明扼要的理解

    KMP算法也算是相当经典,但是对于初学者来说确实有点绕,大学时候弄明白过后来几年不看又忘记了,然后再弄明白过了两年又忘记了,好在之前理解到了关键点,看了一遍马上又能理解上来.关于这个算法的详解网上文章 ...

  5. flex4.0密钥及破解方式

    输入下面的序列号: 1424-4507-0757-7016-8907-6937 1424-4785-4428-8084-6314-8733 1424-4794-9281-8063-2338-9079 ...

  6. oracle SQL查询中间若干条记录

    方法一:利用rownum和差集函数minus select * from ( select * from emp order by sal) where rownum<13 minus sele ...

  7. nullcon HackIM 2016 -- Programming Question 2

    Your simple good Deeds can save you but your GREED can kill you. This has happened before. This gree ...

  8. pip使用

    安装指定版本的插件: pip install -v matplotlib==1.5.1 #安装matplotlib version 1.5.1

  9. JSP页面数据展示:分组数据展示

    一.描述: 页面上要展示的数据只要写好sql从数据库查出来即可,但是展示有时候不是太好处理.比如工作中遇到的这种情况:有一个问题处理的流程,其中需要选择下一处理人,这些处理人要以部门的形式分组展示,实 ...

  10. 什么是侧翼区(flanking region)和侧翼区单核苷酸多态性(Flanking SNPs)

    侧翼区(flanking region) 根据维基定义:The 5' flanking region is a region of DNA that is adjacent to the 5' end ...