引言 在上一篇 细细品读 Retrofit 的设计之美一 后,我们了解了 Builder 构建者模式和(动态)代理模式在 Retrofit 中的做用,以及它们的使用套路。今天继续品读 Retrofit 框架值得我们好好思考的设计:抽象工厂模式 抽象工厂模式 在看 Retrofit 的抽象工厂模式的应用前,先来了解下,抽象工厂模式的套路,不扯虚的直接举一个实用的例子:
这样来设计一个用户系统是不是更清晰点,而且不同的品牌的工厂便于替换,也就是替换登录的平台,不同的产品模块类的功能职责也变的比较单一符合设计模式的单一原则。 案例实现
这些产品模块的接口规范功能抽象,对于 app 的用户系统来说基本够用了。当然上面的这些接口,也可以统一用一个接口文件来写,这些模块就作为子接口嵌套在里面,这是为了方便管理。
主要就是获取不同模块的产品抽象接口对象,便于客户端使用工厂的模块对象的时候多态性。
比如,当我们使用app自己的用户账号登录的时候的实现 再比如,用微信来登录应用 这里我实现了登录产品模块的,其它的模块也是一样的。对于调用者的使用也很简单: 对于调用者来说很简单,只要关心当前用的是什么平台的账号系统,而不需要关心具体的实现方式。也把不同平台的登录、注册、获取用户信息等分离开来。当然往往不同的平台可能退出当前账号的方式是一样,这个时候,其实可以把 BaseLoginer 当做代理对象,目标接口就是 ILoginer,目标对象另外新建一个类实现目标接口,利用代理模式。 Retrofit 抽象工厂的应用 我们都知道网络请求通讯,当服务端返回数据后,都需要进行解析转换为可以直接使用的实体对象,便于设置显示到 UI 界面上,我们在构建 Retrofit 对象的时候往往会给构建器注入一个解析转换器工厂对象。 其中 FastJsonConverterFactory.create() 创建的就是一个 Factory 抽象工厂对象。 接下来看看使用 FastJson 作为转换器的工厂实现类: 通过封装一个 create 方法,来创建工厂对象,外部调用者就不需要关系工厂对象是如何创建的。这点和我上面举的例子是一样的。再一个通过responseBodyConverter、requestBodyConverter 方法分别创建了请求响应和请求发起这两种产品的对象。 再来看看 FastJsonRequestBodyConverter 请求发起转换产品的实现: 实现了转换器这抽象产品接口类,入参是 RequestBody,返回的结果是泛型T(因为请求的参数是针对具体业务的作为框架无法确定,于是用泛型来代替),这个 FastJsonRequestBodyConverter 产品的功能就是convert 转换功能,这里使用了阿里巴巴的 json 解析库 fastJson 来转换,具体的实现就是通过 JSON.toJSONBytes 方法转换出 json 的字节数组,然后交由给 OkHttp 的 RequestBody.create 来构建一个请求体,并且请求的多媒体类型是 json 格式的。OkHttp 中的实现: 你会发现 RequestBody 是个抽象类,writeTo 是个抽象方法,那么必定就有调用此方法的地方。也不能盲目的看源码找,一个请求的构建最好的地方就是发起请求的时候,call.enqueue(callback),通过 enqueue 发起一个异步的请求,但 Call 是接口,也不晓得实现类。还有个办法就是倒退的方式,将光标放置上门的 writeTo 方法上,按组合键(有使用到writeTo 的地方):ctrl + alt + F7: 很明显是最后一个 ReqeustBuilder,请求构建类,跟进去是ContentTypeOverridingRequestBody,它是个代理类,目标对象是其内部的 RequestBody 对象这个对象我们猜测就是上文FastJsonRequestBodyConverter 的 converter 转换创建的RequestBody。再来看看 ContentTypeOverridingRequestBody 在RequestBuild的build() 构建方法中有使用: 继续看 RequestBuild的build() 的调用者是 ServiceMethod 的toRequest() 方法: 先看看 apply 方法,它是 ParameterHandler 的抽象方法,里面有很多参数的创建的实现: ServiceMethod的toRequest() 方法调用者是 OkHttpCall 的createRawCall() 上面的代码意思是,通过一些参数创建了一个请求发起对象,然后再通过一个工厂对象创建了一个用于发起请求的 okhttp3 的 call 对象,再来看看 createRawCall() 方法的调用,它有三个地方调用了: 很明显我们在发起一个网络业务请求的时候,使用的就是enqueue(callback) 方法,大概来看看具体的实现: 这样倒过来分析,不知有没有更清晰点,梳理下:
总结 今天的篇幅也比较长,主要说明了抽象工厂设计模式的使用,具体举了个在开发中比较实用的多平台登录的用户系统模块的问题,当然这只是个例子实际项目中需要完善的还很多。通用的例子还有很多比如:多种支付方式的切换、多种地图 SDK 的切换、多种网络框架的切换、多种持久化数据存储方式的切换、多种数据处理方式的切换、多种图片加载器的切换等等。 后面主要介绍了 Retrofit 中抽象工厂的应用,以及简单分析了,Retrofit 是如何构建请求和发起请求的。 篇幅比较长,感谢您的耐心阅读。 与之相关 日 更 精 彩 微信号:code-xiaosheng 公众号 「code小生」 |
|
来自: codingSmart > 《待分类》