Разработка базового класса / фабричного класса RxJava для распространенных стадий RxJava - PullRequest
0 голосов
/ 13 сентября 2018

Я изучаю использование RxJava / Retrofit в моем текущем Android-приложении.

Мое Android-приложение должно поддерживать множество вызовов веб-службы RestFul для поддержки как пользовательских, так и справочных данных.

ХотяЯ называю много разных API, на высоком уровне они могут быть сгруппированы в небольшой набор «шаблонов» Call.

Например, все мои вызовы API используют одинаковые Completable InitialProcess, RetryProcess и ErrorProcess.

То, что я хотел бы сделать, - это создать базовый класс, (Step) Builder и / или Factory решение, которое позволяет мне предоставлять только уникальные этапы RxJava и объединять их с «общими» этапами, упомянутыми выше.

Решение позволит мне указать subscribeOn() / observeOn(), а также позволит выбрать blockingWait() или subscribe() и т. Д.

Например, скажите, что мне нужно следующеепоследовательность операций: -

  commonInitialProcess()
                .andThen(Completable.defer(() -> uniqueCompletableProcessX()))
                .andThen(Single.defer(() -> uniqueSingleProcessA())))
                .doOnSuccess(commonSuccessProcess())
                .ignoreElement()
                .andThen(Single.defer(() -> uniqueSingleProcessB())))
                .doOnSuccess(commonSuccessProcess())
                .ignoreElement()
                .andThen(uniqueCompletableProcessY())
                .retryWhen(commonRetryWhenProcess())
                .doOnComplete(uniqueCompleteProcess())
                .doOnError(commonErrorProcess())
                .blockingAwait();

Я бы поставил

uniqueCompletableProcessX()
uniqueSingleProcessA()
uniqueSingleProcessB()
uniqueCompletableProcessY()
uniqueCompleteProcess()

и получил бы полную последовательность, показанную выше, которую я затем могу выполнитьth blockingAwait().

В другом примере

 commonInitialProcess()
                .andThen(Completable.defer(() -> uniqueCompletableProcessZ()))
                .andThen(Single.defer(() -> uniqueSingleProcessC())))
                .doOnSuccess(commonSuccessProcess())
                .retryWhen(commonRetryWhenProcess())
                .doOnComplete(uniqueCompleteProcessZ())
                .doOnError(commonErrorProcess())
                .subscribe();

Я бы поставил

uniqueCompletableProcessZ()
uniqueSingleProcessC()
uniqueCompleteProcessZ()

И получил бы полную последовательность, показанную выше, которую я затем могу выполнить сsubscribe().

Я пытался разработать Step Builder для поддержки типов высокого уровня

Это режим Step Builder

public class FigurateSequence extends Sequence {

    private static final int COMMON_INITIAL_PROCESS = 0;
    private static final int UNIQUE_COMPLETABLE_STEP_A = 1;

    private static final int UNIQUE_SINGLE_STEP_B = 0;

    public FigurateSequence(final FigurateSequenceBuilder figurateSequenceBuilder) {
        COMPLETABLES.addAll(figurateSequenceBuilder.getCompletables());
        SINGLES.addAll(figurateSequenceBuilder.getSingles());
    }

    public static Step_0001 builder() {
        return new FigurateSequenceBuilder();
    }

    public interface Step_0001 {
        Step_0002 first(final Completable completable);
    }

    public interface Step_0002 {
        Build second(final Single<String> single);
    }

    public interface Build {
        FigurateSequence build();
    }

    public static class FigurateSequenceBuilder implements Step_0001, Step_0002, Build {

        private final List<Completable> completables = new LinkedList<>();
        private final List<Single<String>> singles = new LinkedList<>();

        /**
         * 
         */
        private FigurateSequenceBuilder() {

        }

        @Override
        public Step_0002 first(final Completable completable) {
            completables.add(completable);
            return this;
        }

        @Override
        public Build second(final Single<String> single) {
            singles.add(single);
            return this;
        }

        @Override
        public FigurateSequence build() {
            return new FigurateSequence(this);
        }

        /**
         * @return the completables
         */
        public List<Completable> getCompletables() {
            return completables;
        }

        /**
         * @return the singles
         */
        public List<Single<String>> getSingles() {
            return singles;
        }
    }

    public void execute() {

        COMPLETABLES.get(COMMON_INITIAL_PROCESS)
        .andThen(Completable.defer(() -> COMPLETABLES.get(UNIQUE_COMPLETABLE_STEP_A)))
        .andThen(Single.defer(() -> SINGLES.get(UNIQUE_SINGLE_STEP_B)))
        .subscribe();       
    }
}

и базовый класс последовательности

public class Sequence {

    protected final List<Completable> COMPLETABLES = new LinkedList<>();
    protected final List<Single<String>> SINGLES = new LinkedList<>();

    public Sequence() {
        COMPLETABLES.clear();
        SINGLES.clear();

        COMPLETABLES.add(getCommonInitialProcess());
    }


    /**
     * @return
     * 
     */
    private Completable getCommonInitialProcess() {
        return Completable.create(new CompletableOnSubscribe() {

            @Override
            public void subscribe(final CompletableEmitter emitter) throws Exception {
                Thread.sleep(500);
                System.out.println("CommonInitialProcess()");
                emitter.onComplete();
            }
        });

    }

}

Что работает, однако его использование все еще "неуклюже"

FigurateSequence.builder().first(getUniqueCompletableProcess_A()).second(getUniqueSingleProcess_A()).build().execute();

Однако есть некоторые случаи, которые все еще неприятны

Например, когда у меня есть оба по умолчаниюи пользовательские «Последовательности шагов».

, например, если у меня есть значение по умолчанию DoOnError() и пользовательский DoOnError(), как определить внутренние интерфейсы моих конструкторов шагов, чтобы справиться с «необязательным» шагом?

...