国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > C# > 正文

C# 設(shè)計(jì)模式系列教程-組合模式

2020-01-24 01:08:33
字體:
供稿:網(wǎng)友

1. 概述

  將對象組合成樹形結(jié)構(gòu)以表示“部分-整體”的層次結(jié)構(gòu)。組合模式使得用戶對單個(gè)對象和組合對象的使用具有一致性。

2. 解決的問題

  當(dāng)希望忽略單個(gè)對象和組合對象的區(qū)別,統(tǒng)一使用組合結(jié)構(gòu)中的所有對象(將這種“統(tǒng)一”性封裝起來)。

3. 組合模式中的角色

  3.1 組合部件(Component):它是一個(gè)抽象角色,為要組合的對象提供統(tǒng)一的接口。

  3.2 葉子(Leaf):在組合中表示子節(jié)點(diǎn)對象,葉子節(jié)點(diǎn)不能有子節(jié)點(diǎn)。

  3.3 合成部件(Composite):定義有枝節(jié)點(diǎn)的行為,用來存儲部件,實(shí)現(xiàn)在Component接口中的有關(guān)操作,如增加(Add)和刪除(Remove)。

4. 模式解讀

  4.1 組合模式的類圖

http://files.VeVB.COm/file_images/article/201606/2016060111022323.png

  4.2 組合模式的實(shí)現(xiàn)代碼

  /// <summary>  /// 一個(gè)抽象構(gòu)件,聲明一個(gè)接口用于訪問和管理Component的子部件  /// </summary>  public abstract class Component  {    protected string name;    public Component(string name)    {      this.name = name;    }    /// <summary>    /// 增加一個(gè)節(jié)點(diǎn)    /// </summary>    /// <param name="component"></param>    public abstract void Add(Component component);    /// <summary>    /// 移除一個(gè)節(jié)點(diǎn)    /// </summary>    /// <param name="component"></param>    public abstract void Remove(Component component);    /// <summary>    /// 顯示層級結(jié)構(gòu)    /// </summary>    public abstract void Display(int level);  }  /// <summary>  /// 葉子節(jié)點(diǎn)  /// </summary>  public class Leaf : Component  {    public Leaf(string name)      : base(name)    { }    /// <summary>    /// 由于葉子節(jié)點(diǎn)沒有子節(jié)點(diǎn),所以Add和Remove方法對它來說沒有意義,但它繼承自Component,這樣做可以消除葉節(jié)點(diǎn)和枝節(jié)點(diǎn)對象在抽象層次的區(qū)別,它們具備完全一致的接口。    /// </summary>    /// <param name="component"></param>    public override void Add(Component component)    {      Console.WriteLine("Can not add a component to a leaf.");    }    /// <summary>    /// 實(shí)現(xiàn)它沒有意義,只是提供了一個(gè)一致的調(diào)用接口    /// </summary>    /// <param name="component"></param>    public override void Remove(Component component)    {      Console.WriteLine("Can not remove a component to a leaf.");    }    public override void Display(int level)    {      Console.WriteLine(new string('-',level) + name);    }  }  /// <summary>  /// 定義有枝節(jié)點(diǎn)的行為,用來存儲部件,實(shí)現(xiàn)在Component接口中對子部件有關(guān)的操作  /// </summary>  public class Composite : Component  {    public Composite(string name)      : base(name)    { }    /// <summary>    /// 一個(gè)子對象集合,用來存儲其下屬的枝節(jié)點(diǎn)和葉節(jié)點(diǎn)    /// </summary>    private List<Component> children = new List<Component>();    /// <summary>    /// 增加子節(jié)點(diǎn)    /// </summary>    /// <param name="component"></param>    public override void Add(Component component)    {      children.Add(component);    }    /// <summary>    /// 移除子節(jié)點(diǎn)    /// </summary>    /// <param name="component"></param>    public override void Remove(Component component)    {      children.Remove(component);    }    public override void Display(int level)    {      Console.WriteLine(new string('-', level) + name);      // 遍歷其子節(jié)點(diǎn)并顯示      foreach (Component component in children)      {        component.Display(level+2);      }    }  }

  4.3 客戶端代碼

  class Program  {    static void Main(string[] args)    {      // 生成樹根,并為其增加兩個(gè)葉子節(jié)點(diǎn)      Component root = new Composite("Root");      root.Add(new Leaf("Leaf A in Root"));      root.Add(new Leaf("Leaf B in Root"));      // 為根增加兩個(gè)枝節(jié)點(diǎn)      Component branchX = new Composite("Branch X in Root");      Component branchY = new Composite("Branch Y in Root");      root.Add(branchX);      root.Add(branchY);      // 為BranchX增加頁節(jié)點(diǎn)      branchX.Add(new Leaf("Leaf A in Branch X"));      // 為BranchX增加枝節(jié)點(diǎn)      Component branchZ = new Composite("Branch Z in Branch X");      branchX.Add(branchZ);      // 為BranchY增加葉節(jié)點(diǎn)      branchY.Add(new Leaf("Leaf in Branch Y"));      // 為BranchZ增加葉節(jié)點(diǎn)      branchZ.Add(new Leaf("Leaf in Branch Z"));      // 顯示樹      root.Display(1);      Console.Read();    }  }

  運(yùn)行結(jié)果

http://files.VeVB.COm/file_images/article/201606/2016060111022324.png

5. 透明方式與安全方式

  5.1 透明方式:在Component中聲明所有來管理子對象的方法,其中包括Add,Remove等。這樣實(shí)現(xiàn)Component接口的所有子類都具備了Add和Remove方法。這樣做的好處是葉節(jié)點(diǎn)和枝節(jié)點(diǎn)對于外界沒有區(qū)別,它們具備完全一致的接口。

  5.2 安全方式:在Component中不去聲明Add和Remove方法,那么子類的Leaf就不需要實(shí)現(xiàn)它,而是在Composit聲明所有用來管理子類對象的方法。

  5.3 兩種方式有缺點(diǎn):對于透明方式,客戶端對葉節(jié)點(diǎn)和枝節(jié)點(diǎn)是一致的,但葉節(jié)點(diǎn)并不具備Add和Remove的功能,因而對它們的實(shí)現(xiàn)是沒有意義的;對于安全方式,葉節(jié)點(diǎn)無需在實(shí)現(xiàn)Add與Remove這樣的方法,但是對于客戶端來說,必須對葉節(jié)點(diǎn)和枝節(jié)點(diǎn)進(jìn)行判定,為客戶端的使用帶來不便。

6. 模式總結(jié)

  6.1 優(yōu)點(diǎn)

    6.1.1 使客戶端調(diào)用簡單,它可以一致使用組合結(jié)構(gòu)或是其中單個(gè)對象,簡化了客戶端代碼。

    6.1.2 容易在組合體內(nèi)增加對象部件。客戶端不必因加入了新的部件而更改代碼。有利于功能的擴(kuò)展。

  6.2 缺點(diǎn)

    6.2.1 需要抉擇使用透明方式還是安全方式。

    6.2.2 透明方式違背了面向?qū)ο蟮膯我宦氊?zé)原則;安全方式增加了客戶需要端判定的負(fù)擔(dān)。

  6.3 適用場景

    6.3.1 當(dāng)想表達(dá)對象的部分-整體的層次結(jié)構(gòu)時(shí)

    6.3.3 希望用戶忽略組合對象與單個(gè)對象的不同,用戶將統(tǒng)一地使用組合結(jié)構(gòu)中的所有對象時(shí)。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 时尚| 晋宁县| 江山市| 环江| 新宾| 新郑市| 肃南| 嘉荫县| 西乌| 和龙市| 靖远县| 开化县| 砀山县| 扶沟县| 南漳县| 保山市| 武陟县| 石河子市| 兰西县| 营口市| 旬阳县| 文安县| 资兴市| 长寿区| 淮北市| 丁青县| 凤城市| 沙河市| 龙海市| 闽侯县| 宜州市| 安顺市| 浪卡子县| 柳州市| 新兴县| 泊头市| 大悟县| 卫辉市| 贵南县| 东城区| 景谷|