在我的应用程序中,我有几种类型的 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原则(如果我想更改任何内容,我不能忘记更新两个类的字段以及构造函数)并且容易出错。所以这是我的问题:是否有任何现有的模式,我不知道实现持有者对象的可变和不可变版本?
我突然发现上面的代码是Builder模式的非常准确的版本(请参阅this或this)。这让我觉得在这种情况下DRY违规被认为是可以接受的。
答案 0 :(得分:1)
另一种可能的解决方案是State design pattern。因为它的主要概念是在状态改变时改变对象的行为。还允许对象在其内部状态更改时更改其行为。该对象似乎会改变其类。
在您的情况下,您可以考虑以下实施:
//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
}
答案 1 :(得分:1)
我也曾经磕磕绊绊过一段时间。这是我提出的一种设计模式,我没有在其他地方看到过。
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);
}
}
这类似于子类可变模式,但由于Mutable类是内部类,因此它可以访问基类中的私有字段和方法,因此不需要保护任何可能被覆盖的内容。基类就像标准的可变类,除了构造函数和mutator是私有的。可变子类是一个薄层(每个方法都是超...)暴露了变异器。
创建不可变实例:Bob test1 = Bob.immutable(99);创建可变实例:Bob.Mutable test2 = Bob.mutable();