DataBinding最佳实践

作者: 天之界线2010 | 来源:发表于2016-08-14 14:08 被阅读2750次

本文会不定期更新,推荐watch下项目。如果喜欢请star,如果觉得有纰漏请提交issue,如果你有更好的点子可以提交pull request。
本文的示例代码主要是基于作者的经验来编写的,若你有其他的技巧和方法可以参与进来一起完善这篇文章。文章中大量参考和引用了DBinding权威使用指南的内容,如果你想了解更多建议深入阅读一下DBinding权威使用指南

说明:下文中vm是view model的缩写

本文固定连接:https://github.com/tianzhijiexian/Android-Best-Practices

一、需求背景

开发者都希望可以更快更简单地编写代码,并且还希望代码的可维护性和健壮性能符合团队的期望。很多初创团队在发展多年后逐渐认识到了早期代码模式的弊端,并且在代码的组织结构上有了很多思考。
在模式方面,2015年大家开始争相讨论mvc,mvp,mvvm,期间谷歌也推出了自家的数据绑定框架databinding,借此来简化代码的编写。在这一片百家争鸣中,开发者十分希望能找到一个满足项目需求并且稳定可靠的框架来简化开发工作。

二、需求

开发者对于一个框架最看重的是下面几点:

  1. 能加快开发速度,屏蔽底层细节
  2. 代码可读性好,易维护
  3. 代码量越少越好,易阅读
  4. bug少,有不错的健壮性

三、实现

指定明确的分层

如果一个项目有了明确的分层结构,那么代码的可读性和可维护性会上升很多,它也是一个架构的基础。分层良好的的优点有很多,而且即使某天要更换框架,也不会伤筋动骨。
需要格外注意的是:只有当一个项目的成员都能明确项目的层级后才可以谈框架和模式,否则一个框架再优秀也无法在混乱中发挥出优势。

mvc
层名 内容
view层 具体的view,activity,fragment等,做ui展示、ui逻辑、ui动画
vm层 具体的视图模型类,是view展示的数据的java映射,能被model层直接操作
model层 非ui层面的业务逻辑的实现。包含网络请求,数据遍历等操作,是很多具体类的抽象载体

DBinding是一个databinding的扩展类,它提供了快速绑定vm和通过vm维持多个页面之间数据同步等功能,并且它还有强大的as插件来做支持,因此本文将选择它作为mvvm框架。

通过数据来更新UI

目前流行的做法都是通过数据来驱动UI,其优点在于方便做单元测试和多人协作,对bug的定位也有比较好的帮助。mvvm是一个抽象的概念,它目前最稳定可靠的实现就是databinding,在用databinding之后,我已经很少到view层定位bug了。databinding的代码由xml代码和java代码构成。
layout:

<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <!-- 定义变量: private org.kale.vm.UserViewModel user -->
        <variable
            name="user"
            type="org.kale.vm.UserViewModel"
            />
    </data>
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="@{user.name}"/>
</layout>  

Activity:

    private UserViewModel mUserVm = new UserViewModel();
    
     @Override
    protected void onCreate(Bundle savedInstanceState) {
    
        DBinding.bindViewModel(this, R.layout.activity_main, mUserVm);
        mUserVm.setName("kale");  // textview中就会自动渲染出文字了
    }

layout文件中的vm取名应该和layout文件名字有关联,layout文件的名字也应该和activity的名字有关,这样可以方便定位问题和查找逻辑。layout中vm的参数完全可以模仿之前取id名字的思路,只不过千万不要加view的缩写,出现tv_username或username_tv就闹笑话了。layout文件中强烈不建议写import语句,vm类名强制写全称。至于java代码就十分简单了,没有过多的要求,只要对vm操作即可更新ui。

通过代码模板快速生成layout文件

为了快速产生mvvm的layout文件,我利用了as提供的代码模板功能。

forbid

强类型语言和弱类型语言的一个差异(仅仅是差异)就是在于IDE可以帮你做很多限制,databinding本身是相当灵活的,支持双向绑定,支持xml中写逻辑等操作,但是我这里利用插件或者是其他的方式强烈禁止在xml中写方法和特殊逻辑,对于import我只允许了View这一个类的import。对于双向绑定,我建议你在编码的时候就应该有所警惕,最好能有注释,方便你的同伴进行定位问题。
如果你是一人开发一个不需要维护的应用,那么xml中随便你怎么写,但如果你是团队开发,你会发现那些在xml中的逻辑很可能是团队合作的灾难。当然了,如果你已经通过某种文档或者是其他的标准化方式来限制和规定xml中的逻辑格式,那么我倒是觉得是可行的。

自由是在限制之中的,如果没有限制那么就没有社会。

四、总结

我经历了项目从mvc到mvp,然后变成mvvm,最后到mvpvm的各个阶段,在每个阶段中我也花了大量的时间去发现问题解决问题,为后续的扩展和灵活性做了很多的工作。在做这些事情的时候我渐渐发现,无论你采用什么模式,你都必须有明确的分层的概念,其实大到分层小到单一职责概念,都是在提升代码可维护性。在现在这个时期,我的建议是中小型公司可以放心尝试databinding,大型公司的话因为体量和人员的问题很难会改变模式。当然了,如果目前你的代码本身就有很好的可维护性,我也不建议因为技术的新颖而动项目,因为我们的目的不是尝鲜和炫技,而是为了解决问题!

话说,你写了多少年的findViewById?

developer_kale@foxmail.com

相关文章

网友评论

  • NeWolf:感谢分享
  • RabbitL:楼主可以把代码分享出来么,跟我理解的不一样呢
    RabbitL:@RabbitL Ok:smile:谢谢楼主
    天之界线2010:@RabbitL 460412008@qq.com
    天之界线2010:@RabbitL github 搜 dbinding
  • 9711922c6b29:viewmodel的生成插件可以添加支持default么,我现在如果用default看预览,生成插件会把default也当做变量名生成。
    天之界线2010:@水手辛巴 是的,这个我以后会说明一下。你可以和我说下你用的感受
    9711922c6b29:@水手辛巴 原来是`,`不能挨着变量名,需要空一格才不会生成 :sweat:
  • hahaee:看了楼主的DBinding权威使用指南
    似乎楼主对于VM的理解是只是View的数据模型

    可是按我对MVVM设计图的理解
    VM更多却像是Present负责View和Model之间的业务逻辑控制
    只不过因为MVVM中的数据绑定特性 而和MVP有所区别罢了

    我尝试在VM中使用内部类作为Present负责控制业务逻辑 此时VM和Present是一对一的关系
    但是 按照Databinding的思想 一个layout中是可以使用多个VM的 那么VM和Prensent就应该是多对一的关系
    那么VM就不能直接调用Present(因为Present不可能知道VM) 那么此时VM就成了楼主那种单纯的View数据模型
    我在考虑 是否能让layout-VM一对一,如此的话VM与Present也就是一对一了 也就符合MVVM的思想
    天之界线2010:因为觉得vm应该功能单一
    hahaee:@天之界线2010 我感觉你这个就是MVP了 layout和VM是VIew 而你的model可以拆分为Present和model
    感觉MVVM的优势全都没了
    MVVM对比MVP 的优势不是就在于 通过数据绑定来简化Present操纵View吗

    说说你重写代码的理由?
    天之界线2010:viewmodel顾名思义就是视图模型,我之前也是你这个想法后来恍然大悟,重写了所有的代码
  • sing_song:顶。
  • 捡淑:马克

本文标题:DataBinding最佳实践

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