Reputation:
I'll describe what I'm trying to do, and hopefully, somebody can tell me what design pattern this is or point out a better alternative.
I have a method doing a bunch of complicated stuff that involves an approximation. It is possible to compute the result without the approximation but this involves more work.
What I want to do is get out some comparisons related to the inner workings of the implementation. My idea is to pass in an object that would do this extra work and store the info about the comparisons.
I think I want to go from:
class Classifier(object):
...
def classify(self, data):
# Do some approximate stuff with the data and other
# instance members.
to
class TruthComparer(object):
def compute_and_store_stats(self, data, accessory_data):
# Do the exact computation, compare to the approximation,
# and store it.
def get_comparison_stats(self):
# Return detailed and aggregate information about the
# differences between the truth and the approximation.
class Classifier(object):
...
def classify(self, data, truth_comparer=None):
# Do some approximate stuff with the data and other
# instance members.
# Optionally, do exact stuff with the data and other
# instance members, storing info about differences
# between the exact computation and the approximation
# in the truth_comparer
if truth_comparer is not None:
truth_comparer.compute_and_store_stats(data,
[self._index, self._model],
intermediate_approximation)
The reason I don't want to do those comparisons inline within the classify
method is that I don't think it fits the job of that method or object to do those comparisons.
So, what design pattern, if any, is this? Can you suggest an alternative?
Upvotes: 4
Views: 335
Reputation: 6312
You could use the Decorator Pattern. You define the Classifier
interface and use a TruthComparerDecorator
that inherits from Classifier
. A TruthComparer
, the decorator, takes a Classifier
as input, computes the approximation with this classifier instance and then runs the compute_and_store_stats
method. Using this pattern you a classifier does not need to know anything about a TruthComparer
. In the end, a TruthComparer
is a Classifier
but does some more things. In Java this could look like:
public interface Classifier {
void classify(Data data);
}
public abstract class TruthComparer implements Classifier {
private Classifier classifier;
public TruthComparerDecorator(Classifier classifier) {
this.classifier = classifier;
}
public void classify(Data data) {
classifier.classify(data);
computeAndStoreStats(data);
}
public abstract void computeAndStoreStats(Data data);
}
Upvotes: 2
Reputation: 45039
My problem with your proposed change is that it doesn't seem right that the classifier requests the compute and store stats part. The classifier shouldn't really be concerned about that. Ideally, it shouldn't even know that the TruthComparer exists.
I'd suggest you really want two methods on Classifier: classify/classify_exact. Classify returns the approximate result; classify_exact returns the exact result. Instead of passing the TruthComparer as a parameter, give TruthComparer the two classifications and let it do its thing.
That way you reduce the number of objects your Classifier has to deal with (lower coupling), and I think makes what is going on clearer.
Upvotes: 0