强制覆盖两种方法中的一种

时间:2017-10-02 20:17:21

标签: java design-patterns override abstract-class optional

我有一种对象,称之为AbstractFoo,它可以根据该实例的属性“接受”或“拒绝”特定类Bar的实例。因此,我在AbstractFoo基类中添加了以下方法:

public abstract boolean acceptsBar(Bar bar);

然而,我发现在某些情况下我需要知道为什么 Bar被拒绝,而这个拒绝消息很复杂,足以保证一种新类型的对象来代表它: BarRejection。然后我将以下方法添加到AbstractFoo基类:

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

如果Bar被拒绝,则此方法返回原因;否则返回Optional.empty()。当然,现在这个方法的结果完全决定了acceptsBar是否应该为真,所以我更新了这个方法:

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

这一切都很好,除了现在我留下了我认为的风格问题。在大多数情况下,我不关心为什么Bar被拒绝,所以我最终写了类似以下内容:

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

这里,Optional<BarRejection>实际上只是布尔值的替身。在这些情况下,允许类实现acceptsBar并将getBarRejection代码推送到超类更为可取:

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

强制AbstractFoo的派生类实现两个方法中的一个是非常理想的,未实现的方法采用其默认行为。显然这不可能直接在Java中完成,但有一种设计模式可以让我完成类似的事情吗?

1 个答案:

答案 0 :(得分:2)

您可以为不想提供拒绝原因的客户制作第二个抽象基类:

TimePicker timePicker = new TimePicker(this);
int currentHour = timePicker.getHour();
int currentMinute = timePicker.getMinute();

想要提供自定义原因的派生类将直接继承flatMap(lambda row: [(f,l) for f, l in zip(row.feature, row.label)]) ,而想要提供默认原因的类将继承public abstract class AbstractFoo { public final boolean acceptsBar(Bar bar) { return !getBarRejection(bar).isPresent(); } public abstract Optional<BarRejection> getBarRejection(Bar bar); } public abstract class AbstractQuickRejectFoo extends AbstractFoo { @Override public Optional<BarRejection> getBarRejection(Bar bar) { return checkAcceptBar(bar) ? Optional.empty() : BarRejection.getDefault(); } protected abstract boolean checkAcceptBar(Bar bar); } 。每个类为其子类提供一个抽象方法来覆盖。