美文网首页RxJAva OKHttp Retrofitandorid学习Net
实现Android主流网络框架封装,可无缝侵入切换框架

实现Android主流网络框架封装,可无缝侵入切换框架

作者: AWeiLoveAndroid | 来源:发表于2017-06-17 16:07 被阅读2290次

一、什么是“有多种可替代解决方案的业务逻辑”?

举几个例子说明:

★  客户端的http请求操作,可以实现的方案有Retrofix、OkHttp、Volley等;

★  客户端的数据库存储方案可以为Realm、greenDao、OrmLite等;

★  图片加载的方案可以是Fresco、Glide、Picasso、UIL等。  

二、如何快速替换?

先来描述一下需求,比如说,目前正在用的http请求是Volley,现在发现使用OkHttp来封装一套会更好。又比方说,目前正在用的数据存储方案是OrmLite,现在使用greenDao或者Realm会更好,在类似这些情况下,如何做到不修改Activity/Fragment/Presenter代码的情况下,把Volley的http请求实现更换成Okhttp的实现,把OrmLite更换成greenDao或者Realm?

解决问题的关键词:设计模式中的——工厂方法模式。

本质:利用接口进行解耦。

说到这里,可能很多有经验的朋友已经会心一笑,是的,老实说这篇文章可能对老司机没有太大的意义,但是如果看到这里还是心存疑问,或者你不知道什么是工厂方法模式,也不知道如何使用接口解耦什么的,没关系,请继续往下看。

三、Talk is cheap, show me the code.

    下面,我们就用Volley更换到OkHttp这个例子来说明一下如何做到不修改Activity/Fragment/Presenter的代码情况下,更快地更换业务逻辑实现的代码。

    在开始之前先来思考一下上述所说“可替代解决方案”的含义,为何这些方案是可替代的?是因为它们具有相同的共性,它们所要解决的问题是相同的,比如说http请求框架,无论是Volley/OkHttp/Retrofix,它们所要实现的都是http请求中的get/post/put/delete这些方法,数据库存储框架中无论是Realm/greenDao/OrmLite,它们要实现的都是增删改查这些方法。

    “博主你别再瞎逼逼,赶紧说重点…”

    我:dalao我错了,下面说重点…

   先来概括一下我们的实现思路:

        把http请求框架的共性方法抽取到接口中,我们把这个接口称为“请求接口”;

        创建一个用于返回请求结果的接口,我们把这个接口称为“回调接口”;

        分别用Volley和OkHttp实现“请求接口”;

       创建一个类来返回上述接口的对象,我们把这个类叫做“工厂”类;

        在Activity/Fragment/Presenter中,使用“工厂”返回的这个接口对象调用get/post/put/delete方法,并在“回调接口”中得到请求结果。

    本文完整代码   https://github.com/AweiLoveAndroid/HttpRequestProcessor ,可以先clone到本地再看文章,为了方便阅读,下文中的代码将省略非重点部分。

四、具体步骤:

Step1:把http请求框架的共性方法抽取到接口中(也就是上述说的get/post/put/delete这些方法)

       上面的IRequestManager接口中用到的请求结果回调接口——IRequestCallback


    至此,我们已经把数据请求的接口,以及数据返回的接口都定义好了,整理一下思绪

        ● 1.首先我们搞清楚http请求,有哪些方法,需要有哪些参数——IRequestManager;

        ● 2.数据返回会有什么情况?——IRequestCallback;

Step2:用Volley来实现IRequestManager这个接口

        VolleyRequestManager实现了IRequestManager接口,到这里我想你也看出来可以使用VolleyRequestManager来进行get/post/put/delete操作了,是的,已经可以用于请求操作,但是我们先不这样做,原因请继续往下看Step3。

Step3:创建一个类来返回IRequestManager请求接口的对象

       到这里,请容许我再逼逼一下,为什么要用这种方法来返回对象,而不直接在Activity/Fragment/Presenter中创建VolleyRequestManager对象来进行操作?如果直接在Activity/Fragment/Presenter中使用VolleyRequestManager来创建对象,你的代码就依赖了VolleyRequestManager,这种情况下,如果要更换成OkHttp,岂不是要把代码中所有的VolleyRequestManager对象也更换成OkHttp的请求对象?再试想一下,如果你有很多个Activity/Fragment/Presenter使用了VolleyRequestManager对象,你是不是要每个地方都更换一遍?

        使用RequestFactory的方式在Activity/Fragment/Presenter中创建对象,代码只依赖了IRequestManager这个接口,这就是使用接口进行解耦的关键点,无论在什么地方使用了这个接口,当要更换实现的时候,只需要修改RequestFactory中return的实现类就可以了。

Step4:调用上述方法进行测试

        注意我们创建请求对象的代码,这里没有出现具体的实现类:

       IRequestManager requestManager = RequestFactory.getRequestManager();

Step5:不更改MainActivity中任何代码,把Http请求的逻辑替换成OkHttp来实现

    1)先用OkHttp来实现IRequestManager这个接口.

    2) 使用OkHttp更换Volley

        现在我们用OkHttp的请求方式也实现了一套get/post/put/delete的请求方法,此时只要修改Step3中,返回的对象为OkHttpRequestManager对象,就已经完成了我们整个http请求框架的更换,此时,你可以完全移除Volley的引用以及代码,而不会对程序有任何影响。


总结:

对于有多种可替代解决方案的业务逻辑,我的解耦思路是这样的:

    1. 抽取它们的共性方法到接口中;

    2. 使用自己选择的实现方案去实现;

    3. 使用“工厂”类把具体实现转换成抽象接口,并返回抽象接口对象;

    4. Activity/Fragment/Presenter中,使用“工厂”中返回的接口进行操作,而不要依赖于其实现类。

    5. 要更换方案的时候,只需要修改“工厂”中返回的实现类。

后记:

这篇文章只是提供一种解耦思想,而不是“如何封装http请求框架”的教程,也不是讨论“哪个http请求框架好用”的文章,当然,你完全可以用这种方法进行http请求的封装。欢迎大家提出宝贵意见。

我在原作者的基础上加了另一种和实现方式,这是github地址 可以去下载看看

我写的 网络请求隔离框架github下载地址


引用原文网址:对于有多种可替代解决方案的业务逻辑,提供一种快速更换的思路

相关文章

网友评论

  • 树叶秋:虽然有多款网络框架,但是无疑retrofit做到了极致,无人能及。这样兼容的做法,只会引起不必要的麻烦,重度依赖retrofit才是最好的选择
    树叶秋:@AWeiLoveAndroid 老项目重度依赖某个库,如果要重构,则重构为retrofit,如果不需要重构,那就继续用,何苦兼容呢。接口适配确实可以减少替换网络请求库的成本,但是会增加当时编码及日后维护的成本(对于retrofit来说),而retrofit又做得这么好,虽然不久后也会沦为你说的老项目,但是它封装的接口到了最精简的地步了吧,所以就算哪天okhttp不好用了,retrofit也会在底层适配好用的那个库。所以我觉得做接口适配的做法,只会增加成本
    AWeiLoveAndroid:@树叶秋 这是在项目发现过程中产生的。。你去维护一个老丈项目就知道这个库有多6了
  • 唐涛_fdff:楼主。 如果要切换成 retrofit+rxjava。怎么搞啊。代理类怎么写啊
  • RabbitL:问下,当需要在工厂中保留多个实例的时候,比如 RequestFactory 中既可以返回 VolleyRequestManager,也可以返回 OkHttpRequestManager 的时候。而每个 Manager 又有自己的独特的方法,也就是不可以封装在公共 IRequestManager 中的方法,这时正确的设计方法是什么样的?
  • zmy26:学习了感谢作者分享,可有个地方不明白:VolleyRequestManager. getInstant方法返回的为什么是IRequestManager呢?
    RabbitL:@AWeiLoveAndroid 问几个问题:
    1、如果替换某一个框架时,原有的参数不能满足条件的时候,还是需要改动接口的吧,参数部分如何定义,才能尽可能的避免这种改动呢?
    2、如上我评论中的问题,当需要保留多种实现的时候,某一种实现中需要有一些自己特定的方法需要实现,这个方法按照规则是不能定义在顶层接口中的,因为不是每种「Manager」都应该实现此方法。所以此时应该怎么设计更合理一点?为此「Manager」单独定义一个特殊方法的接口?这样的话通过统一代理类去返回实例的时候,就需要强转成定义了特定方法的特定类,才能调用对应的方法了,感觉不是一个好的设计呢。
    AWeiLoveAndroid:@RabbitL 不管我换什么框架 我都可以自由切换 代码中使用网络请求的地方原封不动不变 只是我框架内部在进行转变 这样开发者就正常开发 不用关心框架内部实现 我采用的是代理类实现的。
    RabbitL:多态的思想,返回共同的父类,这样如果你替换了 OkHttp,可以通过工厂模式生成不同的 IRequestManager 实现。
  • 绮怀先生:建议加上泛型,数据返回的是字符串,而不是实体类,转json字符串成实体类会变成重复劳动.
    这种封装思想学习了,谢谢博主
  • 小丑xyx:叼叼叼叼叼叼,楼主谢谢您的奉献,让我学到更多的知识
  • 0c2f40bfeffa:mark,楼主写的真好
  • 梦华芳秋:楼主,天下韦姓一家人!这个工具类很叼!
    梦华芳秋:@阿韦爱Android :joy:
    AWeiLoveAndroid:不好意思 我不姓韦:joy:

本文标题:实现Android主流网络框架封装,可无缝侵入切换框架

本文链接:https://www.haomeiwen.com/subject/osfbqxtx.html