2010-03-06 77 views
0

這裏的「問題」是一般性討論主題。ICloneable的實用替代品

這是衆所周知的,ICloneableserious problems。純粹不可變的對象是可以克隆的(通過引用),所以可以假定用於克隆對象的接口處理可變對象。一個我已經看到可克隆對象的概念非常有用的地方是與使用可凍結對象進行線程化和/或性能優勢相結合。 IMO,從WPF的Freezable類是這種模式的一個很好的例子,但太特殊應用:

與治療 System.Windows.Freezable作爲通用
  • 問題:
    • 這是一個類而不是一個接口,這限制了它的範圍
    • 它從DispatcherObjectDependencyObject,這兩者加特定領域的開銷
    • 再添上WindowsBase.dll中的依賴,這是不拿起這將是一個SMA正是輕量級的方法得到的LL接口

Freezable類型的精神,我相信下面IFreezable接口是廣泛適用於現代的代碼。

  • 幾個設計決定我做:
    • 爲了幫助在多線程環境中,此界面的使用,冷凍操作的設計不會引發InvalidOperationException如果CanFreeze是假的。但是,接口中不包括線程安全的明確保證(這些由實施者決定)。
    • Freezable類別Changed財產不包括 - 使用INotifyPropertyChanged和/或INotifyCollectionChanged來代替。

下面是代碼:

/// <summary> 
/// Defines an object that has a modifiable state and a read-only (frozen) state. 
/// Classes that implement IFreezable can be made immutable, and can clone 
/// themselves. 
/// </summary> 
public interface IFreezable 
{ 
    /// <summary> 
    /// Gets a value that indicates whether the object can be made unmodifiable. 
    /// </summary> 
    bool CanFreeze 
    { 
     get; 
    } 

    /// <summary> 
    /// Gets a value that indicates whether the object is currently modifiable. 
    /// </summary> 
    bool IsFrozen 
    { 
     get; 
    } 

    /// <summary> 
    /// Creates a modifiable clone of the IFreezable, making deep copies of the 
    /// object's values. 
    /// </summary> 
    /// <returns> 
    /// A modifiable clone of the current object. The cloned object's IsFrozen 
    /// property is false even if the source's IsFrozen property is true. 
    /// </returns> 
    IFreezable Clone(); 

    /// <summary> 
    /// Makes the current object unmodifiable and sets its IsFrozen property 
    /// to true. 
    /// </summary> 
    /// <returns>true if the object is made frozen, otherwise false.</returns> 
    bool TryFreeze(); 

    /// <summary> 
    /// Creates a frozen copy of the IFreezable. Because the copy is frozen, any 
    /// frozen sub-objects are copied by reference. 
    /// </summary> 
    /// <param name="freezable"> 
    /// Upon return, this is set to a frozen copy of the IFreezable. If a frozen 
    /// copy could not be made, the value is set to null. 
    /// </param> 
    /// <returns> 
    /// true if the current instance is frozen or if a frozen copy of the 
    /// instance could be made, otherwise false. 
    /// </returns> 
    bool TryGetAsFrozen(out IFreezable freezable); 
} 
+0

@nobugz:你或者1)同意我提出的接口和所有給定的基本原理,因此並不認爲它是討論要點,或者2)完全沒有涉及這一點。隱含的問題包括但不限於「這可用/有用嗎?」 「這會造成什麼問題?」 「你會如何改善這一點?」還有別人可能會看到的 – 2010-03-06 23:32:05

+3

問題是,1)和2)都沒有爲有意義的答案留下空間。如果我已經同意你的觀點,那麼我喋喋不休的意見就沒有意義了。如果我不同意你已經否認這是「我錯過了這一點」。考慮開始你自己的博客。 – 2010-03-07 00:48:07

回答

2

是不是Builder模式較好地解決了同樣的問題?更好地說,我的意思是說,讓一個可變類生成一個不可改變的類比嘗試在一個地方創建兩個功能塊更有意義。

+1

這裏的問題是你不能採取線程安全的不可變對象,並使用它創建一個可變實例,除非你可以克隆構建器,這會導致回到ICloneable的原始問題。 – 2010-03-06 20:57:35