本人现在每日一道算法题的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 list);
void onError();
}
public EssayModel(Context context){
mContext = context;
}
private OnEssayListener mListener;
public void getEssay(int num,OnEssayListener listener){
mListener = listener;
ArrayList list = new ArrayList();
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 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的解耦来说是一个不错的选择!
不当之处,欢迎路过大神指正批评。