Как обрабатывать возможные пустые значения в цепочках без нуля (без хитростей модели)? - PullRequest
0 голосов
/ 28 мая 2019

Я пытаюсь добавить библиотеку RX Android pack в предыдущем проекте MVC, в котором я пытаюсь обработать значения из ответов API на контроллер Activity, передавая некоторый контроллер, который будет выполнять над ним некоторые дополнительные операции.

Возможны следующие варианты: значение может быть пустым / необязательным / нулевым с помощью API, в этом случае контроллер попытается получить значение из кэш-памяти, которая также может находиться в том же состоянии, и, наконец, передатьэто к контроллеру, где, в зависимости от значения, он будет выполнять какую-то инициирующую операцию или пытаться выполнить другой вызов API с тем же механизмом, проверить этот ответ и затем выбрать способ инициации действия.

Пример кода (подписи неверны)

В API:

Maybe<User> getUser(){
    //...
}

В контроллере:

Single<User> getUser(){
    return API.getUser().switchIfEmpty(() -> Cache.getUser());
}

В действии:

Disposable d = getUser().subscribe(user -> { if(user != null) init(user); else checkGuest();  } );

//...

void checkGuest(){
    Disposable d = getGuest().subscribe(guest -> { init(guest) } );
}

Все это было бы невероятно круто и гладко, за исключением рассмотрения, RX Java не может обрабатывать нулевые значения .Мы можем сказать, что, начиная с Java 8, где пытаются перебрать нулевые значения в пользу необязательных значений ( действительно?!?!? ), поэтому шаблон Empty / Maybe будет уместен.

Итак, давайте попробуем это ...

В API:

Maybe<User> getUser(){
    //...
}

В контроллере:

Single<User> getUser(){
    return API.getUser().switchIfEmpty(() -> Cache.getUser()).switchIfEmpty(() -> ???);
}

В активности:

Disposable d = getUser().subscribe(user -> { if(user != ???) init(user); else checkGuest();  } );

//...

void checkGuest(){
    Disposable d = getGuest().subscribe(guest -> { init(guest) } );
}

Я хочу сказать, что я ненавижу и вообще не могу принять, чтобы изменить мои модели , чтобы добавить вид дополнительного атрибута, который бы обозначал экземпляр как экземпляр Rx nulled, также потому, что это абсолютное нарушение целостности, как и в любом другом методе, было бы обязательным проверять этот атрибут с помощью looooot шаблонной таблицы.

Решения:

  • 1 Я пытаюсь справиться с этимпросто используя условную проверку одиночного и пользовательского исключения в ошибке подписки, чтобы решить, куда перейти к следующему методу в распространении цепочки, смешивая функциональное и реактивное программирование.

  • 2 Я должен был бы изменитьмои модели, и использоватьRX Обнуляет экземпляры вместо наших любимых нулевых значений, но, конечно, также потому, что я использую Realm, и я даже не могу использовать полиморфизм, а также он нарушает целостность, как было сказано ранее.

  • 3 В идеале я хотел бы сохранить шаблон цепочки и, используя Maybe, иметь возможность выполнить путь цепочки, если предыдущее значение пустое, или другой путь цепочки, если значение не задано.

Я был бы рад, если бы кто-то захотел опередить вариант 3, который заставил бы меня сказать «ВАУ» в первый раз, когда я увидел пример ReactiveX.

1 Ответ

0 голосов
/ 03 июня 2019

После некоторых поисков я обнаружил, что в конечном итоге лучшее решение на самом деле состоит в том, чтобы ... держаться крепче ... использовать Java 8 Необязательно!

Во-первых, это позволяет сохранить старую старую добрую универсальную модель проверки нуля, как всегда, так что нам действительно не нужно забывать об этом, а также продолжать разработку новых технологий и, таким образом, соответствовать новый стандарт, какой мы хотим, и следовать новым спецификациям Java по мере их появления.

Это также «не» разрыв обратной совместимости, так как в Android мы можем положиться на некоторые обратные зависимости, чтобы включить это до уровня API 24.

// support for optionals
compile "net.sourceforge.streamsupport:streamsupport:1.5.1"

И, кроме того, это позволяет использовать цепные операции, условия, ReactiveX и значение Single, как мы предпочитаем кодировщикам.

    public Single<Optional<Model>> getMyModel(boolean offlineFallback) {

    return apiInterface.getModel()
            .map( model -> {
                if( model.isPresent() ){

                    MyModel serverMyModel = model.get();
                    MyModel savedMyModel = databaseRepository.getMyModel();
                    if( serverMyModel != savedMyModel ){
                        serverMyModel.setMyAttribute(true);
                        databaseRepository.saveMyModel( serverMyModel );
                    }
                    return java8.util.Optional.ofNullable( serverMyModel );

                }else{

                    if(offlineFallback){
                        MyModel MyModel = databaseRepository.getMyModel();
                        if(MyModel != null){
                            return java8.util.Optional.ofNullable(MyModel);
                        }
                    }
                    return Optional.empty();

                }
            });
}

Разве это не мило?

...