《Android源码设计模式》读书笔记 (25) 第25章 Android架构之MVC,MVP,MVVM

前言

  • 在说MVC和MVP,MVVM架构之前,我们先得理清楚什么是框架模式,什么时设计模式.
  • 框架模式:通常是对代码的重用,用来对软件的设计进行分工.
  • 设计模式:通常是对设计的重用,是小技巧,对具体的问题提出解决方案,以提高代码复用率,降低耦合度.

  • MVP模式简单总结就是:Presenter与view和数据Dao层先建立链接实现抽象接口,内部实现业务逻辑和数据处理;
  • View只负责数据显示和初始化.数据Dao负责数据模型和本地存储
  • 其次,就是在使用过程中需要建立Presenter和Activity对象基类,用来在Activity生命周期中绑定二者,避免内存泄露

MVC模式

  • 定义:model-view-controller.其分别代表的意思.
    1.视图(view):用户界面
    2.控制器(Controller):业务逻辑
    3.模型(Model):数据保存
  • 通信方式:
    这里写图片描述
  • 所有通信都是单向的.View 传送指令到 Controller,Controller 完成业务逻辑后,要求 Model 改变状态,Model 将新的数据发送到 View,用户得到反馈.
  • 优点:理解容易,技术含量并不高,不便于维护.

MVP模式

  • 定义:model-view-presenter
    1.Presenter:交互中间人,作为沟通View和model的桥梁,它从model层检索数据后,返回给View层,使得View和model之间没有耦合,也将业务逻辑从View角色上抽离出来
    2.View:用户界面,通常指activity\fragment或者自定义View类中,它含有一个presenter成员变量,需要实现一个逻辑接口,将View上的操作通过转交给presenter进行实现,最后presnter调用view逻辑接口将结果返回给view元素
    3.model:数据的存储.封装了数据库DAO或者网络获取数据的角色,或者两种数据获取方式的集合.主要提供给presenter进行逻辑处理
  • 通信方式:
    这里写图片描述
  • 各部分之间的通信,都是双向的
  • View 与 Model 不发生联系,都通过 Presenter 传递
  • View 非常薄,不部署任何业务逻辑,称为”被动视图”(Passive View),即没有任何主动性,而 Presenter非常厚,所有逻辑都部署在那里

  • 优点:
    1.理想化的MVP模式可以实现同一份逻辑代码搭配不同的显示界面.因为它们之间并不依赖于具体,而是依赖于抽象.
    2.可以让UI界面和数据分离.业务逻辑和数据存储是紧耦合的,缺乏经验的工程师可能会将各种各样的业务逻辑塞入activity\fragment或者自定义View类中.业务逻辑和View元素严重的紧耦合在一起导致了类型膨胀的问题

MVVM模式

  • MVVM 模式将 Presenter 改名为 ViewModel,基本上与 MVP 模式完全一致.
    1.ViewModel的角色:业务逻辑处理,以及修改view或者model的状态.
    这里写图片描述
  • 唯一的区别是,它采用双向绑定(data-binding):View的变动,自动反映在 ViewModel,反之亦然。Angular 和 Ember 都采用这种模式。
  • MVVM模式优点类似adapter,

MVC,MVP,MVVM三者间对比

  • MVC耦合性相对较高,用户可以向view\controller发送指令,controller相当于事件路由的作用,同时业务逻辑都部署在controller中,缺点是view可以直接访问model层,导致三者之间构成回路.

MVP模式案例

  • 本案例是书上提供给读者的MVP模式的案例,笔者写了一下,稍稍有一点MVP这种模式解耦优于MVC的感觉,但实际开发没真正使用过此框架,可能以下自我总结有疏漏的地方,请各位辩证性的看待和指出,一切研究都是为了更好的学习嘛.
  • View:即activity\fragment等,只做一些View的初始化工作,职责单一,功能简单,易于维护.其次与 Presenter中间类建立联系.并实现主界面ViewInterface的接口,用于Presenter回调View的操作
/**
 * MVP架构模式demo
 * @author max
 *
 */
public class MainActivity extends Activity implements ViewInterface{
    List<Model> models = new LinkedList<>();
    Presenter presenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //初始化控件
        initViews();
        //构建presenter,与当前activity建立关联
        presenter = new Presenter(this);
    }

    private void initViews() {

    }

    @Override
    public void showData(Model model) {
        //在这里就可以直接填充数据了,而把所有的业务逻辑和数据库操作全部放在Presenter层了.
    }

}
/**
 * 主界面的逻辑接口
 * 代表了View接口角色,用于Presenter回调View的操作
 * @author max
 *  */
public interface ViewInterface {
    //展示数据
    public void showData(Model model);
}
  • Presenter:中间人对象,用于view和model通信,主要持有的view显示层和model数据库操作层引用都是抽象而非具体,那么可以实现轻易的替换.
/**
 * 中间人对象,用于view和model通信
 * 从网络获取model数据省略
 * @author max
 *  */
public class Presenter {
    //view的接口角色
    ViewInterface mInterface;
    //数据model
    Model model = new Model();

    public Presenter(ViewInterface sInterface){
        this.mInterface = sInterface;
    }

    //想后台后去数据
    public void getDatFromWeb(){
        //向后台获取数据,在存储到本地数据库,过程省略
    }
}
  • model层主要是数据实体,ModelDaoImpl主要封装封装的数据库操作Dao的操作,这里就不贴代码了.
  • 最后文章提供了一个Prensenter和BaseActivity的基类,通过基类的声明周期函数来控制它与Presnter的关系,在oncreate建立view和Presenter联系,在onDestroy解除两者联系,避免内存泄露.
/**
 * 中间基类,放置activity关闭,但Presenter一直持有activity强引用对象,从而造成内存泄露
 * @author max
 *
 * @param <T> view角色要实现的接口类型
 */
public abstract class BasePresenter<T> {
    protected Reference<T> mViewRef;

    /**
     * 与view建立关联
     * @param view
     */
    public void attachView(T view){
        mViewRef = new WeakReference<T>(view);
    }

    /**
     * 获取View
     * @return
     */
    protected T getView(){
        return mViewRef.get();
    }

    /**
     * 判断是否与View建立了关联
     * @return
     */
    public boolean isViewAttached(){
        return mViewRef != null && mViewRef.get() != null;
    }

    /**
     * 解除关联
     */
    public void detachView(){
        if (mViewRef != null) {
            mViewRef.clear();
            mViewRef = null;
        }
    }
}
/**
 * 通过基类的声明周期函数来控制它与Presnter的关系
 * 在oncreate建立view和Presenter联系,在onDestroy解除两者联系,避免内存泄露
 * @author max
 *
 * @param <V> View接口类型
 * @param <T> Presenter的具体类型
 */
public abstract class MVPBaseActivity<V, T extends BasePresenter<V>> extends Activity{
    protected T mPrensenter; //Presenter对象

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //创建Presenter
        mPrensenter = createPresenter();
        //Presenter绑定view
        mPrensenter.attachView((V) this);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mPrensenter.detachView();
    }
    protected abstract T createPresenter();
}

源码下载

  • MVP模式,可能没经历过该类型的实际项目,可能在写的过程中,有些地方没有写的很详细易懂,今后经历过MVP和MVVC类型的项目会把心得体会补充进来.不得不说android项目的MVC的时代已经过了,掌握好MVC甚至MVVM才能做好android开发.
  • 项目源码下载.http://download.csdn.net/detail/qq_28690547/9441181
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值