美文网首页
Android 设计模式及MVVM简单试水

Android 设计模式及MVVM简单试水

作者: lforxeverc | 来源:发表于2018-03-18 17:51 被阅读103次

    首先,我们先大致了解下Android开发中常见的模式。

    MVC

    ViewXML布局文件。

    Model实体模型(数据的获取、存储、数据状态变化)。

    Controller对应于Activity,处理数据、业务和UI。

    ·  优点:把业务逻辑全部分离到Controller中,模块化程度高。当业务逻辑变更的时候,不需要变更View和Model,只需要Controller换成另外一个Controller就行了。

    ·  缺点:

    1、 Controller测试困难。因为视图同步操作是由View自己执行,而View只能在有UI的环境下运行。在没有UI环境下对Controller进行单元测试的时候,Controller业务逻辑的正确性是无法验证的:Controller更新Model的时候,无法对View的更新操作进行断言。

    2、 xml作为view层,控制能力实在太弱,Activity基本上都是View和Controller的合体,既要负责视图的显示又要加入控制逻辑,承担的功能很多,导致代码量很大。如想去动态的改变一个页面的背景,或者动态的隐藏/显示一个按钮,这些都没办法在xml中做,只能把代码写在activity中,造成了activity既是controller层。

    3、 view层和model层之间存在耦合。

    MVP

    View: 对应于Activity和XML,负责View的绘制以及与用户的交互。

    Model: 依然是实体模型。

    Presenter: 负责完成View与Model间的交互和业务逻辑。

    ·  优点:

    1、便于测试。Presenter对View是通过接口进行,在对Presenter进行不依赖UI环境的单元测试的时候。可以通过Mock一个View对象,这个对象只需要实现了View的接口即可。然后依赖注入到Presenter中,单元测试的时候就可以完整的测试Presenter业务逻辑的正确性。

    2、避免了传统开发模式中View和Model耦合的情况,提高了代码可扩展性、组件复用能力、团队协作的效率。

    ·  缺点:

    1、 View(Activity)需要持有Presenter的引用,同时,Presenter也需要持有View(Activity)的引用,增加了控制的复杂度;

    2、MVC中Activity的代码很臃肿,转移到MVP的Presenter中,同样造成了Presenter在业务逻辑复杂时的代码臃肿

    MVVM

    View: 对应于Activity和XML,负责View的绘制以及与用户交互。

    Model: 实体模型。

    ViewModel: 负责完成View与Model间的交互,负责业务逻辑。

    ·  优点:

    1、低耦合。View可以独立于Model变化和修改,一个ViewModel可以绑定到不同的”View”上,当View变化的时候Model可以不变,当Model变化的时候View也可以不变。

    2、可重用性。你可以把一些视图逻辑放在一个ViewModel里面,让很多view重用这段视图逻辑。

    3、独立开发。开发人员可以专注于业务逻辑和数据的开发(ViewModel),设计人员可以专注于页面设计,生成xml代码。

    4、ViewModel解决MVP中View(Activity)和Presenter相互持有对方应用的问题,界面由数据进行驱动,响应界面操作无需由View(Activity)传递,数据的变化也无需Presenter调用View(Activity)实现,使得数据传递的过程更加简洁,高效。

    ·  缺点:

    1、ViewModel中存在对Model的依赖。

    2、数据绑定使得 Bug 很难被调试。你看到界面异常了,有可能是你 View 的代码有 Bug,也可能是 Model 的代码有问题。

    3、IDE不够完善(修改ViewModel的名称对应的xml文件中不会自动修改等)

    MVVM使用:

    Xml布局变化:根标签不再是viewgroup,而是,layout标签中新增了标签,标签内可使用导入命名空间,可使用标签声明此xml需要用到的数据。

    在布局中的控件可以使用data内定义的数据,使用@{}的方式获取到数据中的值。

    在对应的activity或者fragment中设置view也有一定改变。需要通过DataBindingUtil工具类去设置view的绑定关系,返回的对象是构建后自动生成的,并且对文件中使用到的参数进行初始化操作,自动生成的类名为布局文件名+Binding。

    在此例子中我们拿用户数据来做说明。binding设置完用户数据后是怎么响应User数据变化的呢?我们来看看User这个bean和我们之前的Bean有什么区别。

    我们可以看到User继承自BaseObservable,实际上MVVM需要变更的数据实现Observable接口,而BaseObservable则是实现了该接口并对数据变更做了一层封装,从而实现数据变更的通知。我们可以看到调用了User的setter方法后还调用notifyPropertyChanged方法去通知更新。在notifyPropertyChanged方法中我们可以看到后面有个BR对象,是根据我们在User中的getter方法使用@Bindable注解声明对外暴露的实体字段,用来标示变更的数据字段。

    这样完整的事件绑定过程就完成了,我们只需要变更用户的数据,ui的变更就会同步刷新。

    如果只是要监听某个字段的变化,可使用部分系统提供的Observable开头的数据类型,比如上面的ObservableLong数据类型。

    谷歌Android推荐架构设计(https://developer.android.com/topic/libraries/architecture/guide.html)

    理解这个架构首先关注几个对象(LifecycleOwner、LiveData、Room)

    简单来说LiveData是一种具有生命周期意识的数据包装类,它可在数据改变时通知到关

    心它变化的Observer。(https://developer.android.com/topic/libraries/architecture/livedata.html)

    Room是Google提供的一个ORM库

    https://developer.android.com/topic/libraries/architecture/room.html

    举个例子:

    在MainActivity我们声明了一个LiveDataViewModel,他有一个MutableLive成员变量time,我们通过调用time的observe()方法传入一个LifecycleOwner对象和Observable观察器,当LifecycleOwner 在active状态下时我们就可以在observe中监听到time的值的变化。

    除此之外,我们还可以让ViewModel实现LifecycleObserver,然后注册进对应的LifecycleOwner,方便我们在不同的生命周期间做不同的操作。

    最后我们可以在ViewModel的onCleared()方法中做资源的回收操作。

    有什么疑问或者不妥的地方欢迎在下方评论。

    相关文章

      网友评论

          本文标题:Android 设计模式及MVVM简单试水

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