组合模式(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. oop的三种设计模式(单例、工厂、策略)

    参考网站 单例模式: 废话不多说,我们直接上代码: <?php /** 三私一公 *私有的静态属性:保存类的单例 *私有的__construct():阻止在类的外部实例化 *私有的__clone ...

  2. Event-Driven Architecture思考

    什么是Event? An event represents a fact, something happened; and it is immutab. 事件代表着事实,代表着过去发生的某件事情,是不 ...

  3. TeamX

    介绍 TeamX 是基于 SolonJT 平台构建的团队管理小工具,主要功能有: Wiki(团队词条,用于写MD格式接口文档也行...) Planned(项目计划 和 个人日志) Issues(问题管 ...

  4. Spring框架零基础学习(一):IOC|DI、AOP

    文章目录 一.IDEA创建Spring项目 二.Spring: IOC和DI 三.Spring: AOP 参考链接: HOW2J.CN:Spring idea创建一个spring项目 一.IDEA创建 ...

  5. 用x种方式求第n项斐波那契数,99%的人只会第一种

    大家好啊,我们又见面了.听说有人想学数据结构与算法却不知道从何下手?那你就认真看完本篇文章,或许能从中找到方法与技巧.     本期我们就从斐波那契数列的几种解法入手,感受算法的强大与奥妙吧. 原文链 ...

  6. python-闭包和装饰器-01-闭包(closure)

    闭包(closure) 闭包就是在一个函数定义的内部再定义一个函数,并且这个函数用到了外边函数的变量,那么将这个函数以及用到的一些变量称之为闭包,如: def line(a, b): def cal( ...

  7. vue学习(三) v-bind指令

    //html <div id="app"> <input type="button" value="ok" v-bind: ...

  8. 【Vue组件通信】props、$ref、$emit,组件传值

    1.什么是组件通信 组件间如何通信,也就成为了vue中重点知识,组件通信,涉及到组件之间数据的传递.类似NET POST/GET参数传递. Vue基本的三种传递方式** (props.\(ref.\) ...

  9. C#怎么统计网站当前在线人数

    1.问题背景 c#网站怎么合理的统计在线人数?我想通过全局变量来统计软件的使用情况,当启动软件时向服务器的用户表写开始使用时间,正常退出时写一个结束使用时间,来统计用户的在线使用情况. 但是有一个问题 ...

  10. PDOStatement::rowCount

    PDOStatement::rowCount — 返回受上一个 SQL 语句影响的行数(PHP 5 >= 5.1.0, PECL pdo >= 0.1.0)高佣联盟 www.cgewang ...