从Mvc到Mvp
2016-07-22 16:37
489 查看
记得刚入行那会儿,Mvc架构都被吹上了天,去那家面试,都必须要问Mvc,突然一天风向一转来了一个Mvp,为什么会这样呢,让我们先来捋一下这两个概念
MVC:
M : 业务层和模型层,相当与javabean和我们的业务请求代码
V : 视图层,对应Android的layout.xml布局文件
C : 控制层,对应于Activity中对于UI 的各种操作
看起来MVC架构很清晰,但是实际的开发中,请求的业务代码往往被丢到了Activity里面,布局文件只能提供默认的UI设置,所以开发中视图层的变化也被丢到了Activity里面,再加上Activity本身承担着控制层的责任。所以Activity达成了MVC集合的成就,实现了代码的耦合,最终我们的Activity就变得越来越难看,从几百行变成了几千行。维护的成本也越来越高
MVP:
M : 还是业务层和模型层
V : 视图层的责任由Activity来担当
P : 新成员Presenter 用来代理 C(control) 控制层
MVP与MVC最大的不同,其实是Activity职责的变化,由原来的C (控制层) 变成了 V(视图层),不再管控制层的问题,只管如何去显示。控制层的角色就由我们的新人 Presenter来担当,这种架构就解决了Activity过度耦合控制层和视图层的问题。
让我们以一个小小的功能来看看这两种实现方式有啥子不一样的,比如模拟在一个Activity中发起网络请求,结果添加到listView列表,并实现列表的点击事件
先定义一个接口 和抽象类 用接口回调来模拟实现网络请求
1.接口
2.接口
3.实现类
最后看一下在Activity中的调用方式
然后就结束了 初始化控件—->网络请求——->子线程更新UI—点击事件(C: 控制层(点击事件,网络请求), V : 视图层(界面刷新) 。就这样耦合到了Activity里面。)
让我们看下Mvp是怎么来做的,,既然是Mvp 我们先来看下v(View)和p(Prensenter)
先来看下View 用一个接口来定义一些View层要实现的抽象方法,比如显示,隐藏,初始化,弹出提示
再来看p(Prensenter)的方法 发起网络请求,更新UI ,销毁UI (操作UI)实现点击事件,
Activity调用
我们的实际发开中需求往往瞬息万变,每次还要等美工出界面,这样往往会浪费大量时间,但是在MVP的世界这些都不是事,视图层与控制层完全分离,可以让我们在界面还是很粗糙的情况下,先进行控制层的开发,甚至可以先让View层先提供方法出来,这样可以节省很多时间。后面的复杂需求变化,也就是构建接口的时候会变的复杂,但是在有这么多优势的情况下,这点复杂度完全可以接受 。。。。
MVC:
M : 业务层和模型层,相当与javabean和我们的业务请求代码
V : 视图层,对应Android的layout.xml布局文件
C : 控制层,对应于Activity中对于UI 的各种操作
看起来MVC架构很清晰,但是实际的开发中,请求的业务代码往往被丢到了Activity里面,布局文件只能提供默认的UI设置,所以开发中视图层的变化也被丢到了Activity里面,再加上Activity本身承担着控制层的责任。所以Activity达成了MVC集合的成就,实现了代码的耦合,最终我们的Activity就变得越来越难看,从几百行变成了几千行。维护的成本也越来越高
MVP:
M : 还是业务层和模型层
V : 视图层的责任由Activity来担当
P : 新成员Presenter 用来代理 C(control) 控制层
MVP与MVC最大的不同,其实是Activity职责的变化,由原来的C (控制层) 变成了 V(视图层),不再管控制层的问题,只管如何去显示。控制层的角色就由我们的新人 Presenter来担当,这种架构就解决了Activity过度耦合控制层和视图层的问题。
让我们以一个小小的功能来看看这两种实现方式有啥子不一样的,比如模拟在一个Activity中发起网络请求,结果添加到listView列表,并实现列表的点击事件
先定义一个接口 和抽象类 用接口回调来模拟实现网络请求
1.接口
public interface OnRequestListener { void onSuccess(List<String> data); void onFailed(); }
2.接口
public interface RequestBiz { void requestForData(OnRequestListener listener); }
3.实现类
public class RequestBiziml implements RequestBiz{ @Override public void requestForData(final OnRequestListener listener) { new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(2000); ArrayList<String> data = new ArrayList<>(); for(int i = 1 ; i< 8 ; i++){ data.add("item"+i); } if(null != listener){ listener.onSuccess(data); } }catch(Exception e){ e.printStackTrace(); } } }).start(); } }
最后看一下在Activity中的调用方式
public class MVCActivity extends AppCompatActivity{ private ListView mvcListView; private RequestBiz requestBiz; private ProgressBar pb; private Handler handler; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_mvc); mvcListView = (ListView)findViewById(R.id.mvc_listview); pb = (ProgressBar) findViewById(R.id.mvc_loading); pb.setVisibility(View.VISIBLE); handler = new Handler(Looper.getMainLooper()); requestBiz = new RequestBiziml(); requestForData(); } public void requestForData(){ requestBiz.requestForData(new OnRequestListener() { @Override public void onSuccess(final List<String> data) { //模拟网络请求 handler.post(new Runnable() { @Override public void run() { pb.setVisibility(View.GONE); ArrayAdapter adapter = new ArrayAdapter(MVCActivity.this,android.R.layout.simple_list_item_1,data); mvcListView.setAdapter(adapter); mvcListView.setOnItemClickListener(itemClickListener); } }); } @Override public void onFailed() { pb.setVisibility(View.GONE); Toast.makeText(MVCActivity.this,"加载失败",Toast.LENGTH_SHORT).show(); } }); } //点击事件 private AdapterView.OnItemClickListener itemClickListener = new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Toast.makeText(MVCActivity.this,"点击了item"+(position+1),Toast.LENGTH_SHORT).show(); } }; }
然后就结束了 初始化控件—->网络请求——->子线程更新UI—点击事件(C: 控制层(点击事件,网络请求), V : 视图层(界面刷新) 。就这样耦合到了Activity里面。)
让我们看下Mvp是怎么来做的,,既然是Mvp 我们先来看下v(View)和p(Prensenter)
先来看下View 用一个接口来定义一些View层要实现的抽象方法,比如显示,隐藏,初始化,弹出提示
public interface MvpView { void showLoading(); void hideLoading(); void setListItem(List<String> data); void showMessage(String message); }
再来看p(Prensenter)的方法 发起网络请求,更新UI ,销毁UI (操作UI)实现点击事件,
public class MvpPresenter { private MvpView mvpView; private RequestBiz requestBiz; private Handler mHandler; //此构造方法传入了一个MvpView 所以我们只需要在Activity中实现这个MvpView接口就可以传入上下文 并以此调用MvpView 的抽象方法(可能这种说法不对,管他呢) public MvpPresenter(MvpView mvpView) { this.mvpView = mvpView; requestBiz = new RequestBiziml(); mHandler = new Handler(Looper.getMainLooper()); } public void onResume(){ mvpView.showLoading(); requestBiz.requestForData(new OnRequestListener() { @Override public void onSuccess(final List<String> data) { mHandler.post(new Runnable() { @Override public void run() { mvpView.hideLoading(); mvpView.setListItem(data); } }); } @Override public void onFailed() { mvpView.showMessage("请求失败"); } }); } public void onDestroy(){ mvpView = null; } public void onItemClick(int position){ mvpView.showMessage("点击了item"+position); } }
Activity调用
public class MVPActivity extends AppCompatActivity implements MvpView,AdapterView.OnItemClickListener{ private ListView mvpListView; private MvpPresenter mvpPresenter; private ProgressBar pb; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_mvp); mvpListView = (ListView)findViewById(R.id.mvp_listview); mvpListView.setOnItemClickListener(this); pb = (ProgressBar) findViewById(R.id.mvp_loading); mvpPresenter = new MvpPresenter(this); } @Override protected void onResume() { super.onResume(); mvpPresenter.onResume(); } @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { mvpPresenter.onItemClick(position); } @Override public void showLoading() { pb.setVisibility(View.VISIBLE); } @Override public void hideLoading() { pb.setVisibility(View.GONE); } @Override public void setListItem(List<String> data) { ArrayAdapter adapter = new ArrayAdapter(MVPActivity.this,android.R.layout.simple_list_item_1,data); mvpListView.setAdapter(adapter); } //退出时销毁持有Activity @Override protected void onDestroy() { mvpPresenter.onDestroy(); super.onDestroy(); } @Override public void showMessage(String message) { Toast.makeText(this,message,Toast.LENGTH_SHORT).show(); } }
我们的实际发开中需求往往瞬息万变,每次还要等美工出界面,这样往往会浪费大量时间,但是在MVP的世界这些都不是事,视图层与控制层完全分离,可以让我们在界面还是很粗糙的情况下,先进行控制层的开发,甚至可以先让View层先提供方法出来,这样可以节省很多时间。后面的复杂需求变化,也就是构建接口的时候会变的复杂,但是在有这么多优势的情况下,这点复杂度完全可以接受 。。。。
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories