MVC
MVC框架模式最早由Trygve Reenskaug 于1978年在Smalltalk-80系统上首次提出。经过了这么多年的发展,当然会演变出不同的版本,但核心没变依旧还是三层模型Model-View-Control。
可能由于MVP、MVVM的兴起,MVC在android中的应用变得越来越少了,但MVC是基础,理解好MVC才能更好的理解MVP,MVVM。因为后两种都是基于MVC发展而来的。
-
视图层(View)
对应于xml布局文件和java代码动态view部分 -
控制层(Controller)
MVC中Android的控制层是由Activity来承担的,Activity本来主要是作为初始化页面,展示数据的操作,但是因为XML视图功能太弱,所以Activity既要负责视图的显示又要加入控制逻辑,承担的功能过多。 -
模型层(Model)
针对业务模型,建立的数据结构和相关的类,它主要负责网络请求,数据库处理,I/O的操作。
MVC总结
- 具有一定的分层,model彻底解耦,controller和view并没有解耦
- 层与层之间的交互尽量使用回调或者去使用消息机制去完成,尽量避免直接持有
- controller和view在android中无法做到彻底分离,但在代码逻辑层面一定要分清
- 业务逻辑被放置在model层,能够更好的复用和修改增加业务
MVP
MVP概述
当将架构改为MVP以后,Presenter的出现,将Actvity视为View层,Presenter负责完成View层与Model层的交互。每一层都是一个接口,每一层都有它自己的实现类。现在是这样的:
- View 对应于Activity,负责View的绘制以及与用户交互
- Model 处理数据和实体模型
- Presenter 负责完成View于Model间的交互,是V和M层交互的桥梁。
MVP原理图
MVP使用
普通写法
本例子实现一个随机数获取的功能。
1.在项目中创建三个包,view、presenter、model包
2.在三个包名下,创建三个对应的接口,IView、IPresenter、IModel
public interface IView {
void updateUI(String result);
void updateFailed(String error);
}
public interface IPresenter {
void getRandomNum();
}
public interface IModel {
void updateRandomNum(Callback callback);
}
3.创建三个接口对应的实现类
IView因为对应是Actviity,所以不用创建,只需要让Activtity实现IView即可
public class MainActivity extends AppCompatActivity
implements IView, View.OnClickListener {
private Button mClick;
private TextView mResult;
private Presenter presenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
presenter = new Presenter(this);
}
private void initView() {
mClick = (Button) findViewById(R.id.click);
mClick.setOnClickListener(this);
mResult = (TextView) findViewById(R.id.result);
}
@Override
public void updateUI(String result) {
mResult.setText(result);
}
@Override
public void updateFailed(String error) {
mResult.setText(error);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.click:
// TODO 20/04/01
presenter.getRandomNum();
break;
default:
break;
}
}
}
IPresenter实现类
public class Presenter implements IPresenter {
private final Model model;
private IView iView;
// 调用M 层的逻辑
public Presenter(IView iView) {
this.iView = iView;
model = new Model();
}
@Override
public void getRandomNum() {
model.updateRandomNum(new Callback(){
@Override
public void updateUIOK(int i) {
iView.updateUI(i+"");
}
@Override
public void updateUIFailed(int i) {
iView.updateFailed(i+"");
}
});
}
}
IModel实现类
/**
* M 就是真正去做功的类
* 请求网络 数据库 计算
*/
public class Model implements IModel {
@Override
public void updateRandomNum(Callback callback) {
Random random = new Random();
int i = random.nextInt(12343);
if (i%2==0){
callback.updateUIOK(i);
}else{
callback.updateUIFailed(i);
}
}
}
4.它们之间如何交互
1.view–>presenter: activity在这里充当view接口的角色,现在我们需要view调用presenter,我们怎么调用?我们要创建Presenter的对象,就是new Presenter(this);,而且还传入一个参数是this,这个this就是view身份,为什么传它,是因为view在后面会接收计算的数据,以便于显示到UI界面上。
2.Presenter–>Model: 因为Presenter只是作为V和M之间的桥梁,所以它不处理任何数据,它做中转数据,它需要Model去执行数据的运算或者是耗时的任务。所以在presenter类也要创建model类,以便于调用model的方法。
3:Model–>Presenter: model层主要处理耗时或者计算子类的重活,如网络数据获取,数据库数据的获取,大量的数据运算等。model层处理完数据以后,就要把数据传送给Presenter 类,通过callback接口,也就是接口回调得形式回传数据。
4.Presenter–>View:这一步就简单很多,通过上一步数据已经被传送到presenter层,但是presenter获取到数据没有意义,最终还是要显示到UI界面上才行。还记得第一步传送的this吗,这个this就是view层,其实还是一个activity,把这个引用传送过来,我们就可以调用activity得方法了。整个逻辑到此结束。