Observable網(wǎng)絡(luò)框架的解耦和復(fù)用
Observer一端的解耦
我們可以看到BaseObserver實(shí)際做了errorcode響應(yīng)削彬,loading控制,對(duì)外接口的定義等工作蚓挤。這幾部分工作集中在一個(gè)類(lèi)中有一定的耦合析砸。我們?cè)O(shè)計(jì)的目標(biāo)是業(yè)務(wù)使用自定義的Observer或者直接使用BaseObserver都很方便,但目前的設(shè)計(jì)業(yè)務(wù)要么使用BaseObserver全部功能扼雏,要么自己從頭定義燃异,擴(kuò)展性不強(qiáng)携狭。
我們可以如下優(yōu)化:
將callback接口化
BaseObserver定義的onSuccess(T)和onFail(boolean isException ,Object object)兩個(gè)抽象方法是完全面向業(yè)務(wù)使用者的』乩可將其抽象為接口:
public interface ObserverCallback <T extends MapiHttpResponse<? extends Serializable>>{
/**
* 請(qǐng)求成功
* @param t
*/
void onSuccess(T t);
/**
* 請(qǐng)求失敗
* @param isException true:返回Throwable false:返回String(ErrorMsg)
* @param object
*/
void onFail(boolean isException ,Object object);
}
化為接口有兩個(gè)作用
- 規(guī)范自定義的Observer的回調(diào)接口逛腿。
- 可以與其他的網(wǎng)絡(luò)請(qǐng)求調(diào)用方式(callback方式,非observable方式)仅颇,回調(diào)接口上統(tǒng)一鳄逾,降低切換成本。
將loading邏輯和error響應(yīng)邏輯分離
定義LoadingObserver灵莲,其實(shí)現(xiàn)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);
}
}
/**
* 網(wǎng)絡(luò)請(qǐng)求是否loading顯示
* @return
*/
protected boolean isShowProgress(){
return true;
}
}
這樣做:
1雕凹、將更為通用的loading邏輯抽離,使其可以被獨(dú)立使用或繼承政冻。
2枚抵、如果app存在不同業(yè)務(wù)線(xiàn),可將error影響單獨(dú)處理(不同業(yè)務(wù)線(xiàn)code定義可能不同)明场,將loadingObserver類(lèi)下沉汽摹,適配多業(yè)務(wù)線(xiàn)情況
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被分為了三層苦锨,原來(lái)BaseObserver這一層可以由多個(gè)更為具體的Observer來(lái)擴(kuò)展逼泣。每一層都有自己的擴(kuò)展功能趴泌。
ObservableSource一端的解耦
我們看下Observable一端做了哪些事情:
- 對(duì)Request 參數(shù)做發(fā)送前處理:組合和加密處理
- 返回Response 解密處理,Java實(shí)體化
- 返回Response code碼判斷及分類(lèi)
Observable端解耦的目的
- 耦合性降低后拉庶,方便后續(xù)的擴(kuò)展和組合
- 將公共的嗜憔,不易變化的邏輯下沉
這是最終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請(qǐng)求params參數(shù)組合加密處理放到何處氏仗?
前面一章已經(jīng)提到吉捶,params是通過(guò)HttpRequest類(lèi)中的getURLParam()方法完成。
原因有2點(diǎn)
1皆尔、params定義在HttpRequest中呐舔,在Httprequest類(lèi)中拿最方便。
2慷蠕、組合和加密的過(guò)程如果需要定制珊拼,那么直接在HttpRequest子類(lèi)中就可以,和框架不會(huì)有耦合流炕。
Response解密處理杆麸,Java實(shí)體化,在何處處理浪感?
Response解密處理網(wǎng)上有兩種處理方式,
1饼问、在okhttp里使用interceptor攔截器解密 2影兽、ResponseTransformer中處理。
這兩種方式都有問(wèn)題:
雖然app內(nèi)部一般解密方式不變莱革,但是要適應(yīng)多業(yè)務(wù)線(xiàn)峻堰,或者作為適應(yīng)性更廣的框架來(lái)講,這塊解密邏輯放到框架中顯然耦合性太高盅视。
我們采用的方式是定義接口:
public interface ResponseDecryptHandler {
String decrypt(String var1) throws IOException;
}
HttpRequest類(lèi)中定義實(shí)現(xiàn)接口捐名,并將這種解密方式作為Convertor設(shè)置給Retrofit,這樣將加密的邏輯耦合轉(zhuǎn)移到了HttpRequest基類(lèi)中
addConverterFactory(SecurityConvertFactory.create(request.responseDecryptHandler()))
對(duì)于JavaBean實(shí)體化闹击,一般都采用fastJson方式镶蹋,這里我們通過(guò)map操作符完成,作為鏈?zhǔn)秸{(diào)用中的一環(huán)出現(xiàn)赏半,替換方便贺归。
.map(new JavaBeanFunc(t))
Response的code解析,在何處處理断箫?
前面提到拂酣,response的code分為了解析和處理兩個(gè)部分,分別放在observable和observer中完成仲义。其中ResponseTransformer是用于解析response的返回值婶熬。
ErrorResumeFunction和ResponseFunction分別是網(wǎng)絡(luò)錯(cuò)誤和業(yè)務(wù)錯(cuò)誤剑勾,網(wǎng)絡(luò)錯(cuò)誤不會(huì)變,業(yè)務(wù)錯(cuò)誤的判斷是可能擴(kuò)展的赵颅。ResponseFunction的實(shí)現(xiàn)是可以多樣的虽另。
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的生成過(guò)程中性含,除了一部分的邏輯放入的Request的接口中用于擴(kuò)展洲赵,其他的功能在Observable的生成過(guò)程中以鏈?zhǔn)秸{(diào)用的方式存在,每個(gè)鏈?zhǔn)秸{(diào)用的功能由一個(gè)類(lèi)承擔(dān)商蕴。這也是rxjava的優(yōu)勢(shì)所在叠萍,在調(diào)用方式上天然地將各部分解耦了。