[Head First设计模式]生活中学设计模式——组合模式

时间:2023-02-19 19:15:47

系列文章

[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设计模式]生活中学设计模式——迭代器模式

引言

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

组合模式

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

类图

[Head First设计模式]生活中学设计模式——组合模式

角色

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

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

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

适用场景

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

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

优点

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

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

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

缺点

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

一个例子

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

 namespace Wolfy.组合模式
{
/// <summary>
/// 抽象接口类
/// </summary>
public abstract class Company
{
public Company(string name)
{ this.Name = name; }
public string Name { get; set; }
public abstract void Add(Company company);
public abstract void Remove(Company company);
public abstract void Display(int depth);
}
}
 namespace Wolfy.组合模式
{
/// <summary>
/// 叶节点 子公司 部门类
/// </summary>
public class ConcreteCompany:Company
{
private List<Company> list= new List<Company>();
public ConcreteCompany(string name)
: base(name)
{ }
public override void Add(Company company)
{
list.Add(company);
} public override void Remove(Company company)
{
list.Remove(company);
} public override void Display(int depth)
{
StringBuilder sb = new StringBuilder();
for (int i = ; i < depth; i++)
{
sb.Append("-");
}
Console.WriteLine(sb.ToString()+base.Name);
Console.WriteLine();
foreach (Company item in list)
{
item.Display(depth + );
}
}
}
}
 namespace Wolfy.组合模式
{
/// <summary>
/// 叶节点类 人事部
/// </summary>
public class HRDepartment:Company
{
public HRDepartment(string name)
: base(name)
{ }
public override void Add(Company company)
{
throw new NotImplementedException();
} public override void Remove(Company company)
{
throw new NotImplementedException();
} public override void Display(int depth)
{ Console.WriteLine(new String('-', depth) + base.Name); Console.WriteLine();
}
}
}
 namespace Wolfy.组合模式
{
/// <summary>
/// 叶节点 财务部
/// </summary>
public class FinanceDepartment:Company
{
public FinanceDepartment(string name) : base(name) { }
public override void Add(Company company)
{
throw new NotImplementedException();
} public override void Remove(Company company)
{
throw new NotImplementedException();
} public override void Display(int depth)
{
Console.WriteLine(new String('-', depth) + base.Name);
Console.WriteLine();
}
}
}
 namespace Wolfy.组合模式
{
class Program
{
static void Main(string[] args)
{
Company root = new ConcreteCompany("北京总公司");
root.Add(new HRDepartment("总公司人力资源部"));
root.Add(new FinanceDepartment("总公司财务部"));
Company shandongCom = new ConcreteCompany("山东分公司");
shandongCom.Add(new HRDepartment("山东分公司人力资源部"));
shandongCom.Add(new FinanceDepartment("山东分公司账务部"));
Company zaozhuangCom = new ConcreteCompany("枣庄办事处");
zaozhuangCom.Add(new FinanceDepartment("枣庄办事处财务部"));
zaozhuangCom.Add(new HRDepartment("枣庄办事处人力资源部"));
Company jinanCom = new ConcreteCompany("济南办事处");
jinanCom.Add(new FinanceDepartment("济南办事处财务部"));
jinanCom.Add(new HRDepartment("济南办事处人力资源部"));
shandongCom.Add(jinanCom);
shandongCom.Add(zaozhuangCom);
Company huadongCom = new ConcreteCompany("上海华东分公司");
huadongCom.Add(new HRDepartment("上海华东分公司人力资源部"));
huadongCom.Add(new FinanceDepartment("上海华东分公司账务部"));
Company hangzhouCom = new ConcreteCompany("杭州办事处");
hangzhouCom.Add(new FinanceDepartment("杭州办事处财务部"));
hangzhouCom.Add(new HRDepartment("杭州办事处人力资源部"));
Company nanjingCom = new ConcreteCompany("南京办事处");
nanjingCom.Add(new FinanceDepartment("南京办事处财务部"));
nanjingCom.Add(new HRDepartment("南京办事处人力资源部"));
huadongCom.Add(hangzhouCom);
huadongCom.Add(nanjingCom);
root.Add(shandongCom);
root.Add(zaozhuangCom);
root.Add(jinanCom);
root.Add(huadongCom);
root.Add(hangzhouCom);
root.Add(nanjingCom);
root.Display();
Console.Read();
}
}
}

结果:

[Head First设计模式]生活中学设计模式——组合模式

总结

优点

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

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

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

缺点

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

参考:

《Head First 设计模式》

百度百科

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

  1. &lbrack;Head First设计模式&rsqb;生活中学设计模式——外观模式

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

  2. &lbrack;Head First设计模式&rsqb;生活中学设计模式——状态模式

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

  3. &lbrack;Head First设计模式&rsqb;生活中学设计模式——迭代器模式

    系列文章 [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. &lbrack;转&rsqb;mysql drop、truncate和delete比较

    一.drop table tb drop将表格直接删除,没有办法找回. 立刻释放磁盘空间 ,不管是 Innodb和MyISAM . 二.truncate (table) tb 该命令可以清空一个表里的 ...

  2. Codeforces Round &num;157 &lpar;Div&period; 2&rpar; D&period; Little Elephant and Elections&lpar;数位DP&plus;枚举&rpar;

    数位DP部分,不是很难.DP[i][j]前i位j个幸运数的个数.枚举写的有点搓... #include <cstdio> #include <cstring> using na ...

  3. VBA中的FileSystemObject对象&lpar;FSO&rpar;和文本流

    对FileSystemObject一直略有耳闻,VBA爱好者常常简称为FSO对象. 在Scripting类库中有三个可以直接使用NEW关键字实例化的类,第一个就是常用的字典,第三个是FSO. 一.FS ...

  4. &lbrack;TPYBoard - Micropython&rsqb; 五分种学会用TPYBoard - GPS 制作短信群发机

    转载请注明:@小五义 http://www.cnblogs.com/xiao* 欢迎加入讨论群 64770604   一.什么是TPYBoard-GPS TPYBoard-GPS又称TPYBoa ...

  5. swiper结合ajax的轮播图

    Swiper 是什么:是纯JavaScript打造的滑动特效插件,能够实现触屏焦点图.触屏tab切换.触屏多图切换等常用效果. 开源.免费.稳定.应用广泛. 这就是swiper简单的介绍,由于是结合a ...

  6. Effective C&plus;&plus; 读书笔记(1-7)

    作者 Scott Meyers  翻译作者 侯捷 C++ 神牛 *人 术语: 1.explicit C++提供了关键字explicit,可以阻止不应该允许的经过转换构造函数进行的隐式转换的发生.声明 ...

  7. 从零开始学Kotlin-泛型(8)

    从零开始学Kotlin基础篇系列文章 与 Java 一样,Kotlin 也提供泛型,为类型安全提供保证,消除类型强转的烦恼. 泛型类的基本使用 泛型,即 "参数化类型",将类型参数 ...

  8. Unity5 AssetBundle打包加载及服务器加载

    Assetbundle为资源包不是资源 打包1:通过脚本指定打包 AssetBundleBuild ab = new AssetBundleBuild                         ...

  9. mysql主从怎么样使主为innodb辅为myisam

    MySQL主从复制(linux主+windows从) http://blog.csdn.net/qq_20032995/article/details/54380290 mysql主从怎么样使主为in ...

  10. JS中event&period;preventDefault&lpar;&rpar;取消默认事件能否还原?

    参考知乎讨论:https://www.zhihu.com/question/21891734