组合模式(Composite Pattern)
- 组合模式概述
定义:组合多个对象形成树形结构以表示具有部分-整体关系的层次结构。组合模式让客户端可以统一对待单个对象和组合对象。又被成为“部分-整体”(Part-Whole)模式,属于对象结构性模式
定义什么的,最枯燥了。简单的来说,就如我们鼠标右击新建文件夹一样,在一个磁盘里,我们可以新建一个文件夹A,也可以新建某个类型的文件a,A和a都在同一目录下,当然,我们也可以点击进入文件夹A,在A中新建新的文件夹B,也可以在A中新建文件b。只要是文件夹,就可以在里面继续新建文件夹和文件,而文件则只能用来放数据,不能在新建了。
当然,也可以通过win+r调出运行,输入cmd(commmand),进入你想查看文件的磁盘,输入tree命令,就可以结构性的查看所有文件。在上述图中可以看出文件结构就如同一棵树,有文件夹,有文件,我们把文件成为叶子(Laef),因为文件不能再展开了,就如树形结构中叶子是最底层了;把文件夹称为容器(Container),因为文件夹里既可以文件夹,又可以放文件。当想要查看一个磁盘的所有文件时,可以使用DFS(深度优先搜索)即递归的对每个文件夹进行同样的搜索,一条路走到底,当访问到叶子结点时,再退回去访问别的结点。
- 组合模式结构和实现
- Component(抽象构件):它可以是接口或抽象类,为叶子构件和容器构件对象声明接口。定义了访问管理它的子构件的方法,就是对一个子构件该有的操作都应该在这声明,如创建子构件,删除子构件,打开子构件,重命名子构件,复制子构件.......
- Leaf(叶子构件):代表一个文件,实现在Component中的行为,即对文件的操作,可以是读文件,写文件,删除文件,复制文件......
- Composite(容器构件):代表一个文件夹,它提供一个集合放子节点,可以是文件夹,也可以是文件,所以它有一个聚合箭头指向Component,代表可以递归的创建构件
1 abstract class Component 2 { 3 public abstract void Add(Component c); 4 public abstract void Remove(Component c); 5 public abstract Component GetChild(int i); 6 public abstract void Operation(); 7 } 8 class Leaf : Component 9 { 10 public override void Add(Component c) 11 { 12 //throw new NotImplementedException();//这里是报错,叶子文件没有此方法的 13 } 14 15 public override void Remove(Component c) 16 { 17 //throw new NotImplementedException();//同上 18 } 19 20 public override Component GetChild(int i ) 21 { 22 //throw new NotImplementedException();//同上 23 return null; 24 } 25 26 public override void Operation() 27 { 28 //对文件的可执行方法 29 } 30 } 31 class Composite : Component 32 { 33 private IList<Component> list = new List<Component>();//这里通链表容器存放文件夹 34 public override void Add(Component c) 35 { 36 list.Add(c); 37 } 38 39 public override void Remoce(Component c) 40 { 41 list.Remove(c); 42 } 43 44 public override Component GetChild(int i ) 45 { 46 return (Component)list(c); 47 } 48 49 public override void Operation() 50 { 51 //递归实现容器中的对文件的方法 52 foreach(Component child in list) 53 { 54 (Component)child.Operation(); 55 } 56 } 57 }
- 组合模式的应用
教育机构的OA系统要给各办公室下发公文(IssuedBytheOfficeDoucument),采用组合模式模拟实现
分析:从图中可以看出,北京总部,湖南分校,长沙叫教学点,湘潭教学点这几个有子构件,所以它们为文件容器,而教务办公室,行政办公室即为叶子,当然,每个叶子是不同的,要区别开。因此我们定义一个抽象机构类(AbstractInstitutions),其中声明Add,Remove,GetChild和IssuedBytheOfficeDoucument方法。
1 abstract class AbstractInstitutions//Component 2 { 3 public abstract void Add(AbstractInstitutions institutions); 4 public abstract void Remove(AbstractInstitutions institutions); 5 public abstract AbstractInstitutions GetChild(int i); 6 public abstract void IssuedBytheOfficeDoucument(); 7 }
View Code
教务办公室,有自己的名字,即哪一个教务办公室,它只能收到下发的公文
1 class AcademicAffairsOffice : AbstractInstitutions//Leaf 教务办公室 2 { 3 private string name; 4 public AcademicAffairsOffice(string name) 5 { 6 this.name = name; 7 } 8 public override void Add(AbstractInstitutions institutions) 9 { 10 Console.WriteLine("Can't realize this method!!!"); 11 } 12 13 public override void Remove(AbstractInstitutions institutions) 14 { 15 Console.WriteLine("Can't realize this method!!!"); 16 } 17 18 public override AbstractInstitutions GetChild(int i) 19 { 20 Console.WriteLine("Can't realize this method!!!"); 21 return null; 22 } 23 24 public override void IssuedBytheOfficeDoucument() 25 { 26 Console.WriteLine("issued by the office doucument to the {0}",name); 27 } 28 }
View Code
行政办公室和教务办公室类似的实现
1 class AdministrationOffice : AbstractInstitutions//Leaf 行政办公室 2 { 3 private string name; 4 public AdministrationOffice(string name) 5 { 6 this.name = name; 7 } 8 9 public override void Add(AbstractInstitutions institutions) 10 { 11 Console.WriteLine("Can't realize this method!!!"); 12 } 13 14 public override void Remove(AbstractInstitutions institutions) 15 { 16 Console.WriteLine("Can't realize this method!!!"); 17 } 18 19 public override AbstractInstitutions GetChild(int i) 20 { 21 Console.WriteLine("Can't realize this method!!!"); 22 return null; 23 } 24 25 public override void IssuedBytheOfficeDoucument() 26 { 27 Console.WriteLine("issued by the office doucument to the {0}", name); 28 } 29 }
View Code
容器类中实现抽象构件中的方法,并且要向下属机构下发公文
1 class TeachArea : AbstractInstitutions//Composite //教学点 2 { 3 private string name; 4 private IList<AbstractInstitutions> AreaList = new List<AbstractInstitutions>(); 5 6 public TeachArea(String name) 7 { 8 this.name = name; 9 } 10 11 public override void Add(AbstractInstitutions institutions) 12 { 13 AreaList.Add(institutions); 14 } 15 16 public override void Remove(AbstractInstitutions institutions) 17 { 18 AreaList.Remove(institutions); 19 } 20 21 public override AbstractInstitutions GetChild(int i) 22 { 23 return (AbstractInstitutions)AreaList[i]; 24 } 25 26 public override void IssuedBytheOfficeDoucument() 27 { 28 Console.WriteLine("Issue official documents to the {0}", name); 29 foreach (Object obj in AreaList) 30 { 31 ((AbstractInstitutions)obj).IssuedBytheOfficeDoucument(); 32 } 33 } 34 }
View Code
Program中,要将所有的机构创建出来,并一一Add到对应的容器中,最后有由北京总部向下发送公文
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 AbstractInstitutions BeijingHeadquarters; 6 BeijingHeadquarters = new TeachArea("BeijingHeadquarters"); 7 8 AbstractInstitutions BeijingAcademicAffairsOffice; 9 BeijingAcademicAffairsOffice = new AcademicAffairsOffice("BeijingAcademicAffairsOffice"); 10 AdministrationOffice BeijingAdministrationOffice; 11 BeijingAdministrationOffice = new AdministrationOffice("BeijingAdministrationOffice"); 12 13 AbstractInstitutions HunanPartition; 14 HunanPartition = new TeachArea("HunanPartition"); 15 16 AbstractInstitutions HunanChangshaArea; 17 HunanChangshaArea = new TeachArea("HunanChangshaArea"); 18 19 AbstractInstitutions HunanXiangtanArea; 20 HunanXiangtanArea = new TeachArea("HunanXiangtanArea"); 21 22 AbstractInstitutions HunanAcademicAffairOffice; 23 HunanAcademicAffairOffice = new AcademicAffairsOffice("HunanAcademicAffairOffice"); 24 AbstractInstitutions HunanAdministrationOffice; 25 HunanAdministrationOffice = new AdministrationOffice("HunanAdministrationOffice"); 26 27 Console.WriteLine(); 28 AbstractInstitutions ChangshaAcademicAffairOffice; 29 ChangshaAcademicAffairOffice = new AcademicAffairsOffice("ChangshaAcademicAffairOffice"); 30 31 AbstractInstitutions ChangshaAdministrationOffice; 32 ChangshaAdministrationOffice = new AdministrationOffice("ChangshaAdministrationOffice"); 33 AbstractInstitutions XiangtanAcademicAffairOffice; 34 XiangtanAcademicAffairOffice = new AcademicAffairsOffice("XiangtanAcademicAffairOffice"); 35 36 AbstractInstitutions XiangtanAdministrationOffice; 37 XiangtanAdministrationOffice = new AdministrationOffice("XiangtanAdministrationOffice"); 38 39 HunanChangshaArea.Add(ChangshaAcademicAffairOffice); 40 HunanChangshaArea.Add(ChangshaAdministrationOffice); 41 42 HunanXiangtanArea.Add(XiangtanAcademicAffairOffice); 43 HunanXiangtanArea.Add(XiangtanAdministrationOffice); 44 45 HunanPartition.Add(HunanChangshaArea); 46 HunanPartition.Add(HunanXiangtanArea); 47 HunanPartition.Add(HunanAcademicAffairOffice); 48 HunanPartition.Add(HunanAdministrationOffice); 49 50 BeijingHeadquarters.Add(BeijingAcademicAffairsOffice); 51 BeijingHeadquarters.Add(BeijingAdministrationOffice); 52 BeijingHeadquarters.Add(HunanPartition); 53 BeijingHeadquarters.IssuedBytheOfficeDoucument(); 54 } 55 }
View Code
运行结果:
- 透明组合模式和安全组合模式
- 透明组合模式
在Component中声明所有的方法,这样满足了一致性的原则,即对叶子和容器对象都是一样的处理,不需用再去判断,这个对象是叶子还是容器啊,如果是容器,可以实现哪些方法,如果是叶子,又只能实现哪些方法。这些判断都不需要。但是,由于叶子也继承了Component的方法,因此不安全,叶子对象不能调用Add,Remove,GetChild的方法,如果运行时调用,会出错,因此要提供错误处理代码(如上述例子中的( Console.WriteLine("Can't realize this method!!!");
- 安全组合模式
Component中没有声明任何方法,而是在Composite中声明并实现,这样做不会因为Leaf调用错误的方法而报错,但缺点是不够透明,即要区别的对待叶子构件和容器构件,但是日常使用是很多的,毕竟安全的往往好很多
上面的例子使用了透明组合模式。
- 组合模式的优缺点和适用环境
- 组合模式的优点:
- 可以清楚的定义分层次的复杂对象,表示对象的全部会部分层次,让客户忽略层次的差异,方便控制
- 客户端可以一致性的使用一个组合结构或其中单个对象,不必关心处理的是单个对象(叶子文件)还是组合结构(文件夹容器),简化了客户端代码
- 增加新的容器构件和叶子构件很方便
- 为树型结构的面向对象实现了一种灵活的解决方案
- 组合模式的缺点:
- 在增加新的构件时很难对容器中的构件类型进行控制。如果我希望文件夹里只能放文件时,则需要复杂的实现过程来实现
- 组合模式的适用环境
- 在具有整体和部分层次的结构中,希望通过一种方式忽略整体与部分的差异,一致的对待它们
- 在一个使用面向对象语言开发的系统中要处理一个树形结构时
- 在一个系统总能够分离出叶子和容器对象,而且它们的类型不固定,需要增加一些新的类型
转载于:https://www.cnblogs.com/ygsworld/p/10803240.html
组合模式(Composite Pattern)相关推荐
- 【设计模式】组合模式 Composite Pattern
树形结构是软件行业很常见的一种结构,几乎随处可见, 比如: HTML 页面中的DOM,产品的分类,通常一些应用或网站的菜单,Windows Form 中的控件继承关系,Android中的View继承 ...
- python 设计模式之组合模式Composite Pattern
#引入一 文件夹对我们来说很熟悉,文件夹里面可以包含文件夹,也可以包含文件. 那么文件夹是个容器,文件夹里面的文件夹也是个容器,文件夹里面的文件是对象. 这是一个树形结构 咱们生活工作中常用的一种结构 ...
- 24组合模式(Composite Pattern)
动机(Motivate): 组合模式有时候又叫做部分-整体模式,它使我们树型结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以向处理简单元素一样来处理复杂元素,从而使得客户程序与复杂元 ...
- C#设计模式——组合模式(Composite Pattern)
一.概述 在软件开发中,我们往往会遇上类似树形结构的对象体系.即某一对象既可能在树形结构中作为叶节点存在,也可能作为分支节点存在.比如在文件系统中,文件是作为叶节点存在,而文件夹就是分支节点.在设计这 ...
- 组合模式-Composite Pattern
目录 组合模式的定义与特点 组合模式的结构与实现 组合模式的应用实例 组合模式的应用场景 组合模式的扩展 树形结构在软件中随处可见,例如操作系统中的目录结构.应用软件中的菜单.办公系统中的公司组织结构 ...
- 设计模式:组合模式(Composite Pattern)
组合模式: 又叫部分整体模式, 它创建了对象组的树形结构,将对象组合成树状结构以表示"整体-部分"的层次关系. JDK中的HashMap就使用了组合模式 public abstra ...
- 组合模式测试组合模式(Composite Pattern)
改章节是一篇关于组合模式测试的帖子 像一个树形结构一样使用基本的对象和自己本身构建一个复杂的对象,称为组合模式. 这类模式很轻易学习以及应用到某个系统中.组合模式属于结构设计模式之一,比拟常用.经典的 ...
- 设计模式(17):结构型-组合模式(Composite)(2)
设计模式(Design pattern) 是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可靠性. 毫无疑问,设计模式 ...
- 【设计模式自习室】结构型:组合模式 Composite
前言 <设计模式自习室>系列,顾名思义,本系列文章带你温习常见的设计模式.主要内容有: 该模式的介绍,包括: 引子.意图(大白话解释) 类图.时序图(理论规范) 该模式的代码示例:熟悉该模 ...
最新文章
- MIT警告深度学习正在逼近计算极限,网友:放缓不失为一件好事
- Android中解决debug.keystore到期的问题
- mysql死锁检测算法_MySQL 8 死锁检测脚本
- python中requests的常用方法_python3 Requests常用操作
- linux中级-JAVA企业级应用TOMCAT实战
- 使用纯css做的按钮
- Mod, Or and Everything HDU - 6950
- 分割线不显示_90后都30岁了,为什么还不结婚
- 行人属性数据集pa100k_基于InceptionV3的多数据集联合训练的行人外观属性识别方法与流程...
- Java笔记-腾讯验证码平台使用实例
- Air与java通信
- js关于两个字符串的加减乘除运算
- 惠普136nw打印机清零_惠普打印机硒鼓清零方法是怎样的
- 电脑主机箱前置耳机没声音(window7)
- # 2gether 在一起 # 一份生日Party邀请函待查收
- SQL查询语句(从单表到多表、从简单到复杂)
- 《惢客创业日记》2018.11.23(周五) 郭鑫年,你是不是死了?
- JAVA水晶报表从环境搭建到创建动态水晶报表
- 作为有经验的程序员如果不懂Lambda表达式就说不过去了吧
- 这 4 个超实用的 Docker 镜像构建技巧!你不会不知道吧?
热门文章
- iOS功能-统计平均下班时间
- (0065)iOS开发之工具条UIToolBar
- JavaScript基础,Cookies,Sessions
- Hystrix的一个坑,queue中的run方法没有被执行?
- rhel 6.4 + udev + 11.2.0.3 + asm 单点安装
- 【实习项目记录】(一)加密算法MD5和RSA
- 使用AppleScript播放指定时间的电影片段
- poj 2454 Jersey Politics 随机化
- 好记性不如烂博客之 Quartz InterruptableJob 可拦截任务
- .h头文件 .lib动态链接库文件 .dll 动态链接库