什么是组合模式?

  组合模式(Composite):将对象组合成树形结构以表示“部分-整体”的层次结构。

               组合模式使得用户对单个对象和组合对象的使用具有一致性。

何时使用组合模式?

  当需求中是体现部分与整体层次的结构时,以及你希望用户可以忽略组合对象与单个对象的不同,同意地使用组合结构中的所有对象时,就应该考虑用组合模式。

组合模式的组成

  Component():组合中的对象声明接口,在适当情况下,实现所有类共有接口的默认行为。

        声明一个接口用于访问和管理Component的子部件。

  Leaf():在组合中表示叶节点对象,叶节点没有子节点。

  Composite():定义有枝节点行为,用来存储子部件,在Component接口中实现与子部件有关的操作,比如增加Add和删除Remove

组合模式具体实现

组合模式的结构

   

组合模式的实现:

Component():

         abstract class Component
{
protected string name;
public Component(string name)
{
this.name = name;
}
public abstract void Add(Component c);
public abstract void Remove(Component c);
public abstract void Diaplay(int depth);
}

Leaf():

        class Leaf : Component
{
public Leaf(string name) : base(name)
{ } public override void Add(Component c)
{
Console.WriteLine("Cannot add a leaf");
} public override void Diaplay(int depth)
{
Console.WriteLine(new String('-', depth) + name);
} public override void Remove(Component c)
{
Console.WriteLine("Cannot remove from a leaf");
}
}

Composite():

         class Composite : Component
{
private List<Component> children = new List<Component>();
public Composite(string name) : base(name)
{ } public override void Add(Component c)
{
children.Add(c);
} public override void Diaplay(int depth)
{
//将 System.String 类的新实例初始化为由重复指定次数的指定 Unicode 字符指示的值
Console.WriteLine(new String('-', depth) + name);
foreach(Component component in children)
{
component.Diaplay(depth + );
}
} public override void Remove(Component c)
{
children.Remove(c);
}
}

主函数调用:

        static void Main(string[] args)
{
Composite root = new Composite("root");
root.Add(new Leaf("Leaf A"));
root.Add(new Leaf("Leaf B")); Composite comp = new Composite("Composite X");
comp.Add(new Leaf("Leaf XA"));
comp.Add(new Leaf("Leaf XB")); root.Add(comp); Composite comp2 = new Composite("Composite XY");
comp2.Add(new Leaf("Leaf XYA"));
comp2.Add(new Leaf("Leaf XYB")); comp.Add(comp2); root.Add(new Leaf("Leaf C")); Leaf leaf = new Leaf("Leaf D");
root.Add(leaf);
root.Remove(leaf); root.Diaplay(); Console.Read();
}

实现效果:

  

实例解析

  为了深化理解,我们准备一个具体的实例来分析。

  

分析:

  

具体实现:

     class Program
{
static void Main(string[] args)
{
ConcreteCompany root = new ConcreteCompany("北京公司总部");
root.Add(new HRDepartment("北京公司总部人力资源部"));
root.Add(new FinanceDepartment("北京公司总部财务部")); ConcreteCompany com = new ConcreteCompany("上海分公司");
com.Add(new HRDepartment("上海分公司人力资源部"));
com.Add(new FinanceDepartment("上海分公司财务部")); root.Add(com); ConcreteCompany com2 = new ConcreteCompany("南京办事处");
com2.Add(new HRDepartment("南京办事处人力资源部"));
com2.Add(new FinanceDepartment("南京办事处财务部")); com.Add(com2); ConcreteCompany com3 = new ConcreteCompany("杭州办事处");
com3.Add(new HRDepartment("杭州办事处人力资源部"));
com3.Add(new FinanceDepartment("杭州办事处财务部"));
com.Add(com3); Console.WriteLine("\n结构图:");
root.Diaplay(); Console.WriteLine("\n职责:");
root.LineOfDuty();
Console.Read();
}
}
abstract class Company
{
protected string name;
public Company(string name)
{
this.name = name;
}
public abstract void Add(Company c);
public abstract void Remove(Company c);
public abstract void Diaplay(int depth);
public abstract void LineOfDuty();
}
class ConcreteCompany : Company
{
private List<Company> children = new List<Company>();
public ConcreteCompany(string name) : base(name)
{ } public override void Add(Company c)
{
children.Add(c);
} public override void Diaplay(int depth)
{
Console.WriteLine(new String('-', depth) + name);
foreach(Company company in children)
{
company.Diaplay(depth + );
}
} public override void LineOfDuty()
{
foreach(Company component in children)
{
component.LineOfDuty();
}
} public override void Remove(Company c)
{
children.Remove(c);
}
}
class HRDepartment : Company
{
public HRDepartment(string name) : base(name)
{
} public override void Add(Company c)
{ } public override void Diaplay(int depth)
{
Console.WriteLine(new String('-', depth) + name);
} public override void LineOfDuty()
{ Console.WriteLine("{0} 员工招聘培训管理", name); } public override void Remove(Company c)
{ }
}
class FinanceDepartment : Company
{
public FinanceDepartment(string name) : base(name)
{ } public override void Add(Company c)
{ } public override void Diaplay(int depth)
{
Console.WriteLine(new String('-', depth) + name);
} public override void LineOfDuty()
{
Console.WriteLine("{0} 公司财务收支管理", name);
} public override void Remove(Company c)
{ }
}

备注:文中所有代码及知识点均来自于《大话设计模式》,本人属于边学边看边敲代码边总结的阶段。

C#学习笔记-组合模式的更多相关文章

  1. 学习笔记——组合模式Composite

    组合模式,典型的层次结构. 与装饰器类图相似. 区别在于:装饰器模式是为了在接口中增加方法,而组合模式在于层次元素的叠加. ConcreteComponent就是中间结点,可以包含更多的Concret ...

  2. 《Head first设计模式》学习笔记 – 迭代器模式

    <Head first设计模式>学习笔记 – 迭代器模式 代器模式提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示. 爆炸性新闻:对象村餐厅和对象村煎饼屋合并了!真是个 ...

  3. 《Head First 设计模式》学习笔记——迭代模式 + 组合模式

    迭代模式设置共生死亡,一般来说.我们只是想实现一个集,我们需要的同时提供这个集合的迭代器,喜欢java中间Collection.List.Set.Map等,这些集合都有自己的迭代器.假如我们要实现一个 ...

  4. 设计模式学习之组合模式(Composite,结构型模式)(10)

    转载地址:http://www.cnblogs.com/zhili/p/CompositePattern.html 一.引言 在软件开发过程中,我们经常会遇到处理简单对象和复合对象的情况,例如对操作系 ...

  5. 设计模式学习心得<组合模式 Composite>

    组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象.组合模式依据树形结构来组合对象,用来表示部分以及整体层次.这种类型的设计模式属于结构型模式, ...

  6. Java设计模式学习记录-组合模式

    前言 今天要介绍的设计模式是组合模式,组合模式也是结构型设计模式的一种,它主要体现了整体与部分的关系,其典型的应用就是树形结构.组合是一组对象,其中的对象可能包含一个其他对象,也可能包含一组其他对象. ...

  7. 设计模式 笔记 组合模式 Composite

    //---------------------------15/04/16---------------------------- //Composite 组合模式----对象结构型模式 /* 1:意 ...

  8. 设计模式之笔记--组合模式(Composite)

    组合模式(Composite) 定义 组合模式(Composite),将对象组合成树形结构以表示“部分-整体”的层次结构.组合模式使得用户对单个对象和组合对象的使用具有一致性.       组合模式有 ...

  9. 《Head First 设计模式》学习笔记——复合模式

    模型-视图-控制器(MVC模式)是一种很经典的软件架构模式.在UI框架和UI设计思路中扮演着很重要的角色.从设计模式的角度来看,MVC模式是一种复合模式.它将多个设计模式在一种解决方式中结合起来,用来 ...

随机推荐

  1. 三.RabbitMQ之异步消息队列(Work Queue)

    上一篇文章简要介绍了RabbitMQ的基本知识点,并且写了一个简单的发送和接收消息的demo.这一篇文章继续介绍关于Work Queue(工作队列)方面的知识点,用于实现多个工作进程的分发式任务. 一 ...

  2. 随聊——Python的前世今生

    1989年圣诞节前夕,山雨欲来风满楼,计算机程序设计语言界隐隐有大事要发生,果然不出所料.江湖人称龟叔(Guido von Rossum),就是这位祖籍荷兰的大能,在圣诞节百无聊赖的期间,发明了Pyt ...

  3. Android开发——导入github安卓项目源码

    之前在Github上看见其他人的安卓项目源码,便是想下载源码来学习学习,但是下载之后一直导入失败,经过了漫长的摸索终于是成功了,便是分享一下经验 首先进入Github官网,找到想要学习的安卓源码 右上 ...

  4. (五):C++分布式实时应用框架——支撑复杂的业务通讯关系

    C++分布式实时应用框架--支撑复杂的业务通讯关系 技术交流合作QQ群:436466587 欢迎讨论交流 版权声明:本文版权及所用技术归属smartguys团队所有,对于抄袭,非经同意转载等行为保留法 ...

  5. iOS PickerView选择视图

    原文demo: @interface ViewController ()<UIPickerViewDelegate,UIPickerViewDataSource> { UIPickerVi ...

  6. 关于C++函数返回局部对象的详细分析

    以前一直挺好奇的,C++是怎么在函数内返回一个局部对象的.因为按照我之前的想法,函数返回一个基本类型的值是通过存放到ecx实现的(关于浮点不了解),但是局部对象又是比较大的,很明显不能使用寄存器作为通 ...

  7. Git 企业开发者教程

      为什么要写这样一个面向企业开发者的Git教程?这个问题也困扰我自己很久.其实我使用git的时间也不短了,但是就和正在阅读本文的每一位一样,常用的基本就是那么几个(git clone, git pu ...

  8. nova创建虚拟机源码系列分析之二 wsgi模型

    openstack nova启动时首先通过命令行或者dashborad填写创建信息,然后通过restful api的方式调用openstack服务去创建虚拟机.数据信息从客户端到达openstack服 ...

  9. 用vue实现简单分页

    在这个demo中,我用vue对一个json文件中的数据进行了简单的分页,没用用到交互,一下是我的实现过程. 基础逻辑 1.将json文件引入app.vue,并作为data返回 data(){ var ...

  10. 用python在excel中读取与生成随机数写入excel中

    今天是我第一次发博客,就关于python在excel中的应用作为我的第一篇吧. 具体要求是:在一份已知的excel表格中读取学生的学号与姓名,再将这些数据放到新的excel表中的第一列与第二列,最后再 ...