2009-11-23 53 views
3

如果不執行組件並將所有對象視爲組合,我會失去什麼?複合模式簡化

我已經放棄了對葉節點的實現:

class Component : IComponent 
{ 
    /*...*/ 
} 

現在看看我的代碼。

public interface IComponent 
{ 
    int ID { get;set; } 
    string Name { get;set;} 
    void Add(IComponent item); 
    void Remove(IComponent item); 
    List<IComponent> Items { get; } 
    void Show();   
} 


public class Composite : IComponent 
{ 
    private int _id; 
    public int ID 
    { 
     get { return _id; } 
     set { _id = value; } 
    } 

    private string _name; 
    public string Name 
    { 
     get { return _name; } 
     set { _name = value; } 
    } 

    public Composite(int id, string name) 
    { 
     _id = id; 
     _name = name; 
    } 

    private List<IComponent> _items = new List<IComponent>(); 

    public void Add(IComponent item) 
    { 
     _items.Add(item); 
    } 

    public void Remove(IComponent item) 
    { 
     _items.Remove(item); 
    } 

    public List<IComponent> Items 
    { 
     get 
     { 
      return new List<IComponent>(_items); 
     } 
    } 

    public void Show() 
    { 
     Console.WriteLine("ID=" + _id + "; Name=" + _name); 
    }   
} 


class Program 
{ 
    static void Main(string[] args) 
    { 
     IComponent root = new Composite(1, "World"); 

     IComponent asia = new Composite(2, "Asia"); 
     IComponent europe = new Composite(3, "Europe"); 

     root.Add(asia); 
     root.Add(europe); 

     asia.Add(new Composite(4, "China")); 
     asia.Add(new Composite(5, "Japan")); 

     europe.Add(new Composite(6, "Germany")); 
     europe.Add(new Composite(7, "Russia")); 

     root.Show(); 
     Program.Traverse(root.Items); 

     Console.ReadLine(); 
    } 

    static void Traverse(List<IComponent> items) 
    {    
     foreach (IComponent c in items) 
     { 
      c.Show(); 

      Traverse(c.Items); 
     } 
    } 
} 

什麼是錯的組合模式的這種做法?這種類型的設計可以面對什麼樣的問題?

+0

您可能會考慮澄清一下,您的問題是「通過不執行組件並將所有內容視爲組合件而失去了什麼」......我最初認爲您的代碼有問題,並且意識到您的問題不是關於代碼,其中的「作品」,但爲什麼你應該添加葉:) – Mathias 2009-11-23 06:04:05

+0

建議你在這裏研究代碼示例和內容:http://www.dofactory.com/patterns/patterncomposite.aspx看不到任何理由你應該「放棄Leaf節點的實現」。祝你好運 ! – BillW 2009-11-23 06:11:25

回答

7

你放棄任何機會,子類「葉」,如果事實證明你有不同類型的「節點」,你可能會最終污染的結構,這種或那種方式。而且你也違反了單一責任原則。這是很容易得到各種各樣的污染與複合模式,我認爲總是有回報做乾淨。

+0

「污染」是什麼意思?你能清楚一點嗎? – anonymous 2009-11-23 06:01:58

+1

對我來說,看起來你並沒有從樹數據中分離出樹結構。複合是一種相當危險的設計模式,因爲它有引誘你將所有東西放入樹和節點的傾向,即使是很多不應該存在的東西。它的優秀和優雅,但如果你把太多不同種類的邏輯/信息放到同一視圖中,也會變得雜亂無章。每次向樹上添加特定案例時都會發生「污染」。 – krosenvold 2009-11-23 19:40:24

0

如果我正確理解,存在 葉節點的概念,在合成圖案。

不生孩子的任何節點自動爲葉節點。
看你的代碼,這是沒有必要

private List<IComponent> _items = new List<IComponent>(); 

    public void Add(IComponent item) 
    { 
     _items.Add(item); 
    } 

    public void Remove(IComponent item) 
    { 
     _items.Remove(item); 
    } 

    public List<IComponent> Items 
    { 
     get 
     { 
       return new List<IComponent>(_items); 
     } 
    } 

我在看ControlCollection類,這是Control類的屬性。

雖然不完全複合模式,它是誰的孩子,這是從你的代碼所缺少的每個控件都知道。

我的理解完全可以解決。專家指正:)

編輯:我看了看dofactory參考,裏面好像有葉類的概念在複合模式。我完全不理解它的錯誤。

但我建議你看看.NET的方式通過具有ControlControlCollection &相關類實現組成圖案。

EDIT2:如果上面的代碼被刪除,你將有另一類是IComponent集合,你可以通過使用屬性IList<IComponent>,這反過來將有方法來add/remove暴露。

EDIT3:.NET不限制從上述的類層次結構中添加子控件的用戶。如果您想限制某人定義葉節點(沒有任何子節點的節點)的能力,則可以使用dofactory設計方法。編輯4:dofactory代碼顯示的方式,你將不得不定義一個葉節點,這將拋出NotImplementedExceptionAdd /`刪除'。

+0

如果我放棄這段代碼,我會如何儲存孩子?那麼該機制應該是什麼? – anonymous 2009-11-23 06:17:22

+0

好的。那麼IComponent接口會發生什麼?實施將不再有意義。這反過來使整個設計變得毫無意義。 – anonymous 2009-11-23 06:24:49