一、概述

在软件开发中,我们往往会遇上类似树形结构的对象体系。即某一对象既可能在树形结构中作为叶节点存在,也可能作为分支节点存在。比如在文件系统中,文件是作为叶节点存在,而文件夹就是分支节点。在设计这类对象时,如果将叶节点和分支节点区别对待,那么在实际开发中会带来较大的复杂性。比如客户端调用时可能会频繁的使用转型操作,同时代码的可维护性和扩展性也较差。在设计中使用组合模式可以解决这一系列弊端。

二、组合模式

组合模式定义了叶节点和分支节点的一致的接口,将客户端代码与复杂的对象结构解耦,大大降低了客户端调用的复杂性。其结构图如下:

Component定义了所有对象的共同接口,可以在Component中定义管理Component组件的接口以保证一致性,也可以将管理接口下放至Composite中以提高系统调用的安全性。

Leaf表示叶节点。

Composite定义了分支节点对象的行为,并提供一个容器用户存储其子节点。

Client通过Component来处理所有对象。

三、示例

我们利用组合模式来实现一个绘图系统。在该系统中具有Line、Circle、Picture等多种元素,其中Picture可以含有各类子元素。

首先定义Component。

 1     public abstract class Graphic
2 {
3 private string _name;
4
5 public Graphic(string name)
6 {
7 _name = name;
8 }
9
10 public abstract void Add(Graphic graphic);
11 public abstract void Remove(Graphic graphic);
12
13 public virtual void Draw()
14 {
15 Console.WriteLine("Draw {0} {1}", GetType().Name, _name);
16 }
17 }

接着定义Picture对象。

 1     public class Picture : Graphic
2 {
3 private List<Graphic> _graphic = new List<Graphic>();
4 public Picture(string name)
5 : base(name)
6 {
7 }
8
9 public override void Add(Graphic graphic)
10 {
11 _graphic.Add(graphic);
12 }
13 public override void Remove(Graphic graphic)
14 {
15 _graphic.Remove(graphic);
16 }
17
18 public override void Draw()
19 {
20 base.Draw();
21 foreach (Graphic graphic in _graphic)
22 {
23 graphic.Draw();
24 }
25 }
26 }

再定义Line和Circle。

 1     public class Line : Graphic
2 {
3 public Line(string name)
4 : base(name)
5 {
6 }
7
8 public override void Add(Graphic graphic)
9 {
10 throw new Exception("Line can't add graphic");
11 }
12 public override void Remove(Graphic graphic)
13 {
14 throw new Exception("Line can't remove graphic");
15 }
16 }
17
18 public class Circle : Graphic
19 {
20 public Circle(string name)
21 : base(name)
22 {
23 }
24
25 public override void Add(Graphic graphic)
26 {
27 throw new Exception("Circle can't add graphic");
28 }
29 public override void Remove(Graphic graphic)
30 {
31 throw new Exception("Circle can't remove graphic");
32 }
33 }

这样就可以通过统一的Draw接口画出整幅图画。

C#设计模式——组合模式(Composite Pattern)的更多相关文章

  1. 浅谈设计模式--组合模式(Composite Pattern)

    组合模式(Composite Pattern) 组合模式,有时候又叫部分-整体结构(part-whole hierarchy),使得用户对单个对象和对一组对象的使用具有一致性.简单来说,就是可以像使用 ...

  2. 设计模式 - 组合模式(composite pattern) 迭代器(iterator) 具体解释

    组合模式(composite pattern) 迭代器(iterator) 具体解释 本文地址: http://blog.csdn.net/caroline_wendy 參考组合模式(composit ...

  3. 设计模式 -- 组合模式 (Composite Pattern)

    定义: 对象组合成部分整体结构,单个对象和组合对象具有一致性. 看了下大概结构就是集团总公司和子公司那种层级结构. 角色介绍: Component :抽象根节点:其实相当去总公司,抽象子类共有的方法: ...

  4. 乐在其中设计模式(C#) - 组合模式(Composite Pattern)

    原文:乐在其中设计模式(C#) - 组合模式(Composite Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 组合模式(Composite Pattern) 作者:weba ...

  5. 设计模式系列之组合模式(Composite Pattern)——树形结构的处理

    说明:设计模式系列文章是读刘伟所著<设计模式的艺术之道(软件开发人员内功修炼之道)>一书的阅读笔记.个人感觉这本书讲的不错,有兴趣推荐读一读.详细内容也可以看看此书作者的博客https:/ ...

  6. 二十四种设计模式:组合模式(Composite Pattern)

    组合模式(Composite Pattern) 介绍将对象组合成树形结构以表示"部分-整体"的层次结构.它使得客户对单个对象和复合对象的使用具有一致性.示例有一个Message实体 ...

  7. 【设计模式】组合模式 Composite Pattern

    树形结构是软件行业很常见的一种结构,几乎随处可见,  比如: HTML 页面中的DOM,产品的分类,通常一些应用或网站的菜单,Windows Form 中的控件继承关系,Android中的View继承 ...

  8. python 设计模式之组合模式Composite Pattern

    #引入一 文件夹对我们来说很熟悉,文件夹里面可以包含文件夹,也可以包含文件. 那么文件夹是个容器,文件夹里面的文件夹也是个容器,文件夹里面的文件是对象. 这是一个树形结构 咱们生活工作中常用的一种结构 ...

  9. 设计模式-12组合模式(Composite Pattern)

    1.模式动机 很多时候会存在"部分-整体"的关系,例如:大学中的部门与学院.总公司中的部门与分公司.学习用品中的书与书包.在软件开发中也是这样,例如,文件系统中的文件与文件夹.窗体 ...

随机推荐

  1. asp Gridview绑定形式获取行号

    Gridview中使用<%# Container.DataItemIndex %>取得当前行的序号 而在Repeater控件中使用Container.ItemIndex取得当前行的序号 & ...

  2. selenium实战练习之:粉丝反馈表单的自动化脚本

    链接 粉丝反馈表 要求 服务质量5颗星 喜欢的内容选择各种公开课 对交流群的意见需要填写 留下自己正确的联系方式 点击提交 断言 不需要断言,能符合上面的要求成功提交就可以

  3. ajax 异步请求webservice(XML格式)

    function callAjaxWebservice(){ alert("call ajax"); try { $.ajax({ type: "POST", ...

  4. JVM内存溢出及合理配置

    Tomcat本身不能直接在计算机上运行,需要依赖于硬件基础之上的操作系统和一个Java虚拟机.Tomcat的内存溢出本质就是JVM内存溢出,所以在本文开始时,应该先对Java JVM有关内存方面的知识 ...

  5. LoadRunner AJAX TruClient协议Tips and Tricks

    LoadRunner AJAX TruClient协议Tips and Trickshttp://automationqa.com/forum.php?mod=viewthread&tid=2 ...

  6. Newtonsoft 自定义输出内容

    高级用法 1.忽略某些属性 2.默认值的处理 3.空值的处理 4.支持非公共成员 5.日期处理 6.自定义序列化的字段名称 7.动态决定属性是否序列化 8.枚举值的自定义格式化问题 9.自定义类型转换 ...

  7. Linux设备驱动剖析之Input(三)

    /* get current state of buttons */ ; i < pdata->nbuttons; i++) gpio_keys_report_event(&dda ...

  8. SCRIPT1010: 缺少标识符 常见原因

    SCRIPT1010: 缺少标识符 ,一般是在IE下会出现这个问题. 今天在调试一段js代码时,在chrome,ff下均正常,但是在IE下就是一直这样的提示,出现这个问题的原因主要有以下几点: 1.出 ...

  9. BAPI 调用相当于BAPI_TRANSACTION_COMMIT 的方法

    为什么.net调用SAP的BAPI接口需要调用BAPI_TRANSACTION_COMMIT呢?首先得明白BAPI_TRANSACTION_COMMIT这个BAPI的作用.它功劳很大,在SAP里面很多 ...

  10. 二十七、EFW框架BS系统开发中的MVC模式探讨

    回<[开源]EFW框架系列文章索引>        EFW框架源代码下载V1.3:http://pan.baidu.com/s/1c0dADO0 EFW框架实例源代码下载:http://p ...