Fra*_*ens 5 concurrency immutability javabeans
我非常好奇为java bean提供不变性的可能性(这里的bean我指的是带有空构造函数的类,为成员提供getter和setter).显然,这些类不是不可变的,并且它们用于从数据层传输值,这似乎是一个真正的问题.
StackOverflow中已经提到了一种解决这个问题的方法,称为"C#中的不可变对象模式",其中对象在完全构建后被冻结.我有另一种方法,并且非常希望听到人们对此的看法.
该模式涉及两个类Immutable和Mutable,其中Mutable和Immutable都实现了一个提供非变异bean方法的接口.
例如
public interface DateBean {
public Date getDate();
public DateBean getImmutableInstance();
public DateBean getMutableInstance();
}
public class ImmutableDate implements DateBean {
private Date date;
ImmutableDate(Date date) {
this.date = new Date(date.getTime());
}
public Date getDate() {
return new Date(date.getTime());
}
public DateBean getImmutableInstance() {
return this;
}
public DateBean getMutableInstance() {
MutableDate dateBean = new MutableDate();
dateBean.setDate(getDate());
return dateBean;
}
}
public class MutableDate implements DateBean {
private Date date;
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public DateBean getImmutableInstance() {
return new ImmutableDate(this.date);
}
public DateBean getMutableInstance() {
MutableDate dateBean = new MutableDate();
dateBean.setDate(getDate());
return dateBean;
}
}
Run Code Online (Sandbox Code Playgroud)
这种方法允许使用反射(按照惯例)构造bean,并允许我们在最近的机会转换为不可变的变量.不幸的是,每个bean显然有大量的样板.
我很想听听其他人对这个问题的看法.(我抱歉没有提供一个好的问题,可以回答而不是讨论:)
我想我会使用委托模式 - 使用必须在构造函数中指定的单个 DateBean 成员创建一个 ImmutableDate 类:
public class ImmutableDate implements DateBean
{
private DateBean delegate;
public ImmutableDate(DateBean d)
{
this.delegate = d;
}
public Date getDate()
{
return delegate.getDate();
}
}
Run Code Online (Sandbox Code Playgroud)
如果我需要在 DateBean d 上强制不变性,我只需在其上 new ImmutableDate(d) 即可。我本来可以很聪明,确保我没有委托代表,但你明白了。这避免了客户端尝试将其转换为可变对象的问题。这很像 JDK 对 Collections.unmodifyingMap() 等所做的事情。(但是,在这些情况下,仍然需要实现突变函数,并且编码为抛出运行时异常。如果您有一个没有突变者)。
这又是乏味的样板代码,但像 Eclipse 这样的优秀 IDE 只需点击几下鼠标就可以自动生成。
如果这是您最终对大量域对象执行的操作,您可能需要考虑使用动态代理甚至 AOP。那么,为任何对象构建代理、委托所有 get 方法并根据需要捕获或忽略 set 方法将相对容易。