在我的应用程序中,我有几种holder 对象,其主要目的是存储异构相关数据。它们的生命周期可以分为两部分:
- 一旦可用就收集数据;
- 在持有人的余生中提供对存储数据的只读访问权限。
使持有者不可变是非常诱人的,但数据不能一次性传递给构造函数。我看到的最简单的解决方法是制作两个版本的 holder 类,一个是可变的,另一个不是:
public class MutableHolder {
public int field1;
public String field2;
// ...
public Object fieldN;
}
public class Holder {
public final int field1;
public final String field2;
// ...
public final Object fieldN;
public Holder(MutableHolder mutableHolder) {
this.field1 = mutableHolder.field1;
this.field2 = mutableHolder.field2;
// ...
this.fieldN = mutableHolder.fieldN;
}
}
但是,我觉得这种方法违反了 DRY 原则(如果我想更改任何内容,我不能忘记更新两个类的字段以及构造函数)并且容易出错。所以这是我的问题:是否有任何我不知道的现有模式来实现 holder 对象的可变和不可变版本?
编辑
我突然发现上面的代码是构建器模式的一个非常简单的版本(参见 this 或 this )。这让我认为在这种情况下,DRY 违规被认为是可以接受的。
最佳答案
我也被这个绊倒了一段时间。这是我想出的一种设计模式,我在其他地方没有见过。
public class Bob
{
// member variables
private int value;
// simple constructor
private Bob()
{
value(0);
}
// constructor with value
private Bob(int value)
{
value(value);
}
// get value
public final int value()
{
return this.value;
}
// set value
private final void value(int value)
{
this.value = value;
}
// mutable class modifies base class
public static class Mutable extends Bob
{
// simple constructor
private Mutable()
{
super();
}
// constructor with value
private Mutable(int value)
{
super(value);
}
// set value
public final void value(int value)
{
super.value(value);
}
}
// factory creator for immutable
public static final Bob immutable(int value)
{
return new Bob(value);
}
// factory creator for mutable
public static final Mutable mutable()
{
return new Mutable();
}
// another mutable factory creator
public static final Mutable mutable(int value)
{
return new Mutable(value);
}
}
- 该类不是最终类,子类化应该是安全的。
- 所有的构造函数都必须是私有(private)的。
- 公共(public)访问器应该是最终的。
- 基类中的私有(private)修改器应该是最终的。
- Mutable 类中的公共(public)修改器应该是最终的。
- 使用工厂方法构造不可变和可变对象。
这类似于子类可变模式,但由于 Mutable 类是一个内部类,它可以访问基类中的私有(private)字段和方法,因此不需要保护任何可能被覆盖的内容。基类就像一个标准的可变类,除了构造函数和修改器是私有(private)的。可变子类是一个薄层(每个方法都是 super ...),它暴露了修改器。
创建一个不可变实例:Bob test1 = Bob.immutable(99);创建一个可变实例: Bob.Mutable test2 = Bob.mutable();
关于java - 是否有任何模式可用于实现 holder 对象的可变和不可变版本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26662868/