在一个抽象类中,我有一个Predicate
字段,它意味着未知数量的其他Predicate
的组合。 连接谓词工作得很好,但我试图有一些方法来知道谓词何时被初始化(或者更确切地说,只是一种知道它是否已被初始化的方法)。
以下是我所说的一个简短的例子:
public abstract class LimitedSystem implements Moveable {
private Predicate<Double> limits;
private final boolean initialized;
public void setLimits(SingleLimit... limits) {
List<Predicate<Double>> limitsList = Arrays.asList(limits);
this.limits = limitsList.stream().reduce(Predicate::and).orElse(x -> true);
}
public void setLimits(TwoLimits limits) {
this.limits = limits;
}
...
我正在寻找将initialized
设置为true
一次(并且仅一次,因此final
.我想我用对了)任何setLimits
都被调用(它们超载)。
我还有其他setLimits
方法,但为了通用代码,我不想在每个重载方法的末尾放置initialized
。
所以我的问题是,在调用任何setLimits
方法后,我如何以通用方式设置initialized
的值。
我的第一个想法是尝试将setLimits
包装在某个通用方法中,该方法将通过它获得的参数调用正确的重载,然后在该方法中更改initialized
。但我不确定这是否是一个好主意。
我从另一个问题1中得到的其他一些想法是将setLimits
放在某个界面或类似的东西中。但我不确定这会证明有多大用处。
那么如何做到这一点呢?
(另外,如果您碰巧注意到其中的任何设计问题,请告诉我,因为我正在努力改进)
不需要单独的字段:
private Predicate<Double> limits;
private final boolean initialized;
基本上是
private Optional<Predicate<Double>> limits = Optional.empty();
如果您希望initialized
设置为limits
后true
, 前提是您可以保证没有任何setLimits
方法可以将其设置为再次Optional.empty()
。initialized == limits.isPresent()
.
您不能保证在重写方法的主体中调用方法;在任何情况下,这都是 Call 超级反模式的变体。
你可以这样做:
abstract class Base {
final void setFoo(Object param) { // final, so can't be overridden.
setFooImpl(param);
thingThatMustBeCalled();
}
protected abstract void setFooImpl(Object param);
final void thingThatMustBeCalled() { ... }
}
class Derived extends Base {
@Override protected void setFooImpl(Object param) { ... }
}
但它非常丑陋。