2010-03-06 43 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