RxJava練武場之——Observable網路框架的解耦和複用

challengerwang發表於2019-01-02

RxJava練武場之——Observable網路框架的解耦和複用

RxJava練武場是一個rxjava在專案中應用的小系列,包括:

Observable網路框架的解耦和複用

Observer一端的解耦

我們可以看到BaseObserver實際做了errorcode響應,loading控制,對外介面的定義等工作。這幾部分工作集中在一個類中有一定的耦合。我們設計的目標是業務使用自定義的Observer或者直接使用BaseObserver都很方便,但目前的設計業務要麼使用BaseObserver全部功能,要麼自己從頭定義,擴充套件性不強。 我們可以如下優化:

將callback介面化

BaseObserver定義的onSuccess(T)和onFail(boolean isException ,Object object)兩個抽象方法是完全面向業務使用者的。可將其抽象為介面:

public interface ObserverCallback <T extends MapiHttpResponse<? extends Serializable>>{

    /**
     * 請求成功
     * @param t
     */
    void onSuccess(T t);

    /**
     * 請求失敗
     * @param isException true:返回Throwable false:返回String(ErrorMsg)
     * @param object
     */
    void onFail(boolean isException ,Object object);

}
複製程式碼

化為介面有兩個作用

  1. 規範自定義的Observer的回撥介面。
  2. 可以與其他的網路請求呼叫方式(callback方式,非observable方式),回撥介面上統一,降低切換成本。
將loading邏輯和error響應邏輯分離

定義LoadingObserver,其實現ObserverCallback介面

public abstract class LoadingObserver<T extends MapiHttpResponse<? extends Serializable>>
        implements Observer<T> ,ObserverCallback<T>{

    protected BaseContext mBaseContext;

    public LoadingObserver(BaseContext baseContext){
        mBaseContext = baseContext;
    }

    @Override
    public void onSubscribe(Disposable d) {
        if (isShowProgress()) {
            showProgress(true);
        }
    }

    @Override
    public void onNext(T t) {
        if (isShowProgress()) {
            showProgress(false);
        }
        onSuccess(t);
    }

    @Override
    public void onError(Throwable e) {
        if (isShowProgress()) {
            showProgress(false);
        }
    }

    @Override
    public void onComplete() {
        if (isShowProgress()) {
            showProgress(false);
        }
    }

    protected void showProgress(boolean isShow){
        if (mBaseContext != null) {
            mBaseContext.showLoading(isShow);
        }
    }

    /**
     * 網路請求是否loading顯示
     * @return
     */
    protected boolean isShowProgress(){
        return true;
    }
}
複製程式碼

這樣做: 1、將更為通用的loading邏輯抽離,使其可以被獨立使用或繼承。 2、如果app存在不同業務線,可將error影響單獨處理(不同業務線code定義可能不同),將loadingObserver類下沉,適配多業務線情況

BaseObserver程式碼如下:
public abstract class  MapiObserver<T extends MapiHttpResponse<? extends Serializable>>
        extends LoadingObserver<T>{


    public MapiObserver(BaseContext baseContext){
        super(baseContext);
    }


    @Override
    public void onError(Throwable e) {
        super.onError(e);

        handleError(e);

    }

    private void handleError(Throwable e){
        //handle error code
    }
}
複製程式碼

至此,Observer被分為了三層,原來BaseObserver這一層可以由多個更為具體的Observer來擴充套件。每一層都有自己的擴充套件功能。

ObservableSource一端的解耦

我們看下Observable一端做了哪些事情:

  1. 對Request 引數做傳送前處理:組合和加密處理
  2. 返回Response 解密處理,Java實體化
  3. 返回Response code碼判斷及分類

Observable端解耦的目的

  1. 耦合性降低後,方便後續的擴充套件和組合
  2. 將公共的,不易變化的邏輯下沉

這是最終Observable生成的程式碼:

private static Observable<R> sendRequest(final HttpRequest request,final TypeReference<R> t)
  {
        return NetHelper.getApiObservable(request)
              .map(new JavaBeanFunc(t))
              .compose(ResponseTransformer.handleResult())
              .subscribeOn(Schedulers.io())
              .observeOn(AndroidSchedulers.mainThread());
}
複製程式碼
Request請求params引數組合加密處理放到何處?

前面一章已經提到,params是通過HttpRequest類中的getURLParam()方法完成。 原因有2點 1、params定義在HttpRequest中,在Httprequest類中拿最方便。 2、組合和加密的過程如果需要定製,那麼直接在HttpRequest子類中就可以,和框架不會有耦合。

Response解密處理,Java實體化,在何處處理?

Response解密處理網上有兩種處理方式, 1、在okhttp裡使用interceptor攔截器解密 2、ResponseTransformer中處理。 這兩種方式都有問題: 雖然app內部一般解密方式不變,但是要適應多業務線,或者作為適應性更廣的框架來講,這塊解密邏輯放到框架中顯然耦合性太高。 我們採用的方式是定義介面:

public interface ResponseDecryptHandler {
    String decrypt(String var1) throws IOException;
}
複製程式碼

HttpRequest類中定義實現介面,並將這種解密方式作為Convertor設定給Retrofit,這樣將加密的邏輯耦合轉移到了HttpRequest基類中

addConverterFactory(SecurityConvertFactory.create(request.responseDecryptHandler()))
複製程式碼

對於JavaBean實體化,一般都採用fastJson方式,這裡我們通過map操作符完成,作為鏈式呼叫中的一環出現,替換方便。

.map(new JavaBeanFunc(t))
複製程式碼
Response的code解析,在何處處理?

前面提到,response的code分為了解析和處理兩個部分,分別放在observable和observer中完成。其中ResponseTransformer是用於解析response的返回值。 ErrorResumeFunction和ResponseFunction分別是網路錯誤和業務錯誤,網路錯誤不會變,業務錯誤的判斷是可能擴充套件的。ResponseFunction的實現是可以多樣的。


private static Observable<R> sendRequest(final HttpRequest request,final TypeReference<R> t)
  {
        return NetHelper.getApiObservable(request)
              .map(new JavaBeanFunc(t))
              .compose(ResponseTransformer.handleResult())
              .subscribeOn(Schedulers.io())
              .observeOn(AndroidSchedulers.mainThread());
}
複製程式碼

以上可以看出Observable的生成過程中,除了一部分的邏輯放入的Request的介面中用於擴充套件,其他的功能在Observable的生成過程中以鏈式呼叫的方式存在,每個鏈式呼叫的功能由一個類承擔。這也是rxjava的優勢所在,在呼叫方式上天然地將各部分解耦了。

相關文章