mercredi 31 juillet 2019

How to force derived class to call super class method at multiple layers?

I am trying to find the most elegant way to allow a child and parent to react to an event initiated by the grandparent. Here's a naive solution to this:

abstract class A {
    final public void foo() {
        // Some stuff here
        onFoo();
    }

    protected abstract void onFoo();
}

abstract class B extends A {
    @Override
    final protected void onFoo() {
        // More stuff here
        onOnFoo();
    }

    protected abstract void onOnFoo();
}

class C extends B {
    @Override
    protected void onOnFoo() {
        // Even more stuff here
    }
}

So basically, I'm trying to find the best way to allow all related classes to perform some logic when foo() is called. For stability and simplicity purposes I prefer if it is all done in order, although it's not a requirement.

One other solution I found involves storing all the event handlers as some form of Runnable:

abstract class A {
    private ArrayList<Runnable> fooHandlers = new ArrayList<>();

    final public void foo() {
        // Some stuff here
        for(Runnable handler : fooHandlers) handler.run();
    }

    final protected void addFooHandler(Runnable handler) {
        fooHandlers.add(handler);
    }
}

abstract class B extends A {
    public B() {
        addFooHandler(this::onFoo);
    }

    private void onFoo() {
        // Stuff
    }
}

class C extends B {
    public C() {
        addFooHandler(this::onFoo);
    }

    private void onFoo() {
        // More stuff
    }
}

This method is certainly preferable to the first. However I am still curious if there is a better option.

Aucun commentaire:

Enregistrer un commentaire