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) 基本理解 整体和部分可以一直对待. 组合模式:将对象组合成树形结构以表示"部分--整体"的层次结构.组合模式使得用户对单个对象和组合独享的使用具有一 ...
随机推荐
- 【CodeForces 717C】Potions Homework
BUPT 2017 summer training (for 16) #1G 题意 每个人有一个懒惰值,每个任务有个难度,一开始每个人的任务和懒惰值都为\(a_i\),完成任务时间是懒惰值乘以难度,现 ...
- 【HDU 4343】Interval query(倍增)
BUPT2017 wintertraining(15) #8D 题意 给你x轴上的N个线段,M次查询,每次问你[l,r]区间里最多有多少个不相交的线段.(0<N, M<=100000) 限 ...
- Hdoj 1392.Surround the Trees 题解
Problem Description There are a lot of trees in an area. A peasant wants to buy a rope to surround a ...
- 【BZOJ3174】[TJOI2013]拯救小矮人(贪心,动态规划)
[BZOJ3174][TJOI2013]拯救小矮人(贪心,动态规划) 题面 BZOJ 洛谷 题解 我们定义一个小矮人的\(A_i+B_i\)为它的逃跑能力. 我们发现,如果有两个小矮人\(x,y\), ...
- urllib的实现---请求响应and请求头处理
在python3中 urllib库和urilib2库合并成了urllib库..其中urllib2.urlopen()变成了urllib.request.urlopen()urllib2.Request ...
- HEOI2016解题报告
树 在2016年,佳媛姐姐刚刚学习了树,非常开心.现在他想解决这样一个问题:给定一颗有根树(根为1),有以下 两种操作:1. 标记操作:对某个结点打上标记(在最开始,只有结点1有标记,其他结点均无标记 ...
- centos7下安装vnc更改vnc默认端口号
应用场景:某些情景下,需要用的linux的桌面环境,Ubuntu的桌面性能在linux发行版中算是数一数二的,如果不熟悉Debian系统,Centos/RHEL系列也行: 我这里的场景是开发人员不 ...
- multimap多重映照容器
//multimap的基本用法 #include<map> #include<iostream> #include<string> using namespace ...
- (转)深入理解Java注解类型(@Annotation)
背景:在面试时候问过关于注解的问题,工作中也用到过该java的特性,但是也没有深入的了解. 秒懂,Java 注解 (Annotation)你可以这样学 ps:注解最通俗易懂的解释 注解是一系列元数据, ...
- (转)喜马拉雅2018 Java面试题目
背景:将网上的题目整理下. java基础 1:hashTable hashMap ConcurrentHashMap 的区别.数据结构.线程安全 2:equals和==区别, 重写equals一定要重 ...