C#设计模式(八)组合模式
来源:互联网 发布:适合打lol的鼠标 知乎 编辑:程序博客网 时间:2024/06/08 06:15
一、引言
在软件开发过程中,我们经常会遇到处理简单对象和复合对象的情况,例如对操作系统中目录的处理就是这样的一个例子,因为目录可以包括单独的文件,也可以包括文件夹,文件夹又是由文件组成的,由于简单对象和复合对象在功能上区别,导致在操作过程中必须区分简单对象和复合对象,这样就会导致客户调用带来不必要的麻烦,然而作为客户,它们希望能够始终一致地对待简单对象和复合对象。然而组合模式就是解决这样的问题。下面让我们看看组合模式是怎样解决这个问题的。
二、组合模式的详细介绍
2.1 组合模式的定义
组合模式允许你将对象组合成树形结构来表现”部分-整体“的层次结构,使得客户以一致的方式处理单个对象以及对象的组合。下面我们用绘制的例子来详细介绍组合模式,图形可以由一些基本图形元素组成(如直线,圆等),也可以由一些复杂图形组成(由基本图形元素组合而成),为了使客户对基本图形和复杂图形的调用保持一致,我们使用组合模式来达到整个目的。
组合模式实现的最关键的地方是——简单对象和复合对象必须实现相同的接口。这就是组合模式能够将组合对象和简单对象进行一致处理的原因。
2.2 组合模式的实现
介绍完组合模式的定义之后,让我们以图形的例子来实现组合模式,具体代码如下:
class Program { static void Main(string[] args) { ComplexGraphic complexGraphics = new ComplexGraphic("一个复杂图形和一个线段"); ComplexGraphic CompositeCG = new ComplexGraphic("两个线段"); CompositeCG.Add(new line("第一个线段")); CompositeCG.Add(new line("第二个线段")); complexGraphics.Add(CompositeCG); line l = new line("线段C"); complexGraphics.Add(l); complexGraphics.Draw();//得到结果:画第一个线段 //画第二个线段 l.Add(new line("l2"));//dram的时候throw一个execption Console.ReadLine(); } /// <summary> /// 图形抽象类, /// </summary> public abstract class Graphics { public string Name { get; set; } public Graphics(string name) { this.Name = name; } public abstract void Draw(); public abstract void Add(Graphics g); public abstract void Remove(Graphics g); } /// <summary> /// 简单图形类——线 /// </summary> public class line : Graphics { public line(string name) : base(name) { } public override void Draw() { Console.WriteLine("画"+Name); } public override void Remove(Graphics g) { throw new Exception("简单图形line不能删除其他图形"); } public override void Add(Graphics g) { throw new Exception("简单图形line不能添加其他图形"); } } /// <summary> /// 复杂图形,由一些简单图形组成 /// </summary> public class ComplexGraphic : Graphics { private List<Graphics> complexGraphicsList = new List<Graphics>(); public ComplexGraphic(string name) : base(name) { } public override void Add(Graphics g) { complexGraphicsList.Add(g); } public override void Remove(Graphics g) { complexGraphicsList.Remove(g); } public override void Draw() { foreach (Graphics g in complexGraphicsList) { g.Draw(); } } } }由于基本图形对象不存在Add和Remove方法,上面实现中直接通过抛出一个异常的方式来解决这样的问题的,但是我们想以一种更安全的方式来解决——因为基本图形根本不存在这样的方法,我们是不是可以移除这些方法呢?为了移除这些方法,我们就不得不修改Graphics接口,我们把管理子对象的方法声明放在复合图形对象里面,这样简单对象Line、Circle使用这些方法时在编译时就会出错,这样的一种实现方式我们称为安全式的组合模式,然而上面的实现方式称为透明式的组合模式,下面让我们看看安全式的组合模式又是怎样实现的,具体实现代码如下:
class Program {/// 安全式的组合模式 /// 此方式实现的组合模式把管理子对象的方法声明在树枝构件ComplexGraphics类中 /// 这样如果叶子节点Line、Circle使用了Add或Remove方法时,就能在编译期间出现错误 /// 但这种方式虽然解决了透明式组合模式的问题,但是它使得叶子节点和树枝构件具有不一样的接口。 /// 所以这两种方式实现的组合模式各有优缺点,具体使用哪个,可以根据问题的实际情况而定 static void Main(string[] args) { ComplexGraphics complexGraphics = new ComplexGraphics("一个复杂图形和一个线段"); ComplexGraphics CompositeCG = new ComplexGraphics("两个线段"); CompositeCG.Add(new Line("第一个线段")); CompositeCG.Add(new Line("第二个线段")); complexGraphics.Add(CompositeCG); Line l = new Line("线段C"); complexGraphics.Add(l); complexGraphics.Draw();//得到结果:画第一个线段 Console.ReadLine(); } /// <summary> /// 图形抽象类, /// </summary> public abstract class Graphics { public string Name { get; set; } public Graphics(string name) { this.Name = name; } public abstract void Draw(); // 移除了Add和Remove方法 // 把管理子对象的方法放到了ComplexGraphics类中进行管理 // 因为这些方法只在复杂图形中才有意义 } /// <summary> /// 简单图形类——线 /// </summary> public class Line : Graphics { public Line(string name) : base(name) { } // 重写父类抽象方法 public override void Draw() { Console.WriteLine("画 " + Name); } } /// <summary> /// 简单图形类——圆 /// </summary> public class Circle : Graphics { public Circle(string name) : base(name) { } // 重写父类抽象方法 public override void Draw() { Console.WriteLine("画 " + Name); } } /// <summary> /// 复杂图形,由一些简单图形组成,这里假设该复杂图形由一个圆两条线组成的复杂图形 /// </summary> public class ComplexGraphics : Graphics { private List<Graphics> complexGraphicsList = new List<Graphics>(); public ComplexGraphics(string name) : base(name) { } /// <summary> /// 复杂图形的画法 /// </summary> public override void Draw() { foreach (Graphics g in complexGraphicsList) { g.Draw(); } } public void Add(Graphics g) { complexGraphicsList.Add(g); } public void Remove(Graphics g) { complexGraphicsList.Remove(g); } }
三、组合模式的优缺点
优点:
- 组合模式使得客户端代码可以一致地处理对象和对象容器,无需关系处理的单个对象,还是组合的对象容器。
- 将”客户代码与复杂的对象容器结构“解耦。
- 可以更容易地往组合对象中加入新的构件。
缺点:使得设计更加复杂。客户端需要花更多时间理清类之间的层次关系。(这个是几乎所有设计模式所面临的问题)。
0 0
- C#设计模式(八)组合模式
- 设计模式笔记(八)--迭代器模式、组合模式
- 设计模式(八)之 Composite(组合)
- 【C#设计模式-组合模式】
- 设计模式之(八)--组合模式(composite)
- 组合模式(composite)-设计模式(八)
- 设计模式(八)之Composite - 组合模式
- 设计模式之(八)组合模式Composite
- JAVA设计模式(八)----组合模式
- C#设计模式之组合
- C++设计模式之八:Composite(组合)
- c#设计模式之组合模式(composition pattern)
- 深入浅出学习设计模式(C#实现)-组合模式
- C#设计模式之组合模式(Composite Pattern)
- C#设计模式08-组合模式
- C#设计模式—组合模式
- 设计模式(八):组合模式Composite(结构型模式)
- java 设计模式学习笔记八 composite组合模式
- LeetCode-Word Search
- ESQL之事务
- 究竟到哪里寻找OpenGL3.X开发库!!!
- * Subsets - Leetcode
- LeetCode 题解(71): Palindrome Number
- C#设计模式(八)组合模式
- 25款实用的桌面版博客编辑器
- Advanced Installer 11.0实战教程
- 两个netfilter的例子
- 7 Support vector machine(2)
- unity3d shader之Julia集和Mandelbrot集绘制美丽图案 (二)
- spark 案例集群测试整理
- MyEclipse 2014 GA Windows版下载地址
- hdoj 1172 猜数字(暴力)