组合模式(Composite Pattern)

该文章的最新版本已迁移至个人博客【比特飞】,单击链接 https://www.byteflying.com/archives/403 访问。

组合模式属于结构型模式,将对象组合成树形结构以表示“部分-整体”的层次结构,组合模式使得用户对单个对象和组合对象的使用具有一致性。

组合模式有时候又叫做部分-整体模式,它使我们树型结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以像处理简单元素一样来处理复杂元素,从而使得客户程序与复杂元素的内部结构解耦。

角色:

1、抽象构件(Component )

它是所有叶子构件和容器构件的共同父类,里面声明了叶子构件和容器构件的所有方法;

2、叶子构件(Leaf)

在组合中表示叶子结点对象,叶子结点没有子结点,对于从父类中继承过来的容器构件的方法,由于它不能实现,可以抛出异常;

3、容器构件(Composite)

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

示例:

命名空间CompositePattern包含文件系统FileSystem基类充当抽象构件类,文件File类充当叶子构件,文件夹Folder类充当容器构件,文件无效操作FileInvalidException 类进行异常处理。本案例尝试通过一个简单的文件系统来向大家阐述组合模式在调用方使用一致性方面的表现。

namespace CompositePattern
public abstract class FileSystem {

    protected string _name = null;

    protected const char SPLIT_CHAR_FILE = ' ';

    protected const char SPLIT_CHAR_DIR = '▼';

    public FileSystem(string name) {
this._name = name;
} public abstract FileSystem Attach(FileSystem component); public abstract FileSystem Detach(FileSystem component); public abstract void Print(int depth = 0); }

抽象构件,文件系统FileSystem类。

public class File : FileSystem {

    public File(string name) : base(name) {

    }

    public override FileSystem Attach(FileSystem component) {
throw new FileInvalidException(
"You can not attach a component in a file!");
} public override FileSystem Detach(FileSystem component) {
throw new FileInvalidException(
"You can not detach a component from a file!");
} public override void Print(int depth = 0) {
Console.WriteLine(new string(SPLIT_CHAR_FILE, depth) + _name);
} }

叶子构件,文件File类。

public class Folder : FileSystem {

    private List<FileSystem> _childrens = null;

    public Folder(string name) : base(name) {
_childrens = new List<FileSystem>();
} public override FileSystem Attach(FileSystem component) {
_childrens.Add(component);
return this;
} public override FileSystem Detach(FileSystem component) {
_childrens.Remove(component);
return this;
} public override void Print(int depth = 0) {
Console.WriteLine(new string(SPLIT_CHAR_DIR, depth) + _name);
foreach (var component in _childrens) {
component.Print(depth + 1);
}
} }

容器构件,文件夹Folder类。

public class FileInvalidException : Exception {

    public FileInvalidException(string message) : base(message) {

    }

    public FileInvalidException(string message, Exception innerException)
: base(message, innerException) { } }

无效的文件操作FileInvalidException类进行简单的异常处理。

public class Program {

    public static void Main(string[] args) {
try {
var root = new Folder("Root"); var music = new Folder("My Music");
music.Attach(new File("Heal the world.mp3"))
.Attach(new File("When You Say Nothing At All.mp3"))
.Attach(new File("Long Long Way to Go.mp3"))
.Attach(new File("Beautiful In White.mp3")); var video = new Folder("My Video");
video.Attach(new File("The Shawshank Redemption.avi"))
.Attach(new File("Schindler's List.avi"))
.Attach(new File("Brave Heart.avi")); var png = new File("missing.png");
root.Attach(png)
.Detach(png)
.Detach(png); root.Attach(new File("readme.txt"))
.Attach(new File("index.html"))
.Attach(new File("file.cs"))
.Attach(music)
.Attach(video)
.Print(); png.Attach(new File("error.json")); }
catch (Exception ex) {
Console.WriteLine(ex.Message);
} Console.ReadKey();
} }

以上是调用方的代码,以下是这个案例的输出结果:

Root
readme.txt
index.html
file.cs
▼My Music
Heal the world.mp3
When You Say Nothing At All.mp3
Long Long Way to Go.mp3
Beautiful In White.mp3
▼My Video
The Shawshank Redemption.avi
Schindler's List.avi
Brave Heart.avi
You can not attach a component in a file!

优点:

该文章的最新版本已迁移至个人博客【比特飞】,单击链接 https://www.byteflying.com/archives/403 访问。

1、可以清楚地定义分层次的复杂对象,表示对象的全部或部分层次,使得增加新构件也更容易;

2、客户端调用简单,客户端可以一致的使用组合结构或其中单个对象;

3、定义了包含叶子对象和容器对象的类层次结构,叶子对象可以被组合成更复杂的容器对象,而这个容器对象又可以被组合,这样不断递归下去,可以形成复杂的树形结构;

4、更容易在组合体内加入对象构件,客户端不必因为加入了新的对象构件而更改原有代码。

缺点:

1、使设计变得更加抽象,对象的业务规则如果很复杂,则实现组合模式具有很大挑战性,而且不是所有的方法都与叶子对象子类都有关联;

2、增加新构件时可能会产生一些问题,很难对容器中的构件类型进行限制。

使用场景:

1、你想表示对象的部分-整体层次结构;

2、你希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象;

3、对象的结构是动态的并且复杂程度不一样,但客户需要一致地处理它们。

C#设计模式之8-组合模式的更多相关文章

  1. java23种设计模式——八、组合模式

    目录 java23种设计模式-- 一.设计模式介绍 java23种设计模式-- 二.单例模式 java23种设计模式--三.工厂模式 java23种设计模式--四.原型模式 java23种设计模式-- ...

  2. [设计模式] javascript 之 组合模式

    组合模式说明 组合模式用于简单化,一致化对单组件和复合组件的使用:其实它就是一棵树: 这棵树有且只有一个根,访问入口,如果它不是一棵空树,那么由一个或几个树枝节点以及子叶节点组成,每个树枝节点还包含自 ...

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

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

  4. 设计模式之:组合模式(Composite)

    支持原创:http://blog.csdn.net/hguisu/article/details/7530783 设计模式(七)组合模式Composite(结构型) 1. 概述 在数据结构里面,树结构 ...

  5. [js高手之路]设计模式系列课程-组合模式+寄生组合继承实战新闻列表

    所谓组合模式,就是把一堆结构分解出来,组成在一起,现实中很多这样的例子,如: 1.肯德基套餐就是一种组合模式, 比如鸡腿堡套餐,一般是是由一个鸡腿堡,一包薯条,一杯可乐等组成的 2.组装的台式机同理, ...

  6. C#设计模式之十组合模式(Composite)【结构型】

    一.引言   今天我们要讲[结构型]设计模式的第四个模式,该模式是[组合模式],英文名称是:Composite Pattern.当我们谈到这个模式的时候,有一个物件和这个模式很像,也符合这个模式要表达 ...

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

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

  8. C#设计模式之九组合模式(Composite Pattern)【结构型】

    一.引言 今天我们要讲[结构型]设计模式的第四个模式,该模式是[组合模式],英文名称是:Composite Pattern.当我们谈到这个模式的时候,有一个物件和这个模式很像,也符合这个模式要表达的意 ...

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

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

  10. java设计模式-----13、组合模式

    Composite模式也叫组合模式,是构造型的设计模式之一.通过递归手段来构造树形的对象结构,并可以通过一个对象来访问整个对象树. 组合(Composite)模式的其它翻译名称也很多,比如合成模式.树 ...

随机推荐

  1. Python Ethical Hacking - KEYLOGGER(2)

    Report function: Run in the background. Don't interrupt program execution. Every X seconds, send the ...

  2. 又被逼着优化代码,这次我干掉了出入参 Log日志

    本文收录在个人博客:www.chengxy-nds.top,技术资源共享. 最近技术部突然刮起一阵 review 代码的小风,挨个项目组过代码,按理说这应该是件挺好的事,让别人指出自己代码中的不足,查 ...

  3. create-react-app中的babel配置探索

    版本 babel-loader version:"8.1.0" create-react-app:"3.4.1" 三个配置 第一部分: { test: /\.( ...

  4. WebApi部署多服务器配置Nginx负载均衡

    01PARTCoreWebApi教程本地演示环境 Visual Studio2019 --- Vsersion:16.4.4 + NetCore3.1.2 02PARTNginx快速搭建配置负载均衡 ...

  5. 主机无法访问虚拟机中运行的Django项目

    在虚拟机中的linux上运行了Django项目,虚拟机中可以访问,但外部主机无法访问(连接超时),但主机能ping同虚拟机,虚拟机也能ping通主机 需检查三个地方:(后面发现虚拟机的ip地址存在改变 ...

  6. 从Python开始学编程|PDF百度网盘免费下载|Python新手入门

    百度网盘免费下载:从Python开始学编程|附PDF免费下载 提取码:7nkf 豆瓣评分: 本书封面: 读者评论: 内容简介  · · · · · · 改编自Vamei博客的<Python快速教 ...

  7. 5.pandas新增数据列

    有的时候,表格自带的数据根本没有办法满足我们,我们经常会新加一列数据或者对原有的数据进行修改 还是接着上篇文章的数据进行操作 直接赋值 我想算一下每一天的温差 df.loc[:, 'wencha'] ...

  8. PHP操作Redis步骤详解

    一.Redis连接与认证 $redis = new Redis(); //连接参数:ip.端口.连接超时时间,连接成功返回true,否则返回false $ret = $redis->connec ...

  9. 性能测试必备知识(7)- 深入理解“CPU 使用率”

    做性能测试的必备知识系列,可以看下面链接的文章哦 https://www.cnblogs.com/poloyy/category/1806772.html 回顾 CPU 使用率是单位时间内 CPU 使 ...

  10. 2-Numpy之hstack、vstack、concatenate区别

    concatenate与hstack.vstack的异同点: 都表示拼接数组,concatenate可以实现hstack和vstack的功能,只需要通过调整参数axis的值即可. 其中:v表示垂直(V ...