私は現在、反復ソルバーを実装しています。これは、特定の問題に対する解決策を逐次的に改善することによって機能します。解はかなり大量のデータであるため、精緻化が適切に行われます。可変オブジェクトを読み込み専用オブジェクトにカプセル化する
私は、反復が行われている間にアルゴリズムを見ることができるように、単純なObserver/Observableパターンを実装しました。特に、ソルバーは、解の現在の見積もりを返すメソッド
Foo getCurrentSolution()
を提供します。オブザーバは、現在の見積もりに基づいて、いくつかの計算を自由に行うことができます(たとえば、ソリューションが十分であり、反復を停止できるかどうかを判断するなど)。 Foo
は変更可能ですが、もちろん観測者が解の現在の見積もりを変更した場合、ソルバーの反復が損なわれる可能性があります。
したがって、getCurrentSolution()
は本当に防衛的なコピーを返します。しかし、これには大きな問題で時間と記憶が必要なので、getCurrentSolution()
は新しいReadOnlyFoo(bar)
を返します。foo
は解決策の(変更可能な)現在の見積もりで、ソルバー専用です。考え方は、ReadOnlyFoo
がFoo
とほとんど同じインターフェイスを持っているということです。データを変更する可能性のあるメソッドだけが「非アクティブ化」されます(例外がスローされます)。いくつかのダミークラスのすべての詳細を以下に示します。
私の質問です:このアプローチは良い方法ですか?より良いパターンがありますか?
ありがとうございます! Collections
クラスは、それが元のリストが含まれていますが、コレクションを変更するメソッド内での例外をスローするラッパーを返しunmodifiableList(...)
などでないこと実際的なアプローチだ セバスチャン
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");
}
}
それは間違いなくきれいですが、私は 'Solution'の実装を変更できないと思いますか?私はそれを 'MutableSolution'から継承させることはできません。 – Sebastien
次に、getCurrentSolutionによって返される読み取り専用メソッドのみを持つインターフェースを定義し、このインターフェースを実装し、変更可能オブジェクトに委譲するクラスを定義します。 –
私は他の選択肢に満足していないので、私はこのために行くつもりだと思う。どうもありがとう。 – Sebastien