标签:bst 新建 忽略 [] 缺点 cep lis 树形结构 编译
一、组合模式介绍:
组合模式解耦了客户程序与复杂元素内部结构,从而使客户程序可以向处理简单元素一样来处理复杂元素。允许你将对象组合成树形结构来表现”部分-整体“的层次结构,使得客户以一致的方式处理单个对象以及对象的组合。组合模式实现的最关键的地方是——简单对象和复合对象必须实现相同的接口。
二、设计背景:
在软件开发过程中,我们经常会遇到处理简单对象和复合对象的情况,例如对操作系统中目录的处理就是这样的一个例子,因为目录可以包括单独的文件(例如word、txt、excel),也可以包括文件夹,文件夹又是由文件组成的,由于简单对象和复合对象在功能上区别,导致在操作过程中必须区分简单对象和复合对象,这样就会导致客户调用带来不必要的麻烦,然而作为客户,它们希望能够始终一致地对待简单对象和复合对象,然而组合模式就是解决这样的问题。下面就让我们以这个例子来看看组合模式的实现。
三、相关代码:
1、创建文件抽象类
///
/// 文件抽象类
///
public abstract class File
{
public string Name { get; set; }
public File(string name)
{
this.Name = name;
}
public abstract void New();
public abstract void AddFile(File file);
public abstract void DeleteFile(File file);
}
2、创建具体简单对象类(简单对象):Word文档类和Excel文档类
///
/// 具体简单对象类——Word文档文件
///
public class Word : File
{
public Word(string name) : base(name)
{
}
public override void New()
{
Console.WriteLine("新建Word文档:" + Name);
}
//因为文件是目录的最小单位,文件下无法创建文件,所以简单对象Word文档文件类里面的AddFolder和RemoveFolder方法没有意义
public override void AddFile(File file)
{
throw new Exception("不能向Word文件创建文件");
}
public override void DeleteFile(File file)
{
throw new Exception("不能向Word文件删除文件");
}
}
///
/// 具体简单对象类——Excel文档文件
///
public class Excel : File
{
public Excel(string name) : base(name)
{
}
public override void New()
{
Console.WriteLine("新建Excel文档:" + Name);
}
public override void AddFile(File file)
{
throw new Exception("不能向Excel文件创建文件");
}
public override void DeleteFile(File file)
{
throw new Exception("不能向Excel文件删除文件");
}
}
3、创建文件夹类(复合对象):
///
/// 文件夹类,由一些文件组成
///
public class Folder : File
{
private List file_list = new List();
public Folder(string name) : base(name)
{
}
///
/// 文件夹创建各种文件
///
public override void New()
{
foreach (var item in file_list)
{
item.New();
}
}
public override void AddFile(File file)
{
file_list.Add(file);
}
public override void DeleteFile(File file)
{
file_list.Remove(file);
}
}
4、调用
static void Main(string[] args)
{
Folder folder = new Folder("一个文件夹和一个Word文档组成的文件夹");
folder.AddFile(new Word("我是Word文档1"));
Folder folder2 = new Folder("一个Word文档和一个Excel文档组成的文件夹");
folder2.AddFile(new Word("我是Word文档2"));
folder2.AddFile(new Excel("我是Excel文档1"));
folder.AddFile(folder2);
Excel excel = new Excel("我是Excel文档2");
folder.AddFile(excel);
//查看文件夹
folder.New();
Console.ReadKey();
//移除一个文件再查看文件夹
folder.DeleteFile(excel);
folder.New();
Console.ReadKey();
}
上面的实现方式称为透明式的组合模式,由于基本文件对象不存在AddFile和DeleteFile方法,上面实现中直接通过抛出一个异常的方式来解决这样的问题的,但是我们想以一种更安全的方式来解决——因为基本文件根本不存在这样的方法,我们是不是可以移除这些方法呢?为了移除这些方法,我们就不得不修改File接口,我们把管理子对象的方法声明放在文件夹对象里面,这样简单对象Word、Excel使用这些方法时在编译时就会出错,这样的一种实现方式我们称为安全式的组合模式。具体代码如下:
///
/// 文件夹类,由一些文件组成
///
public class Folder : File
{
private List file_list = new List();
public Folder(string name) : base(name)
{
}
///
/// 文件夹创建各种文件
///
public override void New()
{
foreach (var item in file_list)
{
item.New();
}
}
public void AddFile(File file)
{
file_list.Add(file);
}
public void DeleteFile(File file)
{
file_list.Remove(file);
}
}
四、组合模式的三个角色:
-
抽象构件(Component)角色:这是一个抽象角色,上面实现中File充当这个角色,在透明式的组合模式里,它给参加组合的对象定义出了公共的接口及默认行为,可以用来管理所有的子对象。在安全式的组合模式里,构件角色并不定义出管理子对象的方法,这一定义由树枝结构对象给出。
-
树叶构件(Leaf)角色:树叶对象时没有下级子对象的对象,上面实现中Word和Excel充当这个角色,定义出参加组合的原始对象的行为
-
树枝构件(Composite)角色:代表参加组合的有下级子对象的对象,上面实现中Folder充当这个角色,树枝对象给出所有管理子对象的方法实现,如AddFile、DeleteFile等。
五、使用场景:
- 需要表示一个对象整体或部分的层次结构。
- 希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。
六、总结:
优点:
- 组合模式使得客户端代码可以一致地处理对象和对象容器,无需关系处理的单个对象,还是组合的对象容器。
- 将”客户代码与复杂的对象容器结构“解耦。
- 可以更容易地往组合对象中加入新的构件。
缺点:
- 使得设计更加复杂。客户端需要花更多时间理清类之间的层次关系。
C#设计模式——组合模式
标签:bst 新建 忽略 [] 缺点 cep lis 树形结构 编译
原文地址:https://www.cnblogs.com/jiechou/p/9127507.html