一、引言
今天我们要讲【结构型】设计模式的第四个模式,该模式是【组合模式】,英文名称是:Composite Pattern。当我们谈到这个模式的时候,有一个物件和这个模式很像,也符合这个模式要表达的意思,那就是“俄罗斯套娃”。“俄罗斯套娃”就是大的瓷器娃娃里面装着一个小的瓷器娃娃,小的瓷器娃娃里面再装着更小的瓷器娃娃,直到最后一个不能再装更小的瓷器娃娃的那个瓷器娃娃为止(有点绕,下面我会配图,一看就明白)。在我们的操作系统中有文件夹的概念,文件夹可以包含文件夹,可以嵌套多层,最里面包含的是文件,这个概念和“俄罗斯套娃”很像。当然还有很多的例子,例如我们使用系统的时候,会使用到“系统菜单”,这个东西是树形结构。这些例子包含的这些东西或者说是对象,可以分为两类,一类是:容器对象,可以包含其他的子对象;另一类是:叶子对象,这类对象是不能在包含其他对象的对象了。在软件设计中,我们该怎么处理这种情况呢?是每类对象分别对待,还是提供一个统一的操作方式呢。组合模式给我们提供了一种解决此类问题的一个途径,接下来我们就好好的介绍一下“组合模式”吧。
![](https://images2017.cnblogs.com/blog/1048776/201710/1048776-20171027143412867-974161708.png)
1 namespace 透明式的组合模式的实现 2 { 3 ///4 /// 该抽象类就是文件夹抽象接口的定义,该类型就相当于是抽象构件Component类型 5 /// 6 public abstract class Folder 7 { 8 //增加文件夹或文件 9 public abstract void Add(Folder folder);10 11 //删除文件夹或者文件12 public abstract void Remove(Folder folder);13 14 //打开文件或者文件夹--该操作相当于Component类型的Operation方法15 public abstract void Open();16 }17 18 ///19 /// 该Word文档类就是叶子构件的定义,该类型就相当于是Leaf类型,不能在包含子对象20 /// 21 public sealed class Word : Folder22 {23 //增加文件夹或文件24 public override void Add(Folder folder)25 {26 throw new Exception("Word文档不具有该功能");27 }28 29 //删除文件夹或者文件30 public override void Remove(Folder folder)31 {32 throw new Exception("Word文档不具有该功能");33 }34 35 //打开文件--该操作相当于Component类型的Operation方法36 public override void Open()37 {38 Console.WriteLine("打开Word文档,开始进行编辑");39 }40 }41 42 ///43 /// SonFolder类型就是树枝构件,由于我们使用的是“透明式”,所以Add,Remove都是从Folder类型继承下来的44 /// 45 public class SonFolder : Folder46 {47 //增加文件夹或文件48 public override void Add(Folder folder)49 {50 Console.WriteLine("文件或者文件夹已经增加成功");51 }52 53 //删除文件夹或者文件54 public override void Remove(Folder folder)55 {56 Console.WriteLine("文件或者文件夹已经删除成功");57 }58 59 //打开文件夹--该操作相当于Component类型的Operation方法60 public override void Open()61 {62 Console.WriteLine("已经打开当前文件夹");63 }64 }65 66 public class Program67 {68 static void Main()69 {70 71 Folder myword = new Word();72 73 myword.Open();//打开文件,处理文件74 75 myword.Add(new SonFolder());//抛出异常76 myword.Remove(new SonFolder());//抛出异常77 78 79 Folder myfolder = new SonFolder();80 myfolder.Open();//打开文件夹81 82 myfolder.Add(new SonFolder());//成功增加文件或者文件夹83 myfolder.Remove(new SonFolder());//成功删除文件或者文件夹84 85 Console.Read();86 }87 }88 }
1 namespace 安全式的组合模式的实现 2 { 3 ///4 /// 该抽象类就是文件夹抽象接口的定义,该类型就相当于是抽象构件Component类型 5 /// 6 public abstract class Folder //该类型少了容器对象管理子对象的方法的定义,换了地方,在树枝构件也就是SonFolder类型 7 { 8 //打开文件或者文件夹--该操作相当于Component类型的Operation方法 9 public abstract void Open();10 }11 12 ///13 /// 该Word文档类就是叶子构件的定义,该类型就相当于是Leaf类型,不能在包含子对象14 /// 15 public sealed class Word : Folder //这类型现在很干净16 {17 //打开文件--该操作相当于Component类型的Operation方法18 public override void Open()19 {20 Console.WriteLine("打开Word文档,开始进行编辑");21 }22 }23 24 ///25 /// SonFolder类型就是树枝构件,现在由于我们使用的是“安全式”,所以Add,Remove都是从此处开始定义的26 /// 27 public abstract class SonFolder : Folder //这里可以是抽象接口,可以自己根据自己的情况而定28 {29 //增加文件夹或文件30 public abstract void Add(Folder folder);31 32 //删除文件夹或者文件33 public abstract void Remove(Folder folder);34 35 //打开文件夹--该操作相当于Component类型的Operation方法36 public override void Open()37 {38 Console.WriteLine("已经打开当前文件夹");39 }40 }41 42 ///43 /// NextFolder类型就是树枝构件的实现类44 /// 45 public sealed class NextFolder : SonFolder46 {47 //增加文件夹或文件48 public override void Add(Folder folder)49 {50 Console.WriteLine("文件或者文件夹已经增加成功");51 }52 53 //删除文件夹或者文件54 public override void Remove(Folder folder)55 {56 Console.WriteLine("文件或者文件夹已经删除成功");57 }58 59 //打开文件夹--该操作相当于Component类型的Operation方法60 public override void Open()61 {62 Console.WriteLine("已经打开当前文件夹");63 }64 }65 66 public class Program67 {68 static void Main()69 {70 //这是安全的组合模式71 Folder myword = new Word();72 73 myword.Open();//打开文件,处理文件74 75 76 Folder myfolder = new NextFolder();77 myfolder.Open();//打开文件夹78 79 //此处要是用增加和删除功能,需要转型的操作,否则不能使用80 ((SonFolder)myfolder).Add(new NextFolder());//成功增加文件或者文件夹81 ((SonFolder)myfolder).Remove(new NextFolder());//成功删除文件或者文件夹82 83 Console.Read();84 }85 }86 }