复合模式简化

时间:2009-11-23 05:42:44

标签: c# composite

如果不实施Component并将所有内容视为Composite,我会失去什么?

我放弃了Leaf节点的实现:

即。

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);
        }
    }
}

这种复合模式方法有什么问题?这种设计可以带来什么样的问题?

2 个答案:

答案 0 :(得分:7)

你放弃任何机会继承“Leaf”,如果事实证明你有不同类型的“节点”,你可能最终会以这种或那种方式污染结构。而且你也违反了单一的责任原则。使用复合图案很容易污染各种各样的污染物,我认为干净利落地总能带来好处。

答案 1 :(得分: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类的属性。

虽然不完全是复合模式,但每个Control都知道它是谁的孩子,你的代码中缺少了。

我的理解可能完全没有。专家可以纠正我:)。

编辑:我查看了dofactory引用,它似乎在复合模式中有叶类的概念。我完全不了解它的错误。

但我建议你看看.net通过ControlControlCollection&amp;和<{1}}来实现 种类 复合模式的方式。相关课程。

EDIT2:如果要移除上面的代码,您将拥有另一个类,它是IComponent的集合,您可以使用属性IList<IComponent>公开它,而后者又有方法add / remove

EDIT3:.net不限制用户在上述类层次结构中添加子控件。如果您想限制某人定义叶节点(没有任何子节点的节点)的能力,您可以使用dofactory设计方法。

EDIT4:dofactory代码显示的方式,你必须定义一个叶子节点,它会为NotImplementedException /`Remove'抛出Add