系列文章

[Head First设计模式]山西面馆中的设计模式——装饰者模式

[Head First设计模式]山西面馆中的设计模式——观察者模式

[Head First设计模式]山西面馆中的设计模式——建造者模式

[Head First设计模式]饺子馆(冬至)中的设计模式——工厂模式

[Head First设计模式]一个人的平安夜——单例模式

[Head First设计模式]抢票中的设计模式——代理模式

[Head First设计模式]面向对象的3特征5原则

[Head First设计模式]鸭子模型——策略模式

[Head First设计模式]云南米线馆中的设计模式——模版方法模式

[Head First设计模式]餐馆中的设计模式——命令模式

[Head First设计模式]身边的设计模式——适配器模式

[Head First设计模式]生活中学设计模式——迭代器模式

引言

比如:复制文件,可以一个一个文件复制粘贴也可以整个文件夹进行复制粘贴。

组合模式

允许你将对象组合成树形结构来表现“整体/部分”层次结构。组合能让客户以一致的方式处理个别对象以及对象组合。

类图

角色

Component:为组合中的对象声明接口。

Leaf:在组合中表示没有子节点的叶节点。

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

适用场景

希望把对象表示成整体-部分层次结构。

希望永固忽略组合对象与单个对象的不同,用户将统一使用组合结构中所有对象。

优点

基本对象可以被组合成更复杂的组合对象,而这个组合对象又可以被组合,这样不断地递归下去。客户代码中,任何用到基本对象的地方都可以使用组合对象。

客户可以一致的使用组合结构和单个对象。这样用户就不必关心处理的是一个叶节点还是一个组合组件。这样就大大简化了客户代码。

新定义的Componnt或Leaf子类自动地与已有的结构和客户代码一起协同工作,客户程序不需要因新的Component类而改变。

缺点

直接使用了实现类,在面向抽象编程上是很不恰当的,与依赖倒置原则冲突。

一个例子

比如oa系统中最常见的组织结构关系:

  1. namespace Wolfy.组合模式
  2. {
  3. /// <summary>
  4. /// 抽象接口类
  5. /// </summary>
  6. public abstract class Company
  7. {
  8. public Company(string name)
  9. { this.Name = name; }
  10. public string Name { get; set; }
  11. public abstract void Add(Company company);
  12. public abstract void Remove(Company company);
  13. public abstract void Display(int depth);
  14. }
  15. }
  1. namespace Wolfy.组合模式
  2. {
  3. /// <summary>
  4. /// 叶节点 子公司 部门类
  5. /// </summary>
  6. public class ConcreteCompany:Company
  7. {
  8. private List<Company> list= new List<Company>();
  9. public ConcreteCompany(string name)
  10. : base(name)
  11. { }
  12. public override void Add(Company company)
  13. {
  14. list.Add(company);
  15. }
  16.  
  17. public override void Remove(Company company)
  18. {
  19. list.Remove(company);
  20. }
  21.  
  22. public override void Display(int depth)
  23. {
  24. StringBuilder sb = new StringBuilder();
  25. for (int i = ; i < depth; i++)
  26. {
  27. sb.Append("-");
  28. }
  29. Console.WriteLine(sb.ToString()+base.Name);
  30. Console.WriteLine();
  31. foreach (Company item in list)
  32. {
  33. item.Display(depth + );
  34. }
  35. }
  36. }
  37. }
  1. namespace Wolfy.组合模式
  2. {
  3. /// <summary>
  4. /// 叶节点类 人事部
  5. /// </summary>
  6. public class HRDepartment:Company
  7. {
  8. public HRDepartment(string name)
  9. : base(name)
  10. { }
  11. public override void Add(Company company)
  12. {
  13. throw new NotImplementedException();
  14. }
  15.  
  16. public override void Remove(Company company)
  17. {
  18. throw new NotImplementedException();
  19. }
  20.  
  21. public override void Display(int depth)
  22. {
  23.  
  24. Console.WriteLine(new String('-', depth) + base.Name);
  25.  
  26. Console.WriteLine();
  27. }
  28. }
  29. }
  1. namespace Wolfy.组合模式
  2. {
  3. /// <summary>
  4. /// 叶节点 财务部
  5. /// </summary>
  6. public class FinanceDepartment:Company
  7. {
  8. public FinanceDepartment(string name) : base(name) { }
  9. public override void Add(Company company)
  10. {
  11. throw new NotImplementedException();
  12. }
  13.  
  14. public override void Remove(Company company)
  15. {
  16. throw new NotImplementedException();
  17. }
  18.  
  19. public override void Display(int depth)
  20. {
  21. Console.WriteLine(new String('-', depth) + base.Name);
  22. Console.WriteLine();
  23. }
  24. }
  25. }
  1. namespace Wolfy.组合模式
  2. {
  3. class Program
  4. {
  5. static void Main(string[] args)
  6. {
  7. Company root = new ConcreteCompany("北京总公司");
  8. root.Add(new HRDepartment("总公司人力资源部"));
  9. root.Add(new FinanceDepartment("总公司财务部"));
  10. Company shandongCom = new ConcreteCompany("山东分公司");
  11. shandongCom.Add(new HRDepartment("山东分公司人力资源部"));
  12. shandongCom.Add(new FinanceDepartment("山东分公司账务部"));
  13. Company zaozhuangCom = new ConcreteCompany("枣庄办事处");
  14. zaozhuangCom.Add(new FinanceDepartment("枣庄办事处财务部"));
  15. zaozhuangCom.Add(new HRDepartment("枣庄办事处人力资源部"));
  16. Company jinanCom = new ConcreteCompany("济南办事处");
  17. jinanCom.Add(new FinanceDepartment("济南办事处财务部"));
  18. jinanCom.Add(new HRDepartment("济南办事处人力资源部"));
  19. shandongCom.Add(jinanCom);
  20. shandongCom.Add(zaozhuangCom);
  21. Company huadongCom = new ConcreteCompany("上海华东分公司");
  22. huadongCom.Add(new HRDepartment("上海华东分公司人力资源部"));
  23. huadongCom.Add(new FinanceDepartment("上海华东分公司账务部"));
  24. Company hangzhouCom = new ConcreteCompany("杭州办事处");
  25. hangzhouCom.Add(new FinanceDepartment("杭州办事处财务部"));
  26. hangzhouCom.Add(new HRDepartment("杭州办事处人力资源部"));
  27. Company nanjingCom = new ConcreteCompany("南京办事处");
  28. nanjingCom.Add(new FinanceDepartment("南京办事处财务部"));
  29. nanjingCom.Add(new HRDepartment("南京办事处人力资源部"));
  30. huadongCom.Add(hangzhouCom);
  31. huadongCom.Add(nanjingCom);
  32. root.Add(shandongCom);
  33. root.Add(zaozhuangCom);
  34. root.Add(jinanCom);
  35. root.Add(huadongCom);
  36. root.Add(hangzhouCom);
  37. root.Add(nanjingCom);
  38. root.Display();
  39. Console.Read();
  40. }
  41. }
  42. }

结果:

总结

优点

基本对象可以被组合成更复杂的组合对象,而这个组合对象又可以被组合,这样不断地递归下去。客户代码中,任何用到基本对象的地方都可以使用组合对象。

客户可以一致的使用组合结构和单个对象。这样用户就不必关心处理的是一个叶节点还是一个组合组件。这样就大大简化了客户代码。

新定义的Componnt或Leaf子类自动地与已有的结构和客户代码一起协同工作,客户程序不需要因新的Component类而改变。

缺点

直接使用了实现类,在面向抽象编程上是很不恰当的,与依赖倒置原则冲突。

参考:

《Head First 设计模式》

百度百科

[Head First设计模式]生活中学设计模式——组合模式的更多相关文章

  1. [Head First设计模式]生活中学设计模式——外观模式

    系列文章 [Head First设计模式]山西面馆中的设计模式——装饰者模式 [Head First设计模式]山西面馆中的设计模式——观察者模式 [Head First设计模式]山西面馆中的设计模式— ...

  2. [Head First设计模式]生活中学设计模式——状态模式

    系列文章 [Head First设计模式]山西面馆中的设计模式——装饰者模式 [Head First设计模式]山西面馆中的设计模式——观察者模式 [Head First设计模式]山西面馆中的设计模式— ...

  3. [Head First设计模式]生活中学设计模式——迭代器模式

    系列文章 [Head First设计模式]山西面馆中的设计模式——装饰者模式 [Head First设计模式]山西面馆中的设计模式——观察者模式 [Head First设计模式]山西面馆中的设计模式— ...

  4. 设计模式(七)组合模式Composite(结构型)

    设计模式(七)组合模式Composite(结构型) 1. 概述 在数据结构里面,树结构是很重要,我们可以把树的结构应用到设计模式里面. 例子1:就是多级树形菜单. 例子2:文件和文件夹目录 2.问题 ...

  5. Java设计模式(8)组合模式(Composite模式)

    Composite定义:将对象以树形结构组织起来,以达成“部分-整体” 的层次结构,使得客户端对单个对象和组合对象的使用具有一致性. Composite比较容易理解,想到Composite就应该想到树 ...

  6. 设计模式(十)组合模式(Composite Pattern)

    一.引言 在软件开发过程中,我们经常会遇到处理简单对象和复合对象的情况,例如对操作系统中目录的处理就是这样的一个例子,因为目录可以包括单独的文件,也可以包括文件夹,文件夹又是由文件组成的,由于简单对象 ...

  7. js设计模式(六)---组合模式

    组合模式将对象组合成树形结构,以表示“部分-整体”的层次结构.除了用来表示树形结构之外,组合模式的另一个好处是通过对象的多态性表现,使得用户对单个对象和组合对象的使用具有一致性.基本图例 1.组合模式 ...

  8. 设计模式08: Composite 组合模式(结构型模式)

    Composite 组合模式(结构型模式) 对象容器的问题在面向对象系统中,我们常会遇到一类具有“容器”特征的对象——即他们在充当对象的同时,又是其他对象的容器. public interface I ...

  9. 设计模式-(11)组合模式 (swift版)

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

随机推荐

  1. linux init 启动顺序

    redhat init大致启动过程 第一个运行的程序是/sbin/init,该文件会读取/etc/inittab文件,并依据此文件来进行初始化工作.比如在设定了运行等级 “:id:3:initdefa ...

  2. AWS S3 CLI的权限bug

    使用AWS CLI在S3上创建了一个bucket,上传文件的时候报以下错误: A client error (AccessDenied) occurred when calling the Creat ...

  3. BZOJ 3524: [Poi2014]Couriers [主席树]

    3524: [Poi2014]Couriers Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 1892  Solved: 683[Submit][St ...

  4. 洛谷10月月赛Round.1| P3398 仓鼠找sugar[LCA]

    题目描述 小仓鼠的和他的基(mei)友(zi)sugar住在地下洞穴中,每个节点的编号为1~n.地下洞穴是一个树形结构.这一天小仓鼠打算从从他的卧室(a)到餐厅(b),而他的基友同时要从他的卧室(c) ...

  5. 第3章 Linux常用命令(4)_帮助、用户管理和解压缩命令

    4. 帮助命令 4.1 获取帮助信息:man (1)man命令 命令名称 man(英语原义:manual) 命令所在路径 usr/bin/man 执行权限 所有用户 语法 man [级别] [命令或配 ...

  6. python-面向对象进阶

    小总结: 面向对象的好处 更容易扩展,提高代码的使用效率,使代码组织性更强.更清晰,更适合复杂项目的开发 封装:把功能的实现细节封装起来,之暴露调用接口  多态:接口的继承 定义:  类  :  模板 ...

  7. ThinkPHP跨控制器调用方法

    跨控制器调用方法 1. 先造对象,再调用里面的方法 $sc=new \Home\Controller\IndexController();  用绝对路径找echo $sc->ShuChu(); ...

  8. PyCharm3.0默认快捷键(翻译的)

    PyCharm3.0默认快捷键(翻译的) PyCharm Default Keymap 1.编辑(Editing) Ctrl + Space    基本的代码完成(类.方法.属性)Ctrl + Alt ...

  9. 学习web前端学习路程

    学习路程: 1.HTML和CSS基础 2.JavaScript语言 3.jQuery 4.综合网站实践 5.优化及调试

  10. 利用CSS计数函数counter()实现计数

    要实现li列表计数比较简单,直接设置list-style-type即可,但是要实现非li列表计数该怎么办呢,counter()可以轻松实现 body{counter-reset:section 0 s ...