2009-08-07 47 views
2

刪除我有A類 的實例的集合,在某些時候的一個實例意識到它應該刪除自身。我想告訴收集這個,但我不想讓A知道任何有關收集。從集合

什麼是去了解這一點的最好方法是什麼?在我看來,似乎知道收集是非常糟糕的耦合,但如果我錯了,讓我知道。現在我正在考慮使用類似於A的實例可以觸發集合正在偵聽的事件。然後,當該事件被該集合捕獲時,移除它的實例。

上,這將是有幫助的任何想法,感謝

+0

兩個問題:你是使用支持垃圾回收的語言?您是否正在使用內置事件的語言? – 2009-08-07 05:32:43

+0

沒有垃圾收集,但在事件處理中爲是 – Ori 2009-08-07 05:38:15

回答

0

在設計模式方面你所描述的觀察者模式把(又名:發佈/訂閱)。 A的實例將保存一個監聽器。當A被刪除時,A將調用監聽器上的onDelete方法,將其自身作爲參數傳遞。該集合將實現偵聽器接口。

另一個替代方案是連鎖的,責任的圖案。

+0

但是在你描述的內容中,不知道它是否在調用OnDelete方法的集合中? – David 2009-08-07 05:37:05

+0

是的,我曾想過這個,但它看起來像強耦合。 – Ori 2009-08-07 05:38:53

+0

A與定義onDelete()方法的接口相結合。它與集合本身沒有關係。 – 2009-08-07 11:36:56

1

事件可能是最好的解決方案。

如果集合是一個無序集合(ICollection的在.NET)也有另一種解決方案。你可以添加一個IsDeleted屬性到你的類A,你設置爲true然後它被刪除。在你的集合類中,你可以假裝IsDeleted = true的對象不存在。

事情是這樣的:

class A { 
    public bool IsDeleted { get; set; } 
} 

class ACollection : ICollection<A> { 
    private List<A> _innerList = new List<A>(); 

    #region ICollection<A> Members 

    public void Add(A item) { 
     _innerList.Add(item); 
    } 

    public void Clear() { 
     _innerList.Clear(); 
    } 

    public bool Contains(A item) { 
     if(item.IsDeleted) 
      return false; 
     return _innerList.Contains(item); 
    } 

    public void CopyTo(A[] array, int arrayIndex) { 
     throw new NotImplementedException(); 
    } 

    public int Count { 
     get { 
      int count = 0; 
      foreach(var item in _innerList) { 
       if(!item.IsDeleted) 
        count++; 
      } 
      return count; 
     } 
    } 

    public bool IsReadOnly { 
     get { return false; } 
    } 

    public bool Remove(A item) { 
     return _innerList.Remove(item); 
    } 

    #endregion 

    #region IEnumerable<A> Members 

    public IEnumerator<A> GetEnumerator() { 
     foreach(var item in _innerList) { 
      if(!item.IsDeleted) 
       yield return item; 
     } 
    } 

    #endregion 

    #region IEnumerable Members 

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { 
     foreach(var item in _innerList) { 
      if(!item.IsDeleted) 
       yield return item; 
     } 
    } 

    #endregion 
}