MVP模式的个人理解

来源:互联网 发布:java解密encodeuri 编辑:程序博客网 时间:2024/05/14 05:02

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进行回调来进行页面的刷新。
最后上一个我的项目结构图:
目录结构图
由于并没有在实际项目中使用过,所以觉得如果是这么实现的话,代码的逻辑及模块是能清晰好多,但是是不是耦合性增大了呢,还请碰巧看到的大牛们不吝赐教。

0 0
原创粉丝点击