合成模式:有时又叫做部分-整体模式(Part-Whole)。合成模式将对象组织到树结构中,可以用来描述整体与部分的关系。合成模式可以使客户端将单纯元素与复合元素同等看待。

合成模式分为安全式和透明式

安全式合成模式类图:

抽象构件(Component)角色:这是一个抽象角色,它给参加组合的对象定义出公共的接口及其默认行为,可以用来管理所有的子对象。在安全式的合成模式里,构件角色并不是定义出管理子对象的方法,这一定义由树枝构件对象给出。

树叶构件(Leaf)角色:树叶对象是没有下级子对象的对 象,定义出参加组合的原始对象的行为。

树枝构件(Composite)角色:代表参加组合的有下级子对象的对象。树枝对象给出所有的管理子对象的方法,如 add()、remove()、getChild()等。

示例代码:

  1. class Program
  2. {
  3. static void Main(string[] args)
  4. {
  5. Composite root = new Composite("root");
  6. root.Add(new Leaf("Leaf A"));
  7. root.Add(new Leaf("Leaf B"));
  8.  
  9. Composite comp = new Composite("Composite X");
  10. comp.Add(new Leaf("Leaf XA"));
  11. comp.Add(new Leaf("Leaf XB"));
  12. root.Add(comp);
  13. root.Add(new Leaf("Leaf C"));
  14.  
  15. Leaf Leaf1 = new Leaf("Leaf D");
  16. root.Add(Leaf1);
  17. root.Remove(Leaf1);
  18. root.Display();
  19. Console.ReadKey();
  20. }
  21. }
  22.  
  23. public abstract class Component
  24. {
  25. protected string name;
  26. public Component(string name)
  27. {
  28. this.name = name;
  29. }
  30.  
  31. public abstract void Display(int depth);
  32. }
  33.  
  34. public class Composite : Component
  35. {
  36. private ArrayList children = new ArrayList();
  37. public Composite(string name) : base(name) { }
  38.  
  39. public void Add(Component component)
  40. {
  41. children.Add(component);
  42. }
  43.  
  44. public void Remove(Component component)
  45. {
  46. children.Remove(component);
  47. }
  48.  
  49. public override void Display(int depth)
  50. {
  51. Console.WriteLine(new string('-', depth) + name);
  52. foreach (Component item in children)
  53. {
  54. item.Display(depth + );
  55. }
  56. }
  57. }
  58.  
  59. class Leaf : Component
  60. {
  61. public Leaf(string name) : base(name) { }
  62.  
  63. public override void Display(int depth)
  64. {
  65. Console.WriteLine(new String('-', depth) + name);
  66. }
  67. }

运行结果:

透明式合成模式类图:

透明式的合成模式要求所有的具体构件类,不论树枝构件还是树叶构件,均符合一个固定的接口。

抽象构件(Component)角色:这是一个抽象角色,它给参加组合的对象规定一个接口,规范共有的接口及默认行为。

树叶构件(Leaf)角色:代表参加组合的树叶对象,定义 出参加组合的原始对象的行为。树叶类会给出 add()、 remove()以及 getChild()之类的用来管理子类对 对象的方法的平庸实现。

树枝构件(Composite)角色:代表参加组合的有子对 象的对象,定义出这样的对象的行为。

示例代码:

  1. class CompositePartten2
  2. {
  3. public static void Main(string[] args)
  4. {
  5. Composite root = new Composite("rood");
  6. root.Add(new Leaf("Leaf A"));
  7. root.Add(new Leaf("Leaf b"));
  8.  
  9. Composite comp = new Composite("Composite X");
  10. comp.Add(new Leaf("Leaf XA"));
  11. comp.Add(new Leaf("Leaf XB"));
  12.  
  13. root.Add(comp);
  14.  
  15. root.Add(new Leaf("Leaf C"));
  16. // Add and remove a leaf
  17. Leaf l = new Leaf("Leaf D");
  18. root.Add(l);
  19. root.Remove(l);
  20. // Recursively display nodes
  21. root.Display();
  22.  
  23. Console.ReadKey();
  24. }
  25. }
  26.  
  27. abstract class Component
  28. {
  29. protected string name;
  30. public Component(string name)
  31. {
  32. this.name = name;
  33. }
  34.  
  35. public abstract void Add(Component c);
  36. public abstract void Remove(Component c);
  37. public abstract void Display(int c);
  38.  
  39. }
  40.  
  41. class Composite : Component
  42. {
  43. private ArrayList children = new ArrayList();
  44.  
  45. public Composite(string name) : base(name) { }
  46.  
  47. public override void Add(Component c)
  48. {
  49. children.Add(c);
  50. }
  51.  
  52. public override void Remove(Component c)
  53. {
  54. children.Remove(c);
  55. }
  56.  
  57. public override void Display(int depth)
  58. {
  59. Console.WriteLine(new String('-', depth) + name);
  60. foreach (Component item in children)
  61. {
  62. item.Display(depth + );
  63. }
  64. }
  65. }
  66.  
  67. class Leaf : Component
  68. {
  69. public Leaf(string name) : base(name) { }
  70.  
  71. public override void Add(Component c)
  72. {
  73. Console.WriteLine("Connot add to leaf");
  74. }
  75.  
  76. public override void Remove(Component c)
  77. {
  78. Console.WriteLine("Connot remove from a leaf");
  79. }
  80.  
  81. public override void Display(int c)
  82. {
  83. Console.WriteLine(new String('-', c) + name);
  84. }
  85. }

运行结果:

使用时注意问题:

1、明显的给出父对象的引用。在子对象里面给出父对象的引用,可以很容易的遍历所有父对象。有了这个引用,可以方便的应用责任链模式。

2、在通常的系统里,可以使用享元模式实现构件的共享,但是由于合成模式的对象经常要有对父对象的引用,因此共享不容易实现。

3、有时候系统需要遍历一个树枝结构的子构件很多次,这 时候 可以考虑把遍历子构件的结果暂时存储在父构件里面作为缓存。

4、关于使用什么数据类型来存储子对象的问题,在示意性的 代码中使用了 ArrayList,在实际系统中可以使用其它聚 集或数组等。

5、客户端尽量不要直接调用树叶类中的方法,而是借助其父 类(Component)的多态性完成调用,这样可以增加代 码的复用性

九、 合成(Composite)模式 --结构模式(Structural Pattern)的更多相关文章

  1. 十二、享元(Flyweight)模式--结构模式(Structural Pattern)

    Flyweight在拳击比赛中指最轻量级,即"蝇量级",有些作者翻译为"羽量级".这里使用"享元 模式"更能反映模式的用意. 享元模式以共享 ...

  2. 七、适配器(Adapter)模式--结构模式(Structural Pattern)

    适配器模式:把一个类的接口变换成客户端所期待的另一种接口,从而使原本接口不匹配而无法在一起工作的两个类能够在一起工作. 类的 Adapter模式的结构: 类适配器类图: 由图中可以看出,Adaptee ...

  3. 十一、外观(Facade)模式--结构模式(Structural Pattern)

    外部与一个子系统的通信必须通过一个统一的门面(Facade)对象进行,这就是门面模式.门面模式要求一个子系统的外部与其内部的通信必须通过一个统一的门面(Facade)对象进行. 门面模式提供一个高层次 ...

  4. 十、装饰(Decorator)模式 --结构模式(Structural Pattern)

    装饰(Decorator)模式又名包装(Wrapper)模式[GOF95].装饰模式以对客户端透明的方 式扩展对象的功能,是继承关系的一个替代方案. 装饰模式类图: 类图说明: 抽象构件(Compon ...

  5. 八、桥接模式--结构模式(Structural Pattern)

    桥梁模式:将抽象化(Abstraction)与实现化 (Implementation)脱耦,使得二者可以独立地变化. 桥梁模式类图: 抽象化(Abstraction)角色:抽象化给出的定义,并保存 一 ...

  6. 结构型模式概述(Structural Pattern)

    结构型模式可以描述两种不同的东西:类与类的实例.结构型模式可以分为类结构型模式和对象结构型模式. 类结构型模式关心类的组合,可以由多个类组合成一个更大的系统,在类结构型模式中只存在继承关系和实现关系: ...

  7. 设计模式のCompositePattern(组合模式)----结构模式

    一.产生背景 又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象.组合模式依据树形结构来组合对象,用来表示部分以及整体层次.这种类型的设计模式属于结构型模式,它创建了对象组的树形结构. 这种模 ...

  8. 合成(composite)模式

    合成模式属于对象的结构模式,有时又叫做“部分——整体”模式.合成模式将对象组织到树结构中,可以用来描述整体与部分的关系.合成模式可以使客户端将单纯元素与复合元素同等看待. 合成模式 合成模式把部分和整 ...

  9. 八、结构模式之组合(Composite)模式

    组合模式属于对象的结构模式,有时又叫做部分-整体模式,组合模式将对象组织到树结构中,可以用来描述整体与部分的联系.其可以使客户端将单纯元素和组合元素同等对待. 当需求中是体现部分与整体层次的结构时,以 ...

随机推荐

  1. Effective Java实作hashCode() - 就是爱Java

    hashCode()这个方法,也是定义在Object class中,这个是所有class的base class,因此所有的class也都继承这个方法,预设是传回这个对象储存的内存地址编号,因为Mix覆 ...

  2. HDU 4035 Maze(树形概率DP)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4035 题意:一棵树,从结点1出发,在每个结点 i 都有3种可能:(1)回到结点1 , 概率 Ki:(2 ...

  3. java实现文件编码监测(转)

    chardet是mozilla自动字符集探测算法代码的java移植.这个算法的最初作者是frank Tang,C++源代码在http://lxr.mozilla.org/mozilla/source/ ...

  4. 2013第49周一jsp标签

    2013第49周一jsp标签 今天在调试一些前台页面上的问题,在处理structs标签.jstl标签时遇到了些麻烦,为了调用后台数据字典中的类方法,开始在<c:forEach>中尝试怎么样 ...

  5. MCM1988 问题B_lingo_装货问题

    两辆平板车的装货问题有七种规格的包装箱要装到两辆铁路平板车上去包装箱的宽和高是一样的但厚度(t,以厘米计)及重量(,以公斤计)是不同的.下表给出了每种包装箱的厚度重量以及数量每辆平板车有10.2 米长 ...

  6. poj1552

    Doubles Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 18824   Accepted: 10846 Descrip ...

  7. 直接使用ip访问google搜索

    173.194.127.148 173.194.127.51 173.194.36.48 (亲测,个人在用,有的ip有时候应该不能访问); 173.194.72.101 173.194.72.103 ...

  8. IT人员应该怎么跳槽

    中国的程序员只有两个状态,刚跳槽和准备跳槽.   中国IT行业的快速发展对IT从业人员的需求不断扩大,记得08年刚毕业的时候,在帝都找一个3k的工作都让我特别满足,现在仅能写出”hello world ...

  9. debian下编译libev库

    系统为Linux debian 2.6.32-5-686.这是裸系统,连xwindows都没有.帐户为root,不是的注意一下权限.这里想说明安装过程及出现的问题,故打印的信息较多,以供出现错误的读者 ...

  10. OS快速开发必备

    github:https://github.com/koknine (终于改成以前的了) 当前移动互联网行业太火爆,移动端的需求日益增长,很多开发人员每天都应对着各种需求,作为一名iOS开发人员,对于 ...