【发布时间】:2011-03-06 15:48:22
【问题描述】:
我希望能够为可以使用的类提供默认值,但问题是如果它们被更改,那么它将影响对它的所有引用并且不会是“默认”。通过使用这样的默认值,它可以节省内存,并且允许默认值(如果需要)传播到所有使用默认值的引用。
一个简单的例子是
class A
{
static public A Default;
}
然后可以使用 A.Default 作为 A 的“默认”实例。同样,问题是 A 不是不可变的或至少“冻结”,对它的更改将更改所有引用。如果这是人们想要的行为,这可能会很好,但如果意外更改默认值,则会造成严重破坏。
我真正需要的是一种深度冻结和解冻默认值的方法。
显然,一种方法是简单地将所有 setter 设置为一个条件并将集合标记为只读。提供如此简单的行为似乎需要大量重复工作。
是否有一个简单的库、模式或反射来完成这个?写入时复制功能会很好,因此如果尝试更改默认值,则会创建一个新的可变实例。不仅如此,如果有机会提高性能(更改大小),甚至可以创建享元实例。
示例:假设您创建了 1M 大(内存大小)对象,初始状态都相同。通过使用默认模式,这只会创建 1 个实际对象。假设您为所有状态(例如位置)更改 1 个参数,但对象本身非常大。使用享元模式,您只需更改 1M 参数来跟踪(像往常一样更慢但内存更少),而不是 1M 新对象。在更改了足够多的参数后,最终将完整的对象分配给它的引用。
有这样的吗?
【问题讨论】:
-
在什么情况下,您想“解冻”默认值以及谁应该能够“解冻”默认值?
-
你确定你真的需要这么复杂的东西吗?
-
这似乎是一个设计缺陷。您有一个 A 类,当它是“默认”实例时它是不可变的,而当它不是时它是可变的。也许你需要两个类,一个是不可变的,一个是可变的,或者你的 A 类应该是一个结构体或值类型,比如对象(比如字符串)
-
@Merick:不,默认是“不可变的”,但 A 的实例不是。默认是 A(静态)类型的一部分。如果 Default 不是静态定义的,那么你是对的。
-
“它节省了内存”。 c2.com/cgi/wiki?PrematureOptimization