我目前正在實現迭代求解器,該求解器通過不斷地改進對特定問題的解決方案的估計。由於解決方案是一個相當大的一組數據,因此要進行改進。將可變對象封裝到只讀對象
我已經實現了一個簡單的Observer/Observable模式,以便能夠在迭代發生時觀察算法。具體來說,求解器提供了一種方法
Foo getCurrentSolution()
它返回解決方案的當前估計值。然後,觀察者可以根據當前的估計自由地進行一些計算(例如:決定解決方案是否足夠好並且可以停止迭代)。 Foo
是可變的,但當然,如果觀察者修改當前解的估計值,這可能會破壞求解器的迭代。
因此,getCurrentSolution()
應該真的返回一個防禦副本。但是這對於大問題需要時間和內存,所以我想出了另一個想法,即getCurrentSolution()
返回一個新的ReadOnlyFoo(bar)
,其中foo
是解決方案專用的(可變的)當前估計的解決方案。這個想法是,ReadOnlyFoo
幾乎與Foo
具有相同的接口,只有可能修改數據的方法被「停用」(它們會拋出異常)。下面給出了一些虛擬類的所有細節。
我的問題是:這種方法是不是很好的做法?有更好的模式嗎?
謝謝! 塞巴斯蒂安
public abstract class AbstractFoo{
public abstract double getValue();
public abstract void setValue(final double x);
public abstract AbstractFoo add(AbstractFoo bar);
public void addToSelf(AbstractFoo bar){
setValue(getValue + bar.getValue());
}
}
public class Foo extends AbstractFoo{
private double value;
public Foo(final double x){
value = x;
}
public double getValue(){
return value;
}
public void setValue(final double x){
value = x;
}
public AbstractFoo add(AbstractFoo bar){
return new Foo(value + bar.getValue());
}
}
public final class FooReadOnly extends AbstractFoo{
private final Foo foo;
public FooReadOnly(AbstractFoo foo){
this.foo = foo;
}
public double getValue(){
return foo.getValue();
}
public void setValue(final double x){
throw new NotImplementedException("read only object");
}
public AbstractFoo add(AbstractFoo bar){
return foo.add(bar);
}
public void addToSelf(AbstractFoo bar){
throw new NotImplementedException("read only object");
}
}
這肯定會更乾淨,但假設我不能更改'解決方案'的實現?我不能讓它從'MutableSolution'繼承...... – Sebastien
然後用getCurrentSolution返回一個只讀方法定義一個接口,並定義一個實現這個接口的類並委託給你的可變對象。 –
我對其他選擇不滿意,所以我想我會選擇這個。非常感謝。 – Sebastien