翼度科技»论坛 编程开发 .net 查看内容

【23种设计模式】组合模式(八)

11

主题

11

帖子

33

积分

新手上路

Rank: 1

积分
33
前言

组合模式,英文名称是:Composite Pattern。当我们谈到这个模式的时候,有一个物件和这个模式很像,也符合这个模式要表达的意思,那就是“俄罗斯套娃”。“俄罗斯套娃”就是大的瓷器娃娃里面装着一个小的瓷器娃娃,小的瓷器娃娃里面再装着更小的瓷器娃娃,直到最后一个不能再装更小的瓷器娃娃的那个瓷器娃娃为止。在我们的操作系统中有文件夹的概念,文件夹可以包含文件夹,可以嵌套多层,最里面包含的是文件,这个概念和“俄罗斯套娃”很像。

组合模式的定义

客户代码过多地依赖于对象容器复杂的内部实现结构,对象容器内部实现结构的变化将引起客户代码的频繁变化,带来了代码的维护性、扩展性等方面的弊端。组合设计模式就是将对象组合成树形结构以表示“部分-整体”的层次结构。Composite使得用户对单个对象和组合对象的使用具有一致性。
组合模式的组成



  • 抽象构件角色(Component):这是个抽象角色,它给参加组合的对象定义出了公共的接口及默认行为,可以用来管理所有的子对象。在安全式的组合模式里,构件角色并不定义出管理子对象的方法,这一定义由树枝结构对象给出。
  • 树叶构件角色(Leaf):树叶对象是没有下级子对象的对象,定义出参加组合的原始对象的行为。(原始对象的行为可以理解为没有容器对象管理子对象的方法,或者 【原始对象行为】+【管理子对象的行为(Add,Remove等)】=面对客户代码的接口行为集合)
  • 树枝构件角色(Composite):代表参加组合的有下级子对象的对象,树枝对象给出所有管理子对象的方法实现,如Add、Remove等。
组合模式的代码实现

组合模式有两种实现方式,一种是:透明式的组合模式,另外一种是:安全式的组合模式。
所谓透明式是指“抽象构件角色”定义的接口行为集合包含两个部分,一部分是叶子对象本身所包含的行为(比如Operation),另外一部分是容器对象本身所包含的管理子对象的行为(Add,Remove)。这个抽象构件必须同时包含这两类对象所有的行为,客户端代码才会透明的使用,无论调用容器对象还是叶子对象,接口方法都是一样的,这就是透明
所谓安全式是指“抽象构件角色”只定义叶子对象的方法,确切的说这个抽象构件只定义两类对象共有的行为,然后容器对象的方法定义在“树枝构件角色”上,这样叶子对象有叶子对象的方法,容器对象有容器对象的方法,这样责任很明确,当然调用肯定不会抛出异常了。
大家可以根据自己的情况自行选择是实现为“透明式”还是“安全式”的,以下我们会针对这两种情况都有实现,具体实现如下:
透明式

代码定义
  1. /// <summary>
  2.     /// Transparent 透明式实现
  3.     /// </summary>
  4.     public class Transparent
  5.     {
  6.         /// <summary>
  7.         /// 该抽象类就是文件夹抽象接口的定义,该类型就相当于是抽象构件Component类型
  8.         /// </summary>
  9.         public abstract class Folder
  10.         {
  11.             //增加文件夹或文件
  12.             public abstract void Add(Folder folder);
  13.             //删除文件夹或者文件
  14.             public abstract void Remove(Folder folder);
  15.             //打开文件或者文件夹--该操作相当于Component类型的Operation方法
  16.             public abstract void Open();
  17.         }
  18.         /// <summary>
  19.         /// 该Word文档类就是叶子构件的定义,该类型就相当于是Leaf类型,不能在包含子对象
  20.         /// </summary>
  21.         public sealed class Word : Folder
  22.         {
  23.             //增加文件夹或文件
  24.             public override void Add(Folder folder)
  25.             {
  26.                 throw new Exception("Word文档不具有该功能");
  27.             }
  28.             //删除文件夹或者文件
  29.             public override void Remove(Folder folder)
  30.             {
  31.                 throw new Exception("Word文档不具有该功能");
  32.             }
  33.             //打开文件--该操作相当于Component类型的Operation方法
  34.             public override void Open()
  35.             {
  36.                 Console.WriteLine("打开Word文档,开始进行编辑");
  37.             }
  38.         }
  39.         /// <summary>
  40.         /// SonFolder类型就是树枝构件,由于我们使用的是“透明式”,所以Add,Remove都是从Folder类型继承下来的
  41.         /// </summary>
  42.         public class SonFolder : Folder
  43.         {
  44.             //增加文件夹或文件
  45.             public override void Add(Folder folder)
  46.             {
  47.                 Console.WriteLine("文件或者文件夹已经增加成功");
  48.             }
  49.             //删除文件夹或者文件
  50.             public override void Remove(Folder folder)
  51.             {
  52.                 Console.WriteLine("文件或者文件夹已经删除成功");
  53.             }
  54.             //打开文件夹--该操作相当于Component类型的Operation方法
  55.             public override void Open()
  56.             {
  57.                 Console.WriteLine("已经打开当前文件夹");
  58.             }
  59.         }
  60.     }
复制代码
调用实现
  1.   public void RunTest()
  2.         {
  3.             //Folder myword = new Word();
  4.             //myword.Open();//打开文件,处理文件
  5.             //myword.Add(new SonFolder());//抛出异常
  6.             //myword.Remove(new SonFolder());//抛出异常
  7.             Folder myfolder = new SonFolder();
  8.             myfolder.Open();//打开文件夹
  9.             myfolder.Add(new SonFolder());//成功增加文件或者文件夹
  10.             myfolder.Remove(new SonFolder());//成功删除文件或者文件夹
  11.             Console.Read();
  12.         }
复制代码

安全式

代码定义
  1.   /// <summary>
  2.     /// Secure 安全式实现
  3.     /// </summary>
  4.     public class Secure
  5.     {
  6.         /// <summary>
  7.         /// 该抽象类就是文件夹抽象接口的定义,该类型就相当于是抽象构件Component类型
  8.         /// </summary>
  9.         public abstract class Folder //该类型少了容器对象管理子对象的方法的定义,换了地方,在树枝构件也就是SonFolder类型
  10.         {
  11.             //打开文件或者文件夹--该操作相当于Component类型的Operation方法
  12.             public abstract void Open();
  13.         }
  14.         /// <summary>
  15.         /// 该Word文档类就是叶子构件的定义,该类型就相当于是Leaf类型,不能在包含子对象
  16.         /// </summary>
  17.         public sealed class Word : Folder  //这类型现在很干净
  18.         {
  19.             //打开文件---该操作相当于Component类型的Operation方法
  20.             public override void Open()
  21.             {
  22.                 Console.WriteLine("打开Word文档,开始进行编辑");
  23.             }
  24.         }
  25.         /// <summary>
  26.         /// SonFolder类型就是树枝构件,现在由于我们使用的是“安全式”,所以Add,Remove都是从此处开始定义的
  27.         /// </summary>
  28.         public abstract class SonFolder : Folder //这里可以是抽象接口,可以自己根据自己的情况而定
  29.         {
  30.             //增加文件夹或文件
  31.             public abstract void Add(Folder folder);
  32.             //删除文件夹或者文件
  33.             public abstract void Remove(Folder folder);
  34.             //打开文件夹--该操作相当于Component类型的Operation方法
  35.             public override void Open()
  36.             {
  37.                 Console.WriteLine("已经打开当前文件夹");
  38.             }
  39.         }
  40.         /// <summary>
  41.         /// NextFolder类型就是树枝构件的实现类
  42.         /// </summary>
  43.         public sealed class NextFolder : SonFolder
  44.         {
  45.             //增加文件夹或文件
  46.             public override void Add(Folder folder)
  47.             {
  48.                 Console.WriteLine("文件或者文件夹已经增加成功");
  49.             }
  50.             //删除文件夹或者文件
  51.             public override void Remove(Folder folder)
  52.             {
  53.                 Console.WriteLine("文件或者文件夹已经删除成功");
  54.             }
  55.             //打开文件夹--该操作相当于Component类型的Operation方法
  56.             public override void Open()
  57.             {
  58.                 Console.WriteLine("已经打开当前文件夹");
  59.             }
  60.         }
  61.     }
复制代码
调用实现
  1.   public void RunTest()
  2.         {
  3.             //这是安全的组合模式
  4.             Folder myword = new Word();
  5.             myword.Open();//打开文件,处理文件
  6.             Folder myfolder = new NextFolder();
  7.             myfolder.Open();//打开文件夹
  8.             //此处要是用增加和删除功能,需要转型的操作,否则不能使用
  9.             ((SonFolder)myfolder).Add(new NextFolder());//成功增加文件或者文件夹
  10.             ((SonFolder)myfolder).Remove(new NextFolder());//成功删除文件或者文件夹
  11.         }
复制代码

组合模式的优缺点

优点


  • 组合模式使得客户端代码可以一致地处理对象和对象容器,无需关心处理的是单个对象,还是组合的对象容器。
  • 将”客户代码与复杂的对象容器结构“解耦。
  • 可以更容易地往组合对象中加入新的构件。
缺点


  • 使得设计更加复杂。客户端需要花更多时间理清类之间的层次关系。

来源:https://www.cnblogs.com/wml-it/archive/2023/09/11/17693267.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具