C#设计模式(12)——组合模式
1.组合模式
在软件开发中我们经常会遇到处理部分与整体的情况,如我们经常见到的树形菜单,一个菜单项的子节点可以指向具体的内容,也可以是子菜单。类似的情况还有文件夹,文件夹的下级可以是文件夹也可以是文件。举一个例子:一个公司的组织架构是这样的,首先是总公司,总公司下边有直属员工和各个部门,各个部门下边有本部门的子部门和员工。我们去怎么去获取这个公司的组织架构呢(就是有层次地遍历出公司的部门名和员工名)?
组合模式可以很好地解决这类问题,组合模式通过让树形结构的叶子节点和树枝节点使用同样的接口,结合递归的思想来处理部分与整体关系,这种方式模糊了简单对象(叶子)和对象组(树枝)间的概念,让我们可以像处理单个对象一样去处理对象组。
树叶和树枝都要使用相同的接口,所以先创建一个抽象类,其内部定义了树枝和树叶的公共接口:
/// <summary>
/// 抽象部件 定义了树枝和树叶的公共属性和接口
/// </summary>
public abstract class Component
{
public string name;
public Component(string name)
{
this.name = name;
}
//添加子节点
public abstract void Add(Component c);
//删除子节点
public abstract void Remove(Component c);
//展示方法,dept为节点深度
public abstract void Display(int dept);
}
员工类,相当于树叶,没有下一级:
//具体员工,树形结构的Leaf
public class Employee : Component
{
public Employee(string name):base(name)
{
this.name = name;
}
//Leaf不能添加/删除子节点所以空实现
public override void Add(Component c)
{
}
public override void Remove(Component c)
{ }
public override void Display(int dept)
{
Console.WriteLine(new string('-', dept)+name);
}
}
部门类,相当于树枝,下边的节点可有有子部门,也可以有员工:
/// <summary>
/// 部门类,相当于树枝
/// </summary>
public class Depart : Component
{
public Depart(string name) : base(name)
{
this.name = name;
}
//添加子节点
public List<Component> children=new List<Component>();
public override void Add(Component c)
{
children.Add(c);
}
//删除子节点
public override void Remove(Component c)
{
children.Remove(c);
}
//展示自己和和内部的所有子节点,这里是组合模式的核心
public override void Display(int dept)
{
Console.WriteLine(new string('-',dept)+name);
foreach (var item in children)
{
//这里用到了递归的思想
item.Display(dept + );
}
}
}
客户端调用:
class Program
{
static void Main(string[] args)
{
Component DepartA = new Depart("A总公司");
Component DepartAX = new Depart("AX部门");
Component DepartAY = new Depart("AY部门");
Component DepartAX1 = new Depart("AX1子部门");
Component DepartAX2 = new Depart("AX2子部门");
Component Ae1 = new Employee("公司直属员工1");
Component AXe1= new Employee("AX部门员工1");
Component AX1e1= new Employee("AX1部门员工1");
Component AX1e2= new Employee("AX1部门员工2");
Component AYe1= new Employee("AY部门员工1");
Component AYe2= new Employee("AY部门员工2");
DepartA.Add(Ae1);
DepartA.Add(DepartAX);
DepartA.Add(DepartAY);
DepartAX.Add(AXe1);
DepartAX.Add(DepartAX1);
DepartAX.Add(DepartAX2);
DepartAX1.Add(AX1e1);
DepartAX1.Add(AX1e2);
DepartAY.Add(AYe1);
DepartAY.Add(AYe2);
//遍历总公司
DepartA.Display();
Console.ReadKey();
}
}
运行结果如下:
上边的例子中部门类中包含了一个List children,这个List内部装的是该部门的子节点,这些子节点可以是子部门也可以是员工,在部门类的Display方法中通过foreach来遍历每一个子节点,如果子节点是员工则直接调用员工类中的Display方法打印出名字;如果子节点是子部门,调用部门类的Display遍历子部门的下级节点,直到下级节点只有员工或者没有下级节点为止。这里用到了递归的思想。
2.小结
上边例子的类图
组合模式的使用场景:当我们处理部分-整体的层次结构时,希望使用统一的接口来处理部分和整体时使用。
组合模式的优点:在树形结构的处理中模糊了对象和对象组的概念,使用对象和对象组采用了统一的接口,让我们可以像处理简单对象一样处理对象组。
C#设计模式(12)——组合模式的更多相关文章
- 设计模式-12组合模式(Composite Pattern)
1.模式动机 很多时候会存在"部分-整体"的关系,例如:大学中的部门与学院.总公司中的部门与分公司.学习用品中的书与书包.在软件开发中也是这样,例如,文件系统中的文件与文件夹.窗体 ...
- JavaScript设计模式之----组合模式
javascript设计模式之组合模式 介绍 组合模式是一种专门为创建Web上的动态用户界面而量身制定的模式.使用这种模式可以用一条命令在多个对象上激发复杂的或递归的行为.这可以简化粘合性代码,使其更 ...
- C#设计模式(10)——组合模式(Composite Pattern)
一.引言 在软件开发过程中,我们经常会遇到处理简单对象和复合对象的情况,例如对操作系统中目录的处理就是这样的一个例子,因为目录可以包括单独的文件,也可以包括文件夹,文件夹又是由文件组成的,由于简单对象 ...
- c++设计模式15 --组合模式
今天研究了一下设计模式15 组合模式 本人是菜鸟一枚,所以一开始完全不懂组合究竟是什么意思.先上图一张,树形结构图: 文档说,如果想做出这样的结构,通常考虑组合模式.那是为什么呢?现在让我们看一下组合 ...
- 乐在其中设计模式(C#) - 组合模式(Composite Pattern)
原文:乐在其中设计模式(C#) - 组合模式(Composite Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 组合模式(Composite Pattern) 作者:weba ...
- C#设计模式(10)——组合模式(Composite Pattern)(转)
一.引言 在软件开发过程中,我们经常会遇到处理简单对象和复合对象的情况,例如对操作系统中目录的处理就是这样的一个例子,因为目录可以包括单独的文件,也可以包括文件夹,文件夹又是由文件组成的,由于简单对象 ...
- C#设计模式:组合模式(Composite Pattern)
一,C#设计模式:组合模式(Composite Pattern) using System; using System.Collections.Generic; using System.Linq; ...
- [设计模式] 8 组合模式 Composite
DP书上给出的定义:将对象组合成树形结构以表示“部分-整体”的层次结构.组合使得用户对单个对象和组合对象的使用具有一致性.注意两个字“树形”.这种树形结构在现实生活中随处可见,比如一个集团公司,它有一 ...
- 【GOF23设计模式】组合模式
来源:http://www.bjsxt.com/ 一.[GOF23设计模式]_组合模式.树状结构.杀毒软件架构.JUnite底层架构.常见开发场景 package com.test.composite ...
- iOS设计模式之组合模式
组合模式(Composite) 基本理解 整体和部分可以一直对待. 组合模式:将对象组合成树形结构以表示"部分--整体"的层次结构.组合模式使得用户对单个对象和组合独享的使用具有一 ...
随机推荐
- 洛谷P1063能量项链题解
$题目$ 不得不说,最近我特别爱刷这种区间DP题,因为这个跟其他的DP有些不一样的地方,主要是有一定的套路,就是通过小区间的状态更新大区间,从而得到原题给定区间的最优解. $但是$ 这个题应该跟$石子 ...
- scrapy入门与进阶
Scrapy是用纯Python实现一个为了爬取网站数据.提取结构性数据而编写的应用框架,用途非常广泛. 框架的力量,用户只需要定制开发几个模块就可以轻松的实现一个爬虫,用来抓取网页内容以及各种图片,非 ...
- Go Deeper HDU - 3715(2 - sat 水题 妈的 智障)
Go Deeper Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total S ...
- 【XSY1591】卡片游戏 DP
题目描述 有标有数字为\(1\)~\(9\)的卡片各\(a_1,a_2\cdots a_9\)张,还有标有乘号的卡片\(m\)张.从中取出\(n\)张按任意顺序排列,取出两个乘号相邻和乘法在边界上的非 ...
- bzoj 2761: [JLOI2011]不重复数字 (map||Treap)
链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2761 思路: map标记 实现代码: #include<bits/stdc++.h&g ...
- ELK部署详解--filebeat
filebeat.yml ###################### Filebeat Configuration Example ######################### # This ...
- CF1139E Maximize Mex(二分图匹配,匈牙利算法)
好题.不过之前做过的[SCOI2010]连续攻击游戏跟这题一个套路,我怎么没想到…… 题目链接:CF原网 洛谷 题目大意:在一个学校有 $n$ 个学生和 $m$ 个社团,每个学生有一个非负整数能力值 ...
- Ubuntu18.04搜狗输入法最新版本2.2.0.0108经常乱码的解决方案
图示 解决 旧版 可以安装旧版(我只在新版sogoupinyin_2.2.0.0108_amd64才遇到这个问题) 旧版安装指南:http://www.cnblogs.com/dunitian/p/6 ...
- 模拟@Test的功能实现
注解和注释区别 * 注释:给程序员看的.* 注解:给虚拟机看的.(让虚拟机看到程序中的注解,注解代表程序的一些特殊的功能.) JDK中提供的注解 @Override :描述子类重写父类的方法: * J ...
- CentOS单网卡绑定双IP
OS:CnetOS 6.8 初始网卡配置文件 [root@localhost /]# vim /etc/sysconfig/network-scripts/ifcfg-eth0 DEVICE=eth0 ...