通过C#了解复合模式,删除(T项)函数实现

时间:2015-02-11 19:23:20

标签: c# design-patterns composite

我正在研究复合模式,使用Judith Bishop的C#3.0设计模式中的示例(第55页)。

我正在堆叠的问题涉及 Composite类的功能: public IComponent Remove(T item) 制作以下IF声明的意义是什么

 if (_holder != null)
            {
                (_holder as Composite<T>)._items.Remove(p);
                return _holder;
            }

public IComponent<T> Remove(T item)
    {
        _holder = this;
        IComponent<T> p = _holder.Find(item);
        if (_holder != null)
        {
            (_holder as Composite<T>)._items.Remove(p);
            return _holder;
        }
        else
        {
            return this;
        }
    }

    //Recursively looks for an item
    //Returns its reference or else null
    public IComponent<T> Find(T item)
    {
        _holder = this;
        if(Item.Equals(item))
        {
            return this;
        }
        IComponent<T> found = null;
        foreach(IComponent<T> comp in _items)
        {
            found = comp.Find(item);
            if(found != null)
            {
                break;
            }
        }
        return found;
    }

就我而言,_holder变量总是在删除查找函数中分配,因此不能为空。 它们是否意味着要将 p 引用检查为null?

接口IComponent

 public interface IComponent<T>
{
    void Add(IComponent<T> component);
    IComponent<T> Remove(T s);
    IComponent<T> Find(T s);
    string Display(int depth);
    T Item { get; set; }
}

组件类实现:

    class Component<T> : IComponent<T>
{
    public T Item { get; set; }

    public Component(T item)
    {
        Item = item;
    }

    public void Add(IComponent<T> item)
    {
        Console.WriteLine("Cannot add to Single item!");
    }

    public IComponent<T> Remove(T item)
    {
        Console.WriteLine("Cannot remove directly the Single item");
        return this;
    }

    public IComponent<T> Find(T item)
    {
        if (Item.Equals(item))
        {
            return this;
        }
        return null;
    }

    public string Display(int depth)
    {
        return string.Format("-{0}---{1}", depth, Item);
    }
}

复合类实现:

public class Composite<T> : IComponent<T>
{
    public T Item { get; set; }
    private List<IComponent<T>> _items = new List<IComponent<T>>();
    private IComponent<T> _holder;

    public Composite(T item)
    {
        Item = item;
    }

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

    //Finds the item from a particular point in the structure
    //and returns the composite from which it was removed
    //If not found, return the point as given
    public IComponent<T> Remove(T item)
    {
        _holder = this;
        IComponent<T> p = _holder.Find(item);
        if (_holder != null)
        {
            (_holder as Composite<T>)._items.Remove(p);
            return _holder;
        }
        else
        {
            return this;
        }
    }

    //Recursively looks for an item
    //Returns its reference or else null
    public IComponent<T> Find(T item)
    {
        _holder = this;
        if(Item.Equals(item))
        {
            return this;
        }
        IComponent<T> found = null;
        foreach(IComponent<T> comp in _items)
        {
            found = comp.Find(item);
            if(found != null)
            {
                break;
            }
        }
        return found;
    }
}

2 个答案:

答案 0 :(得分:1)

检查是针对p而不是这个,因为这不能为空。

_holder = this;
    IComponent<T> p = _holder.Find(item);
    if (_holder != null)

这不能为空 所以_holder也不能为空 但是find可以返回null 在执行删除之前检查查找结果是非常合理的。

另一种可能性是

_holder as Composite<T> is null ?

所以

if (_holder as Composite<T>==null) 

也是有效的支票。

答案 1 :(得分:1)

很可能这是一个错误,也是因为

     IComponent<T> p = _holder.Find(item); //THIS LINE !
    if (_holder != null)
    {
        (_holder as Composite<T>)._items.Remove(p);
        return _holder;
    }

如果我们以某种方式关注_holder成为null(反射,多线程......)为什么我们之前不会检查这一点?如果我们假设在这种情况下它可以以某种方式成为这样的话,那么保证我在_holder null的情况下有什么保证?

所以,很可能是一个错误。