Say I have a Filter
interface
public interface Filter {
public boolean satisfies(Earthquake earthquake)
}
Which can have different implementations (one such below)
public final class MagnitudeFilter implements Filter {
private final double minimumMagnitude;
private final double maximumMagnitude;
private final ComparisonStrategy strategy;
public MagnitudeFilter(double minimumMagnitude, double maximumMagnitude, ComparisonStrategy strategy) {
this.minimumMagnitude = minimumMagnitude;
this.maximumMagnitude = maximumMagnitude;
this.strategy = strategy;
}
@Override
public boolean satisfies(Earthquake earthquake) {
return switch (strategy) {
case EXCLUSIVE -> earthquake.magnitude() > minimumMagnitude &&
earthquake.magnitude() < maximumMagnitude;
case INCLUSIVE -> earthquake.magnitude() >= minimumMagnitude &&
earthquake.magnitude() <= maximumMagnitude;
};
}
}
In some cases I would like to perform an inclusive
comparison and other times I would like to perform an exclusive
comparison, however in the above form, I will need to repeat the switch
expression for every single implementation.
Is there an alternative way that I can generalize this pattern for all implementations so as not to have to repeat the code in the switch statement?
Tried to user another interface but ended up in a loop of repeating code again.
Note that your Filter
is basically identical to java.util.function.Predicate
, so we can just use that. You also don't need a subclass of Filter
; just use lambdas.
In your example, the inclusive/exclusive choice travels with the filter, so all you have to do is define two factories:
Predicate<Earthquake> rangeInclusive(double min, double max) {
return e -> e.magnitude() > min && e.magnitude() <= max;
}
Predicate<Earthquake> rangeExclusive(double min, double max) {
return e -> e.magnitude() > min && e.magnitude() < max;
}
If you want to use data, rather than the method name, to select inclusive/exclusive, you can do that with the switch in just one place:
Predicate<Earthquake> range(double min, double max, ComparisonStrategy strat) {
return switch (strat) {
case INCLUSIVE -> e -> e.magnitude() > min && e.magnitude() <= max;
case EXCLUSIVE -> e -> e.magnitude() > min && e.magnitude() < max;
}