Observable网络框架的解耦和复用
Observer一端的解耦
我们可以看到BaseObserver实际做了errorcode响应,loading控制,对外接口的定义等工作。这几部分工作集中在一个类中有一定的耦合。我们设计的目标是业务使用自定义的Observer或者直接使用BaseObserver都很方便,但目前的设计业务要么使用BaseObserver全部功能,要么自己从头定义,扩展性不强。
我们可以如下优化:
将callback接口化
BaseObserver定义的onSuccess(T)和onFail(boolean isException ,Object object)两个抽象方法是完全面向业务使用者的。可将其抽象为接口:
public interface ObserverCallback >{
/**
* 请求成功
* @param t
*/
void onSuccess(T t);
/**
* 请求失败
* @param isException true:返回Throwable false:返回String(ErrorMsg)
* @param object
*/
void onFail(boolean isException ,Object object);
}
化为接口有两个作用
- 规范自定义的Observer的回调接口。
- 可以与其他的网络请求调用方式(callback方式,非observable方式),回调接口上统一,降低切换成本。
将loading逻辑和error响应逻辑分离
定义LoadingObserver,其实现ObserverCallback接口
public abstract class LoadingObserver>
implements Observer ,ObserverCallback{
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>
extends LoadingObserver{
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一端做了哪些事情:
- 对Request 参数做发送前处理:组合和加密处理
- 返回Response 解密处理,Java实体化
- 返回Response code码判断及分类
Observable端解耦的目的
- 耦合性降低后,方便后续的扩展和组合
- 将公共的,不易变化的逻辑下沉
这是最终Observable生成的代码:
private static Observable sendRequest(final HttpRequest request,final TypeReference 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 sendRequest(final HttpRequest request,final TypeReference t)
{
return NetHelper.getApiObservable(request)
.map(new JavaBeanFunc(t))
.compose(ResponseTransformer.handleResult())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
}
以上可以看出Observable的生成过程中,除了一部分的逻辑放入的Request的接口中用于扩展,其他的功能在Observable的生成过程中以链式调用的方式存在,每个链式调用的功能由一个类承担。这也是rxjava的优势所在,在调用方式上天然地将各部分解耦了。