我有一种对象,称之为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中完成,但有一种设计模式可以让我完成类似的事情吗?
答案 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);
}
。每个类为其子类提供一个抽象方法来覆盖。