<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12
      Fork me on GitHub

      組合模式(Composite)

      1.1.1 摘要

            在軟件系統(tǒng)設(shè)計(jì)中,我們經(jīng)常會(huì)遇到整體和部分的設(shè)計(jì)問(wèn)題,例如為一家架構(gòu)完善的公司設(shè)計(jì)系統(tǒng)時(shí),我們?cè)谙到y(tǒng)設(shè)計(jì)過(guò)程中應(yīng)該更加注重這種整體和部分的關(guān)系(總部和分部的關(guān)系),這就是我們今天要介紹的組合模式(Composite)。

            組合模式(Composite)把對(duì)象構(gòu)造成為一棵對(duì)象樹,現(xiàn)在讓我們簡(jiǎn)短回憶一下樹的定義。

            樹是一種數(shù)據(jù)結(jié)構(gòu),它是由n(n>=1)個(gè)有限結(jié)點(diǎn)組成一個(gè)具有層次關(guān)系的集合。把它叫做“樹”是因?yàn)樗雌饋?lái)像一棵倒掛的樹,也就是說(shuō)它是根朝上,而葉朝下的。它具有以下的特點(diǎn):

            每個(gè)結(jié)點(diǎn)有零個(gè)或多個(gè)子結(jié)點(diǎn);

            每一個(gè)子結(jié)點(diǎn)只有一個(gè)父結(jié)點(diǎn);

            沒(méi)有前驅(qū)的結(jié)點(diǎn)為根結(jié)點(diǎn);

            除了根結(jié)點(diǎn)外,每個(gè)子結(jié)點(diǎn)可以分為m個(gè)不相交的子樹(參考維基百科);

            使用頻率: clip_image001  medium high

       

      • 定義

              組合模式(Composite),將對(duì)象組合成樹形結(jié)構(gòu)以表示‘部分-整體’的層次關(guān)系(樹狀結(jié)構(gòu))。組合模式使得用戶對(duì)單個(gè)對(duì)象和組合對(duì)象使用具有一致性。

       

      • 意圖

              希望用戶可以忽略單個(gè)對(duì)象和組合對(duì)象的區(qū)別,統(tǒng)一使用組合結(jié)構(gòu)中的所有對(duì)象(封裝變化的思想)。

       

      • 結(jié)構(gòu)圖

       

      composite0

      圖1組合模式(Composite)結(jié)構(gòu)圖

       

      • 參與者

              Component

              它是一個(gè)抽象角色,為對(duì)象的組合提供統(tǒng)一的接口。

              為其派生類提供默認(rèn)的行為。

              通過(guò)該接口來(lái)訪問(wèn)和管理Child Components(節(jié)點(diǎn)后繼)。

              通過(guò)該接口來(lái)訪問(wèn)Parent Components(節(jié)點(diǎn)前驅(qū))。

       

              Leaf

              代表參加組合的葉子對(duì)象(葉子沒(méi)有后繼)。

              定義組成原始對(duì)象的行為。

       

              Composite

              定義非葉子對(duì)象的行為。

              實(shí)現(xiàn)Component中的孩子操作行為(如:Add(),Remove() 等)。

       

       

      1.1.2 正文

            在我們學(xué)習(xí)組合模式(Composite)之前,讓我們先講解一下透明方式和安全方式。

            透明方式:在Component中聲明所有用來(lái)管理子對(duì)象的方法,如Add()方法,Remove()方法及GetChild()方法,所有實(shí)現(xiàn)Component接口的子類都具備這些方法,這使得Component和子類具備一致的行為接口,使得對(duì)客戶端無(wú)需區(qū)別樹葉和樹枝對(duì)象。

            大家可以回憶一下代理模式(Proxy)中,Proxy,RealSubject類和Subject接口具備一致的行為接口,從而使得被代理者對(duì)于客戶端是透明的。

            正由于我們的Composite和Leaf都具備一致的接口行為,但我們知道Leaf不應(yīng)該具有Add(),Remove()及GetChild()方法,因?yàn)槲覀內(nèi)~子節(jié)點(diǎn)不能再添加和移除節(jié)點(diǎn)了。

            安全模式:在透明模式基礎(chǔ)上把Component中聲明所有用來(lái)管理子對(duì)象的方法移到Composite中,在Composite實(shí)現(xiàn)子對(duì)象的管理方法,那么Leaf就沒(méi)有子對(duì)象管理方法,這使得Composite和Leaf的行為接口不一致,所以客戶端在調(diào)用時(shí)要知道樹葉和樹枝對(duì)象存在。

       

      composite1

      圖2透明方式的組合模式(Composite)結(jié)構(gòu)圖

       

       composite2

      圖3安全方式的組合模式(Composite)結(jié)構(gòu)圖

       

            通過(guò)前面的介紹我們知道透明和安全方式組合模式(Composite)的區(qū)別在于是否在抽象接口Component中定義子對(duì)象的管理行為。現(xiàn)在讓我們完成透明方式的組合模式(Composite)。

            以下示例代碼演示透明方式的組合模式代碼:

            首先我們定義一個(gè)抽象類Componet,在其中聲明Add(),Remove()和Display()等子對(duì)象操作發(fā)法及初始化字段name的公共行為。

       

      /// <summary>
      /// The Component acts as abstract class.
      /// </summary>
      public abstract class Component
      {
          protected string name;
      
      
          public Component()
          {
          }
      
      
          public Component(string name)
          {
              this.name = name;
          }
      
          #region Methods
      
          public abstract Component Add(Component obj);
          public abstract void Remove(Component obj);
          public abstract void Display(int depth);
      
          #endregion
      
      }

            接著我們定義Composite類繼承于Component,增加_children保存Component對(duì)象的引用,從而建立起由Component到Composite的聚集關(guān)系(Has-a關(guān)系),并且實(shí)現(xiàn)Component抽象類中的抽象方法。

       

      /// <summary>
      /// The Composite acts as branch.
      /// </summary>
      public class Composite : Component
      {
          private IList<Component> _childen = new List<Component>();
      
      
          public Composite()
          {
          }
      
          public Composite(string name)
              : base(name)
          {
          }
      
      
          /// <summary>
          /// Adds the branch or leaf obj.
          /// </summary>
          /// <param name="obj">The obj.</param>
          /// <returns></returns>
          public override Component Add(Component obj)
          {
              this._childen.Add(obj);
              return obj;
          }
      
      
          /// <summary>
          /// Removes the branch or leaf obj.
          /// </summary>
          /// <param name="obj">The obj.</param>
          public override void Remove(Component obj)
          {
              this._childen.Remove(obj);
          }
      
      
          /// <summary>
          /// Displays the tree's depth.
          /// </summary>
          /// <param name="depth">The depth.</param>
          public override void Display(int depth)
          {
              StringBuilder depthBuilder = new StringBuilder(new String('-', depth) + name);
              Console.WriteLine(depthBuilder);
      
              foreach (Component child in _childen)
              {
                  child.Display(depth + 1);
              }
          }
      
      }

            最后我們定義Leaf類它也是繼承于Component,在其中我們實(shí)現(xiàn)Component定義的行為接口,這使得Composite和Leaf類具有統(tǒng)一的接口行為,但我們并沒(méi)有在Leaf的行為方法中給出具體的實(shí)現(xiàn),因?yàn)槿~子節(jié)點(diǎn)并沒(méi)有后繼,所以沒(méi)有必要實(shí)現(xiàn)Add()和Remove()等行為。

       

      /// <summary>
      /// The "Leaf" acts as Leaf.
      /// </summary>
      public class Leaf : Component
      {
      
          public Leaf(string name)
              : base(name)
          {
          }
      
      
          public Leaf()
          {
          }
      
      
          /// <summary>
          /// Adds the branch or leaf obj.
          /// </summary>
          /// <param name="obj">The obj.</param>
          /// <returns></returns>
          public override Component Add(Component obj)
          {
              throw new NotSupportedException();
          }
      
      
          /// <summary>
          /// Removes the branch or leaf obj.
          /// </summary>
          /// <param name="obj">The obj.</param>
          public override void Remove(Component obj)
          {
              throw new NotSupportedException();
          }
      
      
          /// <summary>
          /// Displays the tree's depth.
          /// </summary>
          /// <param name="depth">The depth.</param>
          public override void Display(int depth)
          {
              StringBuilder depthBuilder = new StringBuilder(new String('-', depth) + name);
              Console.WriteLine(depthBuilder);
          }
      }

            我們定義一個(gè)工廠方法來(lái)創(chuàng)建Composite和Leaf對(duì)象,大家可以注意到在創(chuàng)建一個(gè)Component對(duì)象之后,我們調(diào)用子對(duì)象管理方法時(shí),并不需要判斷當(dāng)前對(duì)象是由Composite類,還是有Leaf類創(chuàng)建得來(lái),這就是透明方式的組合模式(Composite)。

      public class Program
      {
          static void Main(string[] args)
          {
              Client client = new Client();
              Component component = client.Get("root");
              Component componentA = component.Add(new Composite("BranchA"));
              componentA.Add(new Leaf("LeafA"));
              componentA.Add(new Leaf("LeafB"));
              Component componentB = component.Add(new Composite("BranchB"));
      
              component.Display(1);
      
              Console.ReadKey();
          }
      }
      

      composite3

      圖4輸出結(jié)果

       

            前面例子給出了透明方式組合模式(Composite)的實(shí)現(xiàn),我們?cè)贑omponent中聲明了Add() 和Remove()操作子對(duì)象方法,使得Composite和Leaf類具備一致的行為接口,客戶端可以正常調(diào)用Composite中的操作子對(duì)象方法,但如果客戶端嘗試調(diào)用Leaf中操作子對(duì)象方法時(shí)會(huì)拋出異常,因?yàn)槿~子節(jié)點(diǎn)沒(méi)有后繼節(jié)點(diǎn)了,假設(shè)我們要實(shí)現(xiàn)安全方式組合模式(Composite)客戶端在調(diào)用操作子對(duì)象方法時(shí),需要判斷當(dāng)前對(duì)象是葉子節(jié)點(diǎn)或枝節(jié)點(diǎn)。

       

       

      Component component = client.Get("root");
      
      if (component is Composite)
      {
          //// Implemention code.
      }

       

       

            接下來(lái)讓我們通過(guò)繪圖程序?qū)嵗榻B安全方式的組合模式(Composite)的實(shí)現(xiàn),首先我們定義一個(gè)抽象類DrawingProgramm,其角色為Component,然后再添加三個(gè)子類Shape,Triangle和Circle,它們的角色分別為:Composite,Leaf和Leaf。

            現(xiàn)在把子對(duì)象的管理方法都移到Shape類中,所以對(duì)客戶端來(lái)說(shuō)調(diào)用子對(duì)象時(shí),它了解Shape、Triangle和Circle直接的區(qū)別。

       

            以下示例代碼演示安全方式的組合模式代碼:

            首先我們定義一個(gè)抽象類DrawingProgramming(即Componet),在其中聲明Draw()及初始化字段_name的公共行為。

       

      /// <summary>
      /// The "DrawingProgramming" class acts as component.
      /// </summary>
      public abstract class DrawingProgramming
      {
          protected string _name;
          public abstract void Draw();
      
          public DrawingProgramming(string name)
          {
              this._name = name;
          }
      }

       

            接著我們定義Shape類繼承于DrawingProgramming,增加_children保存DrawingProgramming對(duì)象的引用,也是建立起由DrawingProgramming到Shape的聚集關(guān)系(Has-a關(guān)系),大家要注意到安全方式的組合模式(Composite)對(duì)子對(duì)象的管理方法都移到Shape類(即Composite)中,使得Leaf和Composite的行為接口不一致。

       

      /// <summary>
      /// The "Shape" class acts as composite.
      /// </summary>
      public class Shape : DrawingProgramming
      {
      
          IList<DrawingProgramming> _children = new List<DrawingProgramming>();
      
      
          public Shape(string name)
              : base(name)
          {
          }
      
          #region DrawingProgramming 成員
      
          public override void Draw()
          {
              StringBuilder depthBuilder = new StringBuilder(_name);
              Console.WriteLine(depthBuilder);
              foreach (DrawingProgramming child in _children)
              {
                  child.Draw();
              }
          }
      
          #endregion
      
          #region Methods
      
          public void Add(DrawingProgramming dp)
          {
              _children.Add(dp);
          }
      
          public void Remove(DrawingProgramming dp)
          {
              _children.Remove(dp);
          }
      
          #endregion
      }

       

       

            最后我們定義Triangle和Circle類它也是繼承于DrawingProgramming,在其中我們實(shí)現(xiàn)DrawingProgramming定義的Draw()行為,這使得Composite和Leaf類具有不一致的接口行為,這樣我們可以避免在Leaf中實(shí)現(xiàn)沒(méi)有必要地接口,從而使得我們?cè)O(shè)計(jì)符合SRP原則(對(duì)象職責(zé)單一原則)。

       

      /// <summary>
      /// The "Triangle" class acts as leaf.
      /// </summary>
      public class Triangle : DrawingProgramming
      {
      
          public Triangle(string name)
              : base(name)
          {
          }
      
          #region DrawingProgramming 成員
      
          public override void Draw()
          {
              StringBuilder depthBuilder = new StringBuilder(_name);
              Console.WriteLine(depthBuilder);
          }
      
          #endregion
      }
      
      
      /// <summary>
      /// The "Circle" class acts as leaf.
      /// </summary>
      public class Circle : DrawingProgramming
      {
          public Circle(string name)
              : base(name)
          {
      
          }
      
          #region DrawingProgramming 成員
      
          public override void Draw()
          {
              StringBuilder depthBuilder = new StringBuilder(_name);
              Console.WriteLine(depthBuilder);
          }
      
          #endregion
      }

       

       

       

          大家注意到在我們給出的例子中,我們都是把對(duì)象一個(gè)接一個(gè)的鏈接起來(lái),值就是像是一條對(duì)象鏈,不禁讓人想起裝飾者模式(Decorator)中的裝飾對(duì)象鏈。

          組合模式(Composite)和裝飾者模式(Decorator)的關(guān)系

       decorator

      圖5 Decorator中的Composite

       

            通過(guò)上圖我們可以發(fā)現(xiàn),裝飾者模式(Decorator)是通過(guò)組合模式(Composite)來(lái)構(gòu)建起一棵對(duì)象樹,然后通過(guò)裝飾者的子類來(lái)擴(kuò)展裝飾者(即Composite)的行為,從而實(shí)現(xiàn)對(duì)具體組件裝飾行為(即Leaf)。

       

      1.1.3 總結(jié)

            1.組合模式(Composite)采用樹形層次結(jié)構(gòu)來(lái)實(shí)現(xiàn)對(duì)象容器,如:繪圖程序例子我們把各種各樣的圖形添加的Shape中,從而構(gòu)造起一條對(duì)象鏈,把“一對(duì)多”的關(guān)系轉(zhuǎn)化“一對(duì)一”的層次關(guān)系,使得客戶代碼可以一致地處理對(duì)象和對(duì)象容器,無(wú)需關(guān)心處理的是單個(gè)的對(duì)象,還是組合的對(duì)象容器。

           2.組合模式(Composite)中,透明方式和安全方式的使用抉擇,雖然透明方式有可能違背面向?qū)ο蟮腟RP原則(單一職責(zé)),而安全方式?jīng)]有很好的封裝變化,但在實(shí)際開發(fā)時(shí)我們要根據(jù)具體的情況權(quán)衡利弊。

      posted @ 2011-07-10 14:53  JK_Rush  閱讀(4265)  評(píng)論(4)    收藏  舉報(bào)
      主站蜘蛛池模板: 亚洲自在精品网久久一区| 高中女无套中出17p| 中文字幕国产日韩精品| 国产精品久久久久久久久久直播 | 亚洲大尺度一区二区av| 任我爽精品视频在线播放| 色综合视频一区二区三区| 91精品乱码一区二区三区| 欧美精品一区二区三区中文字幕| 97久久精品人人做人人爽| 亚洲丰满老熟女激情av| 免青青草免费观看视频在线| 精品人妻二区中文字幕| 大又大又粗又硬又爽少妇毛片| 蜜芽亚洲AV无码精品国产午夜| 福利一区二区在线观看| 久久综合国产色美利坚| 精品无码一区二区三区电影| 亚洲国产在一区二区三区| 国产美女午夜福利视频| 五月丁香综合缴情六月小说| 在线中文一区字幕对白| 日本韩国一区二区精品| 国产亚洲午夜高清国产拍精品| 国产四虎永久免费观看| 亚洲欧美日韩综合一区在线| 成人免费ā片在线观看| 91精品国产免费人成网站| 国产91久久精品一区二区| 久久精品波多野结衣| 成人综合婷婷国产精品久久蜜臀| 久久精品第九区免费观看| 久久精品中文字幕免费| 国产精一区二区黑人巨大| 熟妇激情一区二区三区| 欧日韩无套内射变态| 亚洲av成人一区二区| 免费无码成人AV片在线| 中文字幕国产精品自拍| 日本熟妇浓毛| 欧美日韩精品一区二区三区高清视频|