MVP模式 个人短浅的理解
最近项目没有很紧(虽然我项目一直不紧),于是看了一下一些mvp模式的博客,现在此记录下自己的观点,仅供参考。当然,如果有兄弟或者姐妹能指出我理解中的误区和偏差,更是不胜感激,下面开始。
传统MVC模式中的项目,都是Activity既承载了View的刷新,又要进行Controller的处理,这样就会造成在大部分的Activity中代码十分的庞大,给后期的后期的维护造成极大的负荷;而且,最最可恶的是,会让人分不清到底MVC模式到底是什么鬼,尤其是像我这种半吊子码农,养成堆砌代码的坏习惯。下面来拨开个传统的项目的栗子(被用烂了的登录功能呗):
public class LoginActivity extends BaseActivity {
private Button button;
private EditText loginNameEt;
private EditText pwdEt;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.main);
initView();
addEvent();
}
@Override
public void initView() {
button = (Button) findViewById(R.id.click);
loginNameEt = (EditText) findViewById(R.id.login_name);
pwdEt = (EditText) findViewById(R.id.login_pwd);
}
@Override
public void addEvent() {
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
doLogin(loginNameEt.getText().toString(), pwdEt.getText().toString());
}
});
}
//这里是Controller的工作吖,为什么会放在View里呢?okey,为了写起来方便
private void doLogin(String name, String pwd) {
//登录处理
//...
}
@Override
public void getExa() {
}
}
然后我们来看这个代码,毫无疑问,这么看起来还算蛮干净整洁的,但是仔细想想,这还是在堆代码吖,从刚从代码界入行我就这么写,到现在还在这么写,这对我在代码界的狗生没有丝毫的帮助,,,那么该怎么办呢???
话不说多先上图(原谅我这么多年一直做一只凶猛的盗图狗)
根据这个图来解释下MVP模式:所谓的mvp,即是(model-处理业务逻辑(主要是数据读写,或者与后台通信(其实也是读写数据)),view-处理ui控件,presenter-主导器,操作model和view),当然这是官方的说法;我的理解是presenter作为一个中间件来处理我们需要做的操作,并通知view更新及model的修改
那让我们变成“gua牛”一步一步来往深爬。所谓知其然必得知其所以然,然后我们来分析:
假设我们有一个Activity(这里就不说model嘞,仿照view的处理),想通过这个Activity来实现登录功能。嗯,View的刷新应该包括:登录后页面的跳转或者当前页面的数据的清除;Controller应该做的事包括:登录的处理。
首先我们来定义present,我们先来定义一个接口,根据上面分析可知,这个接口需要实现登录功能:
public interface LoginPresenter {
void doLogin(String name, String pwd);
}
然后再来定义一个View的接口,毕竟如果想通过present来控制view,必须有个view的引用传进来,不然我还控制个毛吖
public interface LoginView {
void onClearText();
void onLoginResult(boolean result, int code);
}
好啦,指定了view的接口,在activity实现了这个接口,就可以对View进行处理嘞。
根据View和present的接口,我们来实现我们的present类,
public class LoginPresenterCompl implements LoginPresenter {
LoginView loginView;
User user;
public LoginPresenterCompl(LoginView loginView) {
this.loginView = loginView;
}
@Override
public void doLogin(String name, String pwd) {
//网络请求或者其他操作
//...
//选一个做处理.如有必要写在回调中,还要注意是否需要通过主线程来刷新View
loginView.onLoginResult(true, 200);
loginView.onClearText();
}
}
那为什么这么写呢,正如上面所说,当我想要控制view,必须通过一个实例引用来控制我view的刷新,所以定义了一个以view为参数的构造方法,然后就是在dologin(x,y)中进行我们的Controllor的处理及通知view刷新嘞。
下面提供Activity的实现,
//实现了LoginView 接口,在我看来其实是通过回调来实现view的刷新(说这话感觉好虚啊,求重喷)
public class LoginActivity extends BaseActivity implements LoginView {
private Button button;
private EditText loginNameEt;
private EditText pwdEt;
private LoginPresenter loginPresenter;
/**
* Called when the activity is first created.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.main);
//new 一个LoginPresenterCompl实例,并将activity本身作为View传递给present来进行页面更新
loginPresenter = new LoginPresenterCompl(this);
initView();
addEvent();
}
@Override
protected void onDestroy() {
super.onDestroy();
}
@Override
public void initView() {
button = (Button) findViewById(R.id.click);
loginNameEt = (EditText) findViewById(R.id.login_name);
pwdEt = (EditText) findViewById(R.id.login_pwd);
}
@Override
public void addEvent() {
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
loginPresenter.doLogin(loginNameEt.getText().toString().trim(), pwdEt.getText().toString().trim());
}
});
}
@Override
public void getExa() {
}
@Override
public void onClearText() {
loginNameEt.setText("");
pwdEt.setText("");
}
@Override
public void onLoginResult(boolean result, int code) {
Toast.makeText(MyActivity.this, "the result is " + result + " the code is " + code, Toast.LENGTH_SHORT).show();
Intent intent = new Intent();
intent.setClass(MyActivity.this, SecondActivity.class);
startActivity(intent);
}
}
忽然感觉没什么好说的了,就是在onclick的时候调用present进行login处理,然后login处理后调用传入的view进行回调来进行页面的刷新。
最后上一个我的项目结构图:
由于并没有在实际项目中使用过,所以觉得如果是这么实现的话,代码的逻辑及模块是能清晰好多,但是是不是耦合性增大了呢,还请碰巧看到的大牛们不吝赐教。