C#设计模式之8-组合模式
组合模式(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-组合模式的更多相关文章
- java23种设计模式——八、组合模式
目录 java23种设计模式-- 一.设计模式介绍 java23种设计模式-- 二.单例模式 java23种设计模式--三.工厂模式 java23种设计模式--四.原型模式 java23种设计模式-- ...
- [设计模式] javascript 之 组合模式
组合模式说明 组合模式用于简单化,一致化对单组件和复合组件的使用:其实它就是一棵树: 这棵树有且只有一个根,访问入口,如果它不是一棵空树,那么由一个或几个树枝节点以及子叶节点组成,每个树枝节点还包含自 ...
- 设计模式学习之组合模式(Composite,结构型模式)(10)
转载地址:http://www.cnblogs.com/zhili/p/CompositePattern.html 一.引言 在软件开发过程中,我们经常会遇到处理简单对象和复合对象的情况,例如对操作系 ...
- 设计模式之:组合模式(Composite)
支持原创:http://blog.csdn.net/hguisu/article/details/7530783 设计模式(七)组合模式Composite(结构型) 1. 概述 在数据结构里面,树结构 ...
- [js高手之路]设计模式系列课程-组合模式+寄生组合继承实战新闻列表
所谓组合模式,就是把一堆结构分解出来,组成在一起,现实中很多这样的例子,如: 1.肯德基套餐就是一种组合模式, 比如鸡腿堡套餐,一般是是由一个鸡腿堡,一包薯条,一杯可乐等组成的 2.组装的台式机同理, ...
- C#设计模式之十组合模式(Composite)【结构型】
一.引言 今天我们要讲[结构型]设计模式的第四个模式,该模式是[组合模式],英文名称是:Composite Pattern.当我们谈到这个模式的时候,有一个物件和这个模式很像,也符合这个模式要表达 ...
- 设计模式学习心得<组合模式 Composite>
组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象.组合模式依据树形结构来组合对象,用来表示部分以及整体层次.这种类型的设计模式属于结构型模式, ...
- C#设计模式之九组合模式(Composite Pattern)【结构型】
一.引言 今天我们要讲[结构型]设计模式的第四个模式,该模式是[组合模式],英文名称是:Composite Pattern.当我们谈到这个模式的时候,有一个物件和这个模式很像,也符合这个模式要表达的意 ...
- Java设计模式学习记录-组合模式
前言 今天要介绍的设计模式是组合模式,组合模式也是结构型设计模式的一种,它主要体现了整体与部分的关系,其典型的应用就是树形结构.组合是一组对象,其中的对象可能包含一个其他对象,也可能包含一组其他对象. ...
- java设计模式-----13、组合模式
Composite模式也叫组合模式,是构造型的设计模式之一.通过递归手段来构造树形的对象结构,并可以通过一个对象来访问整个对象树. 组合(Composite)模式的其它翻译名称也很多,比如合成模式.树 ...
随机推荐
- Flink之对时间的处理
window+trigger+watermark处理全局乱序数据,指定窗口上的allowedLateness可以处理特定窗口操作的局部事件时间乱序数据 1.流处理系统中的微批 Flink内部也使用了某 ...
- java中同步异步阻塞和非阻塞的区别
同步 所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回. 按照这个定义,其实绝大多数函数都是同步调用(例如sin, isdigit等).但是一般而言,我们在说同步.异步的时候,特 ...
- Python Ethical Hacking - ARP Spoofing
Typical Network ARP Spoofing Why ARP Spoofing is possible: 1. Clients accept responses even if they ...
- X-Tag实战:给博客加一个隐藏侧栏的功能
X-Tag是什么? X-Tag是一个库,这个库可以让你用面向对象的方式定义自定义标签并给与其功能,很适合用来写一些网页小组件. xtag.create('x-clock', class extends ...
- php必须掌握的常用函数
数学函数 数组函数 字符串函数
- MySQL(二)表的操作与简单数据操作
六大约束:主键约束.外键约束.非空约束.唯一约束.默认约束.自动增加 1.not null非空 2.defaul默认值,用于保证该字段的默认值 ; 比如年龄:1900-10-10 3.primar k ...
- Java 继承与抽象类
一.继承 1.概念 在Java中,类的继承是指在一个现有类的基础上去构建一个新的类,构建出来的新类被称作子类,现有类被称作父类,子类会自动拥有父类所有可继承的属性和方法. 2.继承的格式&使用 ...
- LQB201803乘积尾零
果然是练思维呀!!要是我的话估计就能挨个算一算呜呜呜 分解成 2和5相乘的式子 #include <iostream> using namespace std; //快速幂运算 int m ...
- Django学习路9_流程复习
以下图示为 学习过程中,在千锋教育视频上截图的 视频链接: https://www.bilibili.com/video/BV1rx411X717?p=11 2 ...
- 使用SQL实现数据操作
SQL和RDBMS的区别:用SQL操作RDBMS 一.数据的完整性 一个汉字占多少长度与编码有关: UTF-8:一个汉字=3个字节 GBK:一个汉字=2个字节 二.数据库基本操作 1. 登录数据库 首 ...