美文网首页
重构,夜未眠

重构,夜未眠

作者: 罗罗罗罗罗sky | 来源:发表于2016-07-28 22:23 被阅读53次

    已经读完了《App研发录》第一章,并且对整本书有了一个大致了解。我觉得有必要记录一下,对于架构方面,很多问题第一次我真的遇到过,但在不断的优化或者重构中,采用了书中相同的方式或者类似的方式解决了问题。比如我们App之前的收银流程,从金额计算到收银详情中间页面众多,要选优惠券或者核销优惠券,积分优惠等等。整个流程就要传十几个值到下单界面,并且有很多值中间是根据顾客选择方式进行变化的,第一次我使用了单个的intent方式传递,导致要定义很多常量接收,并且在接收的值上进行各种逻辑上的操作,所以最后代码逻辑不堪重负,所以第二次我决定重构。
    今天我们来聊聊一个App最简单的架构是什么,或者换句话说应该注意哪些东西:

    1.项目目录结构
    2.关于重新定义Activity的生命周期
    3.工具类的分类
    4.基于AS的使用Gson数据生成结构体
    5.网络请求数据的规范
    6.界面中如何传递数据
    7.列表万能模版
    8.类型安全转换函数
    9. App和html5交互
    ...
    

    一.项目目录结构
    至于说结构,我这里可能更多想说的是包的划分和功能模块的libs的提取。

    包的划分来说有两种分法:

    (1)所有的Activity放到一起, Adapter放到一起 ,工具类放到一起 ,自定义控件放到一起 ,等等。
    
    (2)按模块划分,例如我首页是门店,门店下面包含会员池,发会员卡,发优惠券,收银等等那么将这里所有的功能放到一个Home包下,然后再在这个包下面进行细致划分(Activity,Adapter等等)。
    

    其实我个人看这两种方法各有所长,可根据自己项目大小进行划分,小中型项目建议第一种,超大型项目建议第二种。

    功能模块libs提取:
    都知道,对于我们的项目,我们会定义一个libs,然后主体项目去依赖它,但是这个libs又应该放些什么呢?又应该注意哪些呢?

    (1)BaseActivity  的定义
    (2)图表库
    (3)支付相关封装
    (4)推送或者js交互封装
    (5)第三方分享类库
    

    当然以上三四点只是我项目里面的一个大致封装,可采用类似主体项目包的划分,只不过提供主体项目共有的服务,让主体项目的逻辑等更加简单,像libs库我建议像分享,第三方推送,第三方聊天等等做出单独的libs,进行单独依赖。

    二.关于重新定义Activity的生命周期
    Activity具体声明周期我不在这里进行详细描述,至于重新定义,主要进行细化了Activity的onCreate()方法的操作。有时候会在 onCreate()方法里面写成百上千行的代码。但是我们有没有回过头来想想我们具体的在onCreate()方法里面做了哪些事情,无法set一个布局,获取控件,初始化数据,网络请求加逻辑,所以在BaseActivity重写onCreate()方法,并且在onCreate()方法中添加四个abstract方法,在子类必须去实现这四个方法。

    1.setView(); // 初始化布局
    2.initView(); // 初始化控件
    3.initData(); // 数据初始化
    4.formatContent(); // 具体逻辑处理
    

    这是我在BaseActivity中定义的几个抽象方法,当然可以增加更多方法,也不一定是抽象方法,否则子类就必须都去实现这些方法了。

    三.工具类的分类
    至于工具类的分类,我的建议是每个相似的工具方法定义到一个类中,比如颜色处理类,图片处理类,json处理类,SharedPreferences工具类等等。所有的同类都定义个工具类,进行分开处理各自的分工,刚到公司时候,只在工具包下发现了一个utils类,里面各种工具方法,在使用和维护上面是个有很多的麻烦和隐患。

    四.基于AS的使用Gson数据生成结构体
    现在客户端和服务端通信大多使用的是Gson数据的传递,我们解析数据时候也大多会通过Gson包生成相应的实体,那么我们就需要构建实体类,而构建实体类是有快速构建方法的,只需要安装一个插件即可。方法:http://www.jianshu.com/p/b83ea5e32ee1

    五.网络请求数据的规范
    现在有很多的网络请求框架,大致原理都很相似,如果我们自己去写一个网络请求框架,那么在一个Activity中需要哪些构建呢?我觉得三行代码即可(不包括数据请求之后的操作),(1)发起网络请求 (2)成功的回调(3)失败的回调
    例如登陆的操作:

    1.HttpRequestAsyncTask.requestLogin(this, USER_LOGIN_INDEX, user_name, user_password);
    2.@Override public void requestJsonObject(String result, int index) { }
    3.@Override public void Error(String error, int index) { }
    

    注意上面的index作用,因为我们一个页面中往往有多个网络的请求,必须进行网络请求的区分。

    六.界面中如何传递数据
    说起数据传输我们会考虑使用Bundle传递或者直接使用Intent,但有一下情景:第一个界面计算需要收银100元,第二个界面有优惠券的兑换和使用,兑换了一张折扣券,可能还需要收银70元,然后前面几次购买累计的有积分,积分折扣之后,到下单详情界面,然后确认下单。可以知道这个直接你的收银金额在传递的过程中在不断的修改,并且到下一个面时候又需要封装,所以后来我想了一个办法那就是传递时候定义个实体对象,只往里面增加属性,然后序列化传递,到下个页面直接修改对象中的值,然后再继续传递,所以会少很多的逻辑操作。

    七.列表万能模版
    我们现在常用的Adapter会大致会有listview的Adapter和RecyclerView的Adapter,无论何种。我们都需要考虑这样几个问题:

    1.Adapter的优化
    2.支持添加头部布局和脚布局(下拉刷新,上拉加载更多)
    3.简化分页逻辑(不用判断是否拉到底部等等逻辑)
    4.减少Adapter中逻辑操作等不同情况(列表中不同的item)
    5.缺省页,网络错误页
    6.多种刷新数据方式的封装(RecyclerView全局刷新,局部刷新)
    

    八.类型安全转换函数
    App中有很多情况都是因为数据转换异常,例如(NumberFormatException)。这样的情况我相信很多,并且从服务端传过来的数据对于我们来说往往是不可控的。我们平时会采用try catch的方法来进行异常处理,但是有太多地方了。所以我建议我们在自己的框架中有个这样的方法,当我们将一个字段toString()时候或者强转时候,先判断是否为null,是否可以强转,不可以的话直接给个默认值。

    九. App和html5交互
    随着h5的快速发展,在我们的app中很多时候会插入h5界面,例如h5界面的商城,在支付时候需要调用本地支付宝或者微信支付,那么这个就牵扯到一个js的交互,在这里推荐一个比较好用的js交互框架:JsBridge:https://github.com/lzyzsd/JsBridge

    以上我觉得是一个App框架中应该注意的一些地方吧,对于列表万能模版(RecyclerView)和App和html5交互后面分两次博客来说。

    明天周五啦!!!!

    相关文章

      网友评论

          本文标题:重构,夜未眠

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