索引

意图

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

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. linux shell学习笔记

    一  变量 声明变量: my_var='ddd'使用变量: ${my_var}设置为只读变量: readonly my_var删除变量: unset my_var 注意只读变量不能被删除 变量类型:( ...

  2. 为什么 1KB = 1024Byte???群里讨论。

  3. Django web 基础

    一.Django概述 Django大而全; 创建Django工程:django-admin startproject sitename 创建django之后生成的目录结构如下: Project Pro ...

  4. 易语言软件加VMProtect壳的正确方法

    VMP是一款很强大的加密壳,代码虚拟化技术可以很好的保护程序不被恶意修改破J但是很多人不知道怎么给自己的程序加壳,今天给大家晋级下加壳的正确方法 相信很多新手都以为只要把软件直接拖到VMP里重新编译一 ...

  5. java.util.Date和java.sql.Date的区别和相互转化(转)

    java.util.Date是在除了SQL语句的情况下面使用的.java.sql.Date是针对SQL语句使用的,它只包含日期而没有时间部分它们都有getTime方法返回毫秒数,自然就可以直接构建.  ...

  6. Java NIO教程 MappedByteBuffer

    之前跟大家说过,要讲MappedByteBuffer,现在我来履行承诺了. 首先从大体上讲一下MappedByteBuffer究竟是什么.从继承结构上来讲,MappedByteBuffer继承自Byt ...

  7. php 处理别人直接丢过来的json字符串

    如果 json校验成功  出现莫名其妙的不能decode 就看下转义 最好是直接使用php定界符eof来赋值字符串

  8. linux shell 去重 uniq和sort的区别

    sort -u 和 uniq都能起到删除重复信息的功能,那么他们的区别究竟在哪呢?$ cat test              jasonjasonjasonfffffjason 下面分别执行三个命 ...

  9. a==null和a.equals("null")的区别

    equals 是值比较,==是比较内存 A==B,比较句柄,就是比较变量A,B的地址存放的东西,比如int A=0;String B="bbbb";那么变量A的地址方的就是0,B的 ...

  10. System.IO.Directory类

    1.参考的博客:System.IO.Directory类和System.DirectoryInfo类(http://blog.sina.com.cn/s/blog_614f473101017du4.h ...