3

本人现在每日一道算法题的Github地址。
https://github.com/Jensenczx/CodeEveryda...
附带OJ地址和本人的代码

引言(扯谈)

昨天腾讯第一次电话面试,跟面试官聊得很嗨,不过好像并没有怎么聊技术也,是要挂我的节奏吗?还是简历上没有技术的东西可以聊,其中问了一个问题就是在android开发中有没有用到MVC或者说是MVP来进行分层处理,orz,orz,平时的程序都是写完之后就结束了,根本没有维护,而且交互简单,完全不需要分层呀,今天看了下相关的资料,算是学习下吧,再次意识到架构之美。开发的路上看来还是有很多路要走呀。同时今天和一个面试挖财的同学交流了一下,顿时感觉自己真的是好菜呀,我这个同学去挖财,直接分分钟手撸红黑,各种吊炸天秀,我去(跪舔去)。。接下来说下MVC和MVP,通过代码来演示下整体流程,再辅助一些理论的讲解。
代码挂在Github。

MVC

MVC,我想对于大部分搞过web的应该都不会陌生,但是对于一个android狗来说,似乎,,,什么鬼,往往社么数据库操作,网络操作,直接一坨放在activity里,好点的话,可能是把这些封装下,在activity里调用下,这不还是依赖,代码相比之下简洁了。我们操作数据库和网络,无非就是想从中获得数据,对,数据,如何获得呢?数据库,网络。所以,使得我们activity和网络数据库产生依赖的原因就是因为数据导致了依赖,所以松耦合需要我们通过model来将数据分离,将网络,数据库和数据的获得将其封装.这里通过一个从数据库中读写的例子来进行一个演示。

  • 向数据库中插入一条数据

  • 读出后在activity中展示

常规写法,直接在activity中写数据库的操作,读出数据之后,然后将值给控件进行显示,最开始我都是这么写,甚至是bean都不知道写,用了bean了,感觉数据规范了,但是数据库的操作还是和activity耦合在一起的,也就是对于数据层的处理是混在了controller层。那么我们通过MVC的模式来重写写下。

  • 首先是bean

public class Essay {
    private String title;
    private String url;
    private String page;

    public void setTitle(String title) {
        this.title = title;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public void setPage(String page) {
        this.page = page;
    }

    public String getTitle() {
        return title;
    }

    public String getUrl() {
        return url;
    }

    public String getPage() {
        return page;
    }

}
  • model层对数据进行封装

public class EssayModel {

    private Context mContext;

    public interface OnEssayListener{
        void onSuccess(List<Essay> list);
        void onError();
    }

    public EssayModel(Context context){
        mContext = context;
    }

    private OnEssayListener mListener;


    public void getEssay(int num,OnEssayListener listener){
        mListener = listener;
        ArrayList<Essay> list = new ArrayList<Essay>();
        SQLiteDatabase db = new DBHelper(mContext).getWritableDatabase();
        String sql = "select title,url,page from essay";
        String sql1 = "insert into essay (title,url,page) values('This is my essay.','http://www.baidu.com','http://www.baidu.com')";
        db.execSQL(sql1);
        //获取数据
        Cursor cursor = db.rawQuery(sql,null);
        cursor.moveToFirst();
        Essay tmp = new Essay();
        tmp.setTitle(cursor.getString(0));
        tmp.setUrl(cursor.getString(1));
        tmp.setPage(cursor.getString(2));
        list.add(tmp);
        listener.onSuccess(list);
        cursor.close();
        db.close();
    }
}

Activity

 public void updateData(){
        EssayModel model = new EssayModel(this);
        model.getEssay(1, new EssayModel.OnEssayListener() {
            @Override
            public void onSuccess(List<Essay> list) {
                esssayInfoTv.setText("标题:"+list.get(0).getTitle()+"文章链接:"+list.get(0).getUrl());
            }

            @Override
            public void onError() {

            }
        });
    }

主要目的说明思想,只插入了一条进行演示,代码有些混乱,刚开始写的时候还蒙了一下,通过一个判断游标是否为最后一个向下走,结果报了越界崩掉,好吧,我只插入了一个,它既是第一个也是最后一个(我只猜中了开头,却没有猜中结尾)。在controller层通过监听器注入的方式来实现和数据库相关操作的松耦合,注意,如果model层你写了单例,小心内存泄露哟!!!来个软引用持有吧。
图片描述

MVP

MVP 是从经典的模式MVC演变而来,它们的基本思想有相通的地方:Controller/Presenter负责逻辑的处理,Model提供数据,View负 责显示。作为一种新的模式,MVP与MVC有着一个重大的区别:在MVP中View并不直接使用Model,它们之间的通信是通过Presenter (MVC中的Controller)来进行的,所有的交互都发生在Presenter内部,而在MVC中View会从直接Model中读取数据而不是通过 Controller。

MVC短板

在MVC里,View是可以直接访问Model的!从而,View里会包含Model信息,不可避免的还要包括一些业务逻辑。 在MVC模型里,更关注的Model的不变,而同时有多个对Model的不同显示,及View。所以,在MVC模型里,Model不依赖于View,但是 View是依赖于Model的。不仅如此,因为有一些业务逻辑在View里实现了,导致要更改View也是比较困难的,至少那些业务逻辑是无法重用的。

简言之,在MVC的基础上,我要将View和数据交互的逻辑部分抽象出来,将这部分逻辑在MVP中继续重新利用,接下来,我们通过MVP的形式将上面的代码重构。

bean无需改变,只需添加Presenter.这里将activity看做了一个view,我们可以声明一个接口或者抽象类,让所有的activity来实现它,这样将activity以view的形式注入到presenter中,然后将逻辑全部转移到presenter中。

Presenter

public class EssayPresenter {

    private EssayView mView;
    private EssayModel mEssayModel;
    public EssayPresenter(EssayView view,Context context) {
        mView = view;
        mEssayModel = new EssayModel(context);
    }
    public void loadEssay() {
        Essay essay = new Essay();
        essay = mEssayModel.getEssay();
        mView.updateData(essay); // 通过调用IUserView的方法来更新显示
    }
}

Model

public Essay getEssay(){
        SQLiteDatabase db = new DBHelper(mContext).getWritableDatabase();
        String sql = "select title,url,page from essay";
        String sql1 = "insert into essay (title,url,page) values('This is my essay.','http://www.baidu.com','http://www.baidu.com')";
        db.execSQL(sql1);
        Cursor cursor = db.rawQuery(sql, null);
        cursor.moveToFirst();
        Essay tmp = new Essay();
        tmp.setTitle(cursor.getString(0));
        tmp.setUrl(cursor.getString(1));
        tmp.setPage(cursor.getString(2));
        cursor.close();
        db.close();
        return tmp;
    }

只是修改了下方法。

Activity

 EssayPresenter presenter = new EssayPresenter(this,this);
        presenter.loadEssay();
        
public void updataData(Essay essay){
     esssayInfoTv.setText("标题:" + essay.getTitle() + "文章链接:" + essay.getUrl());
    }

相比MVC,MVP中代码已经变得非常简洁了。view层不再和model层存在耦合。MVP主要解决就是把逻辑层抽出来成P层,要是遇到需求逻辑上的更改就可以只需要修改P层了或者遇到逻辑上的大概我们可以直接从写一个P也可以,我们会经常把所有的东西都写在了Activity/Fragment里面这样一来遇到频繁改需求或者逻辑越来越复杂的时候,Activity /Fragment里面就会出现过多的混杂逻辑导致出错,所以MVP模式对于APP来对控制逻辑和UI的解耦来说是一个不错的选择!

不当之处,欢迎路过大神指正批评。


Jensen95
2.9k 声望534 粉丝

连续创业者。