日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

设计模式笔记(9)---组合模式(结构型)

發布時間:2023/11/27 生活经验 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 设计模式笔记(9)---组合模式(结构型) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Gof定義

將對象組合成樹形結構以表示“部分--整體”的層次結構。Composite使得用戶對單個對象和組合對象使用具有一致性。

在面向對象系統中,我們經常會遇到一類具有”容器“特征的對象---即他們在充當對象的同時,又是其他對象的容器。比如在一些管理系統中就會出現總公司下面有很多的分公司,分公司下面有很多的部門,每個部門下又有很多的員工,像分公司和部門就是既充當了“對象”的角色也充當了“容器”的角色;還有我們可能玩過的“俄羅斯套娃”也是這種結構,一個大娃娃里面裝個小娃娃,小的里面又有個小的直到最小的一個,中間的娃娃就是既充當了“對象”也充當了“容器”。先看下面這個例子:

interface IBox
{void Process();
}
/// <summary>
/// 相當于樹的葉子節點,沒有子對象了
/// </summary>
public class SingleBox : IBox
{public void Process(){ }
}
/// <summary>
/// 容器
/// </summary>
public class ContainerBox : IBox
{List<IBox> list = new List<IBox>();public void Process() { }public List<IBox> GetBoxes(){return list;}
}
/// <summary>
/// 客戶代碼
/// </summary>
public class App
{static void Mina(){///此處從工廠方法中得到盒子的對象,但我們不知道是SingleBox還是ContainerBox///所以要做判斷IBox box = Factory.Create();if (box is ContainerBox){box.Process();List<IBox> list = ((ContainerBox)box).GetBoxes();}else if(box is SingleBox){box.Process();}}
}

動機

上面代碼的問題的根據在于:客戶代碼過多地依賴對象容器復雜的內部實現結構,對象容器內部實現結構(而非抽象接口)的變化將引起客戶代碼的頻繁變化,帶來了代碼的維護性、擴展性等弊端。

如何將“客戶代碼與復雜的對象容器結構”解耦?讓對象容器自己來實現自身的復雜結構,從而使得客戶代碼就像處理簡單對象一樣來處理復雜的對象容器?

這就要使用Composite模式了,先看下Composite模式的結構圖

Component:定義了Leaf和Composite的一些共有特性。

Composite:有容器特征的類型。

Leaf:葉節點,即一個單獨的個體,下面沒有子節點。

依據上面的結構圖完成代碼實現:

public abstract class Component
{protected string _name;public Component(string name){_name = name;}public abstract void Operation();public abstract void Add(Component component);public abstract void Remove(Component component);
}public class Leaf : Component
{public Leaf(string name) : base(name) { }public override void Add(Component component){throw new NotSupportedException();}public override void Remove(Component component){throw new NotSupportedException();}public override void Operation(){ //...do something}
}public class Composite : Component
{public Composite(string name):base(name){}List<Component> list = new List<Component>();/// <summary>/// 添加/// </summary>/// <param name="conponent"></param>public override void Add(Component component){if (list != null){list = new List<Component>();}list.Add(component);}/// <summary>/// 刪除/// </summary>/// <param name="component"></param>public override void Remove(Component component){if (list == null){throw new NullReferenceException();}list.Remove(component);}public override void Operation(){if (list != null){foreach (Component c in list){c.Operation();}}}
}

Leaf類為葉子節點類,它的實例是沒有子節點的,但是在抽象類中的方法Add和Remove方法必須要實現,按理說這樣的實現是沒有意義的,所以在此處拋出了NotSupportedException 異常,在客戶端調用捕獲到再做相應的處理,這種模式稱之為“透明足組合模式”,這樣做的好處是葉子(Leaf)和容器(Composite)對于外界沒有分別,它們具有一致的接口行為。還有一種情況叫“安全組合模式”,在抽象類(Component)中不定義Add Remove方法,而是在容器的實現類中去定義,這樣就各司其職了,看下面結構圖

代碼實現

public abstract class Component
{protected string _name;public Component(string name){_name = name;}public abstract void Operation();
}public class Leaf : Component
{public Leaf(string name) : base(name) { }public override void Operation(){//...do something}
}public class Composite : Component
{public Composite(string name) : base(name) { }List<Component> list = new List<Component>();/// <summary>/// 添加/// </summary>/// <param name="conponent"></param>public void Add(Component component){if (list != null){list = new List<Component>();}list.Add(component);}/// <summary>/// 刪除/// </summary>/// <param name="component"></param>public void Remove(Component component){if (list == null){throw new NullReferenceException();}list.Remove(component);}public override void Operation(){if (list != null){foreach (Component c in list){c.Operation();}}}
}

使用“安全組合模式”Leaf和Composite就不具有相同的接口,所以在客戶端調用的時候還是要去判斷是什么類型,比較麻煩。所以說選擇哪種還要看具體的需求。

Composite模式的幾個要點

Composite模式采用樹形結構來實現普遍存在的對象容器,從而將“一對多”的關系轉化為“一對一”的關系,使得客戶代碼可以一致地處理對象和對象容器,無需關心處理的是單個的對象還是組合的對象容器。

將“客戶代碼與復雜的對象容器結構”解耦是Composite模式的核心思>想,解耦之后,客戶代碼將與純粹的抽象接口——而非對象容器的復內部實現結構——發生依賴關系,從而更能“應對變化”。

Composite模式中,是將“Add和Remove等和對象容器相關的方法”定義在“表示抽象對象的Component類”中,還是將其定義在“表示對象容器的Composite類”中,是一個關乎“透明性”和“安全性”的兩難問題,需要仔細權衡。這里有可能違背面向對象的“單一職責原則”,但是對于這種特殊結構,這又是必須付出的代價。ASP.NET控件的實現在這方面為我們提供了一個很好的示范。

Composite模式在具體實現中,可以讓父對象中的子對象反向追溯; 如果父對象有頻繁的遍歷需求,可使用緩存技巧來改善效率。

轉載于:https://www.cnblogs.com/oec2003/archive/2009/12/02/1615773.html

總結

以上是生活随笔為你收集整理的设计模式笔记(9)---组合模式(结构型)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。