Java 有没有实现holder对象的可变和不可变版本的模式?
在我的应用程序中,holder对象的类型很少,其主要目的是存储异构相关数据。其生命周期可分为两部分:Java 有没有实现holder对象的可变和不可变版本的模式?,java,design-patterns,immutability,Java,Design Patterns,Immutability,在我的应用程序中,holder对象的类型很少,其主要目的是存储异构相关数据。其生命周期可分为两部分: 一旦数据可用,立即收集数据 在持有者的余生中提供对存储数据的只读访问 使持有者不可变很有诱惑力,但是数据不能一次性传递给构造函数。我看到的最简单的解决方法是创建两个holder类版本,一个是可变的,另一个是不可变的: public class MutableHolder { public int field1; public String field2; // ...
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对象的可变和不可变版本的现有模式
编辑
我突然发现上面的代码是构建器模式的一个非常简单的版本(请参见或)。这使我认为在这种情况下,干法违规被认为是可以接受的。另一种可能的解决方案是。因为它的主要概念是当一个对象的状态改变时改变它的行为。还允许对象在其内部状态更改时更改其行为。对象将显示为更改其类 在你的案例中,你可以考虑以下的实施:
//maintains an instance of a ConcreteState subclass that defines the current state
public class Holder {
//your code
}
//encapsulating the behavior associated with a particular state of the Holder
public abstract class State{
//your code
}
//implements a behavior associated with a state of Holder
public class MutableHolderState extends State {
//your code
}
//implements a behavior associated with a state of Holder
public class ImmutableHolderState extends State {
//your code
}
我也在这个问题上绊倒了一段时间。这是我提出的一个设计模式,我在其他地方没有见过
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);
}
}
- 类不是最终的,子类化应该是安全的
- 所有构造函数都必须是私有的
- 公共访问器应该是最终的
- 基类中的私有变量应该是final
- 可变类中的公共变量应该是final
- 使用工厂方法构造不可变和可变对象
创建不可变实例:Bob test1=Bob.immutable(99);创建可变实例:Bob.mutable test2=Bob.mutable() 依我看,你问错了问题。你的问题是你的数据在你需要的时候不可用。您可能需要重新构造代码以允许创建对象?@bwa遗憾的是,我找不到实现这一点的方法。数据是通过使用流解析器TagSoup解析网页获得的。它不构建DOM,所以我不能在一个地方访问整个页面,而是在找到开始标记、结束标记或字符序列时调用回调。如果不能使对象不可变,就不能使其不可变。不需要两个版本。只需使其可变,并注意尽快填写所需的所有数据。使对象不可变将有助于使您的代码变得更好-如果这项工作太多或使代码在过程中变得更复杂,那么尝试就没有意义了。@B我会考虑这一点。谢谢您的建议,但我认为这种解决方案只会使事情变得过于复杂。在其基础上,它由与构建器模式中相同的两个类(实际持有者和临时构建器)组成,并添加了额外的胶水,在我的例子中,这没有任何价值。