2009-11-23 52 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