Невозможно сослаться на это, пока конструктор супертипа не был назван - PullRequest
0 голосов
/ 05 ноября 2018

Я пытаюсь определить общий абстрактный класс, который обрабатывает логику обработки / повторения реализующего класса. Я хочу, чтобы все реализующие классы передавали функции «process» и «fail», которые выполняются абстрактным классом. Абстрактный класс также содержит логику повторных попыток и некоторый другой общий шаблонный код, который я хотел бы использовать повторно.

В частности, у меня есть следующий абстрактный класс:

public abstract class EnvelopeDispatcher<T> {

    protected Consumer<T> processFn;
    protected Consumer<T> failFn;

    private MetricsRegistry metricsRegistry;


    public EnvelopeDispatcher(MetricsRegistry metricsRegistry, Consumer<T> processFn, Consumer<T> failFn) {
        this.metricsRegistry = metricsRegistry;
        this.processFn = processFn;
        this.failFn = failFn;
    }

    protected void process(T envelope) { 
        //abstract processing logic calling processFn and failFn
    }
}

И следующий класс реализации:

public class ActionEnvelopeDispatcher extends EnvelopeDispatcher<ActionEnvelope> implements Consumer<ActionEnvelope> {
        public ActionEnvelopeDispatcher(MetricsRegistry metricsRegistry ) {
                super(metricsRegistry, this::processEnvelope, this::failEnvelope)
        }

        @Override
        public void accept(@NonNull ActionEnvelope envelopeToProcess) {
            super.process(envelopeToProcess);
        }

        private void processEnvelope( ... ) {
            //processing logic
        }

        private void failEnvelope( ... ) {
            //failure case logic
        }   
    }

Когда я пытаюсь вызвать super, ссылаясь на this :: processEnvelope и this :: failEnvelope, я получаю «Невозможно ссылаться на это до вызова конструктора супертипа».

Я понимаю, почему это происходит, но я не уверен в альтернативах. Кто-нибудь знает, как обойти это или лучший шаблон реализации?

1 Ответ

0 голосов
/ 05 ноября 2018

Что вы можете сделать, так это не делать диспетчер абстрагированием и создавать его с помощью фабричных методов.

Примерно так:

class EnvelopeDispatchers {

    // factory method
    public static EnvelopeDispatcher<ActionEnvelope> actionEnvelopeDispatcher(MetricsRegistry metricsRegistry) {
        return new EnvelopeDispatcher(metricsRegistry,
                                      EnvelopeDispatchers::processEnvelope,
                                      EnvelopeDispatchers::failEnvelope);
    }

    private static void processEnvelope(ActionEnvelope env) {
        //processing logic
    }

    private static void failEnvelope(ActionEnvelope env) {
        //failure case logic
    }   
}
...