lundi 2 octobre 2017

Enforce override of exactly one of two methods

I have a type of object, call it Foo, which can "accept" or "reject" instances of a particular class Bar based on the properties of that instance. Therefore, I add the following method in the Foo base class:

public abstract boolean acceptsBar(Bar bar);

However, I then find that in certain cases I need to know why Bar was rejected, and this rejection message is complicated enough to warrant a new type of object to represent it: BarRejection. Then I add the following method to the Foo base class:

public abstract Optional<BarRejection> getBarRejection(Bar bar);

If Bar was rejected, this method returns the reason; otherwise it returns Optional.empty(). Of course, now the result of this method completely determines whether acceptsBar should be true, so I update that method:

public final boolean acceptsBar(Bar bar) {
    return !getBarRejection(bar).isPresent();
}

This is all well and good, except now I'm left with what I consider a style problem. In the majority of cases, I don't care why Bar was rejected, so I end up writing something like the following:

@Override
public Optional<BarRejection> getBarRejection(Bar bar) {
    return ([acceptance condition]) ? Optional.empty() : BarRejection.default();
}

In this case, the Optional<BarRejection> is effectively just a stand-in for a boolean. In these cases, it would be much more preferable to allow classes to implement acceptsBar and push the getBarRejection code up to the superclass:

public final Optional<BarRejection> getBarRejection(Bar bar) {
    return acceptsBar(bar) ? Optional.empty() : BarRejection.default();
}

It would really be ideal to allow the derived classes of Foo to implement exactly one of the two methods, with the unimplemented method taking on its default behavior. Obviously this isn't possible to do directly in Java, but is there a design pattern that would allow me to accomplish something similar?

Aucun commentaire:

Enregistrer un commentaire