有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何处理没有null的链中可能的空值(无模型技巧)?

我试图在之前的MVC项目中添加RX Android pack库,其中我试图处理API响应中的值到Activity controller,并通过某个控制器对其执行一些附加操作

可能的情况是,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) } );
}

所有这些都将是令人难以置信的酷和流畅,除了考虑,rxjava不能处理空值。我们可以说,由于Java8试图克服空值,而支持可选值(真的吗?!?),因此空/可能模式是合适的

那么,让我们试试这个

在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空实例,这也是因为,这是对完整性的绝对违反,因为在任何其他方法中,都必须检查该属性,并且有大量的样板文件

解决方案:

  • 1我试图通过在subscribe的error callable中使用单一的、自定义的异常条件检查来处理这个问题,以决定在链传播、混合函数式编程和反应式编程中的下一个方法的前进方向

  • 2我将不得不修改我的模型,并使用RX null实例来代替我们喜爱的null值,但当然,也因为我使用的是Realm,我甚至不能使用多态性,而且它违反了前面所说的完整性

  • 3理想情况下,我希望保留链模式,通过使用,如果前一个值为空,我可能能够执行链路径,如果该值为空,我可能能够执行另一个链路径

如果有人愿意站在选项3前面,我会很高兴,这就是我第一次看到ReactiveX示例时说“哇”的那个选项


共 (1) 个答案

  1. # 1 楼答案

    经过一番探索,我发现最终最好的解决方案其实是。。。抓紧使用Java8是可选的

    首先,这允许我们一如既往地保持良好的通用类空检查模式,这样我们就不必真正忘记它,而且还可以继续进行新技术的开发,以符合我们喜欢的新标准,并在新的Java规范出台时遵循它们

    这也是一个“非”向后兼容性中断,因为在Android中,我们可以在API级别24之前依靠一些向后移植依赖项来实现这一点

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

    而且,这允许使用链式操作、条件、反应和单个值,就像我们程序员喜欢的那样

        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();
    
                    }
                });
    }
    

    这不是很好吗