首页 > 解决方案 > 如何摆脱 instanceOf 使用 RxJava 实现 Firebase 注册

问题描述

我们正在尝试使用 RxAndroid 库来实现 Firebase 授权。

问题是所有自己的实现都以instanceOf. 我们正试图摆脱它们。我觉得̶d̶i̶s̶t̶u̶r̶b̶a̶n̶c̶e̶̶i̶n̶̶t̶h̶e̶̶f̶o̶r̶c̶e̶我们以错误的方式使用 Rx 范式。最后,我们决定使用包装库。

我们找到了一个已经为 Firebase实现包装器的库。但实施也落入了instanceOf常规。

这是使用的实现示例:

public void resendVerificationCode(String phoneNumber) {

    final Disposable disposable = RxPhoneAuthProvider.verifyPhoneNumber(
            PhoneAuthProvider.getInstance(),
            phoneNumber, // Phone number to verify
            60,  // Timeout duration
            TimeUnit.SECONDS,  // Unit of timeout
            (Activity) mAuthenticationView,
            forceResendingToken)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(this::phoneVerificationSuccess, this::phoneVerificationError);

    mCompositeDisposable.add(disposable);
}

这是成功处理程序:

private void phoneVerificationSuccess(PhoneAuthEvent phoneAuthEvent){
   if (phoneAuthEvent instanceof PhoneAuthCodeSentEvent) {
       verificationId = ((PhoneAuthCodeSentEvent) phoneAuthEvent).verificationId();
       forceResendingToken = ((PhoneAuthCodeSentEvent) phoneAuthEvent).forceResendingToken();

       mAuthenticationView.showCodeSent();
   }
   if (phoneAuthEvent instanceof PhoneAuthVerificationCompleteEvent) {
       PhoneAuthCredential credential = ((PhoneAuthVerificationCompleteEvent) phoneAuthEvent).credential();
       mAuthenticationView.showVerifySuccess(credential);
       signInWithPhoneAuthCredential(credential);
   }

}

这是错误处理程序:

private void phoneVerificationError(Throwable throwable) {
    if (throwable instanceof FirebaseAuthInvalidCredentialsException) {
        // Invalid request
        mAuthenticationView.showInvalidPhoneNumber();
    } else if (throwable instanceof FirebaseTooManyRequestsException) {
        // The SMS quota for the project has been exceeded
        mAuthenticationView.showSMSQuotaExceeded();
    }

    mAuthenticationView.showVerificationFailedError(throwable.getMessage());
}

请告诉我们我们做错了什么?我觉得这instanceOf很难闻,但我找不到任何其他方法来使用 Rx 实现 Firebase。

标签: javafirebasefirebase-authenticationrx-javarx-java2

解决方案


如果你的目标是不惜一切代价简单地消除instanceof,你可以做这样的事情(广义形式)。

类层次结构:

class Thing {}
class FooThing extends Thing {}
class BarThing extends Thing {}

创建一个调度表,将扩展 Thing 的类映射到处理函数:

interface ThingHandler {
    void handleThing(Thing thing);
}

Map<Class<? extends Thing>, ThingHandler> thingDispatch = new HashMap<>();

向它添加知道如何处理每种类型的事物的处理程序:

thingDispatch.put(FooThing.class, new ThingHandler() {
    @Override
    public void handleThing(Thing thing) {
        // assume Thing is a FooThing by casting it
        FooThing fooThing = (FooThing) thing;
    }
});

// etc
thingDispatch.put(BarThing.class, new ThingHandler() { ... });

现在,当您有要处理的事情时调用它:

Thing thing = ...;
thingDispatch.get(thing.getClass()).handleThing(thing);

恭喜,您已经消除了 instanceof,但代价是增加了一堆额外的代码行!

我会保留判断在任何特定情况下哪个更好。


推荐阅读