I have a class that models LogicalExpressions. The leaves are classes that implement an interface IEvaluable, that has a method called Evaluate which returns a boolean as the result.
public class MyEvaluable : IEvaluable
{
public bool Evaluate(Environment env)
{
}
}
Some of these evaluable objects need to do some heavy stuff to produce the result, like calling a web service for instance. And since a logical expression may have multiple such objects that are related, I would like to evaluate them all at once, doing one web service call for all of them instead of separate calls for each parameter.
So I've been thinking about a good way to design such a system and came up with 2 solutions:
1) Make my evaluable objects mutable.
public interface IBatchEvaluable
{
void BatchEvaluate(object[] siblings, Common.Environment env);
bool IsEvaluated { get; }
bool EvaluationResult { get; }
}
public interface IBatchEvaluable<T> : IBatchEvaluable
{
void BatchEvaluate<T>(T[] siblings, Common.Environment env);
}
So every object that is IBatchEvaluable will have a state. When I need to evaluate it I check if it's already been evaluated and do the batch evaluation if it's needed. The only con is that my objects will be mutable, and that's not really desirable.
2) Store evaluation data in the environment
I could keep the objects immutable, and move the IsEvaluated and EvaluationResult data in the environment. So each object would look in the environment first to see if it has already been evaluated and if so get the result from the environment, otherwise evaluate all the siblings in one go and put the data in the Environment.
This is also not very attractive, since the implementation of my objects will depend on outside data, doesn't seem to abide by OOP principles.
How should I go about this from an OOP perspective ? I am open to hearing other potential solutions to this.