Похож template method pattern.
Но тогда вы должны реализовать Foo.checkable()
и ввести другой абстрактный метод делегирования.
abstract class Foo{
public Foo(){}
public void checkable(){
calledWhenCheckableIsCalled();
doCheckable();
}
protected abstract void doCheckable();
public void calledWhenCheckableIsCalled(){
System.out.println("checkable was called");
}
}
Я также хотел бы предложить, чтобы сделать checkable()
окончательный в этом случае, так что вы можете быть уверены, что checkable()
не может осуществляться по-другому, как вы ожидали.
Помимо комментария Brian Роуча
Недостатком является то, что защищаемый может быть расширена до общественности в подклассе, так что вы не можете явно выполнять его.
Это правда, но вы можете предотвратить Foo
экземпляр из того экземпляра, если подкласс увеличивает видимость doCheckable
. Поэтому вы должны вводить проверку всякий раз, когда объект создается. Я бы рекомендовал использовать код инициализатора, чтобы проверка выполнялась на каждом существующем конструкторе. Тогда нельзя забывать призывать и, следовательно, обходить.
Например:
abstract class Foo {
{ // instance initializer code ensures that enforceDoCheckableVisibility
// is invoked for every constructor
enforceDoCheckableVisibility();
}
public Foo() {...}
public Foo(Object o) {...}
private void enforceDoCheckableVisibility() {
Class<?> currentClass = getClass();
while (currentClass != Foo.class) {
try {
Method doCheckableMethod = currentClass.getDeclaredMethod("doCheckable");
if (Modifier.isPublic(doCheckableMethod.getModifiers())) {
throw new RuntimeException("Visibility of "
+ currentClass.getSimpleName()
+ ".doCheckable() must not be public");
}
} catch (SecurityException | NoSuchMethodException e) {}
currentClass = currentClass.getSuperclass();
}
}
}
Поскольку проверка реализуется с помощью отражения недостатком является то, что оно проверяется только во время выполнения. Конечно, у вас не будет поддержки компилятора. Но этот подход позволит вам обеспечить, чтобы экземпляр Foo
мог существовать только в том случае, если он выполняет ваш контракт.
Erm, no. <----> –
@BrianRoach Вздох, я был уверен, что это не сработает. Это сделало бы функциональность, которую я хочу намного проще реализовать. – Others
Единственный способ, которым вы знаете, 'checkable()' вызывается, помещая в него некоторый код. Или создайте вокруг него метод обертки. – Santosh