設計模式之組合模式(Composite)分享
場景:
如果想模擬windows的開始選單,分析一下會發現裡面的選單項:有些有子選單,有些則沒有;因此大體可以將選單類分為二類,設計程式碼如下:
////// 選單的顯示介面 /// public interface IMenu { void Show(); } ////// 選單基類 /// public class MenuBase { public string MenuName { set; get; } } ////// 有子選單的選單類 /// public class Menu : MenuBase, IMenu { public void Show() { Console.WriteLine(MenuName); } private IList_children; public IList Children { get { if (_children == null) { _children = new List (); } return _children; } } } /// /// 無子選單的選單類(即最底級選單) /// public class SingleMenu : MenuBase, IMenu { public void Show() { Console.WriteLine( MenuName); } }
客戶端示例呼叫如下:
class Program { //客戶程式 static void Main(string[] args) { Menu menuContainer = new Menu() { MenuName = "開始" }; SingleMenu menuShutdown = new SingleMenu() { MenuName = "t關機" }; Menu menuProgram = new Menu() { MenuName = "t程式" }; SingleMenu menuStartUp = new SingleMenu() { MenuName = "tt啟動" }; menuProgram.Children.Add(menuStartUp); menuContainer.Children.Add(menuProgram); menuContainer.Children.Add(menuShutdown); menuContainer.Show(); foreach (IMenu item in menuContainer.Children) { if (item is SingleMenu) { item.Show(); } else if (item is Menu) { ShowAllSubMenu(item); } } Console.ReadLine(); } ////// 客戶端呼叫的遞迴Show程式 /// /// static void ShowAllSubMenu(IMenu menu) { if (menu is SingleMenu) { menu.Show(); } else if (menu is Menu) { menu.Show(); IListchildren = (menu as Menu).Children; foreach (IMenu i in children) { ShowAllSubMenu(i); } } } }
從功能正確性上講,上面的示意程式碼並無大錯,但是如果從客戶程式上考慮,卻發現這樣並非最佳實踐:客戶程式依賴了太多的Menu類細節,客戶程式在樹型選單建立完成後,最關心的莫過於如何把選單完整的顯示出來,但上面的程式碼中為了達到這個目的,卻不得不知道子選單的內部實現(透過Children和型別判斷),如果以後選單類升級,修改了內部構造(比如將Children改成GetChildren),客戶程式將被迫重新修改,這時候組合(Composite)模式就派上用場了。
using System; using System.Collections.Generic; namespace composite { class Program { //客戶程式 static void Main(string[] args) { IMenu menuContainer = new Menu() { MenuName = "開始" }; IMenu menuShutdown = new SingleMenu() { MenuName = "t關機" }; IMenu menuProgram = new Menu() { MenuName = "t程式" }; IMenu menuStartUp = new SingleMenu() { MenuName = "tt啟動" }; menuProgram.Add(menuStartUp); menuContainer.Add(menuProgram); menuContainer.Add(menuShutdown); menuContainer.Show(); Console.ReadLine(); } } ////// 選單的顯示介面 /// public interface IMenu { void Show(); void Add(IMenu menu); void Remove(IMenu menu); } ////// 選單基類 /// public abstract class MenuBase { public string MenuName { set; get; } protected IListChildren; } /// /// 有子選單的選單類 /// public class Menu : MenuBase,IMenu { public void Show() { ShowAllSubMenu(this); } public void ShowAllSubMenu(IMenu menu) { if (menu is SingleMenu) { menu.Show(); } else if (menu is Menu) { Console.WriteLine((menu as Menu).MenuName); IListchildren = (menu as Menu).Children; foreach (IMenu i in children) { ShowAllSubMenu(i); } } } public void Add(IMenu menu) { if (Children == null) { Children = new List (); } Children.Add(menu); } public void Remove(IMenu menu) { if (Children == null) { Children = new List (); } Children.Add(menu); } } /// /// 無子選單的選單類(即最底級選單) /// public class SingleMenu :MenuBase, IMenu { public void Show() { Console.WriteLine( MenuName); } public void Add(IMenu menu) { throw new Exception("最底層選單無法Add子元素!"); } public void Remove(IMenu menu) { throw new Exception("最底層選單無法Remove子元素!"); } } }
最後再來理解Composite的意圖可能就更清楚了(摘自terrylee的“.NET設計模式(11):組合模式(Composite Pattern)"):
概述
組合模式有時候又叫做部分-整體模式,它使我們樹型結構的問題中,模糊了簡單元素和複雜元素的概念,客戶程式可以向處理簡單元素一樣來處理複雜元素,從而使得客戶程式與複雜元素的內部結構解 耦。
意圖
將物件組合成樹形結構以表示“部分-整體”的層次結構。Composite模式使得使用者對單個物件和組合物件的使用具有一致性。[GOF 《設計模式》]
類圖:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/818/viewspace-2800142/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 設計模式之組合模式---Composite Pattern設計模式
- [C++設計模式] composite 組合模式C++設計模式
- 《設計模式》 - 7. 組合模式( Composite )設計模式
- C#設計模式-組合模式(Composite Pattern)C#設計模式
- C#設計模式系列:組合模式(Composite)C#設計模式
- 設計模式--組合模式Composite(結構型)設計模式
- 設計模式的征途—9.組合(Composite)模式設計模式
- 組合模式(Composite)模式
- JAVA設計模式(10):結構型-組合模式(Composite)Java設計模式
- 【設計模式自習室】結構型:組合模式 Composite設計模式
- composite pattern(組合模式)模式
- PHP 設計模式之組合模式PHP設計模式
- 設計模式系列之「組合模式」設計模式
- 設計模式系列之組合模式(Composite Pattern)——樹形結構的處理設計模式
- 組合模式(Composite)的安全模式與透明模式模式
- 23種設計模式之組合模式設計模式
- Java設計模式之(十)——組合模式Java設計模式
- 【趣味設計模式系列】之【組合模式】設計模式
- javascript設計模式 之 7組合模式JavaScript設計模式
- 設計模式漫談之組合模式設計模式
- C#設計模式之組合模式C#設計模式
- 【設計模式】組合模式設計模式
- 設計模式《組合模式》設計模式
- 設計模式-組合模式設計模式
- 設計模式:組合模式設計模式
- 我所理解的設計模式(C++實現)——組合模式(Composite Pattern)設計模式C++
- js設計模式–組合模式JS設計模式
- js設計模式--組合模式JS設計模式
- 設計模式系列 – 組合模式設計模式
- javascript設計模式組合模式JavaScript設計模式
- 設計模式(十三):組合模式設計模式
- JavaScript設計模式之策略模式【組合委託】JavaScript設計模式
- 每天一個設計模式之組合模式設計模式
- 軟體設計模式系列之十——組合模式設計模式
- 設計模式(十四、十五)----結構型模式之組合模式設計模式
- 使用C# (.NET Core) 實現組合設計模式 (Composite Pattern)C#設計模式
- GoLang設計模式20 - 組合模式Golang設計模式
- 設計模式【11】-- 搞定組合模式設計模式