В настоящее время я внедряю итеративные решатели, которые работают, последовательно улучшая оценку решения конкретной проблемы.Поскольку решение представляет собой довольно большой набор данных, уточнение выполняется на месте.
Я реализовал простой шаблон 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");
}
}