Android开发中的MVP实现

CarSowerby 8年前
   <p>最近想要重构代码,因为项目需要给几个学校使用,而每个学校的界面是有差别的,但是功能几乎一模一样,虽然用gradle的分支可以做到代码的差异,但是公共部分的代码逻辑也越来越多,所以想重构一下,最近比较火的MVP模式看了一下,觉得很合适,不过网上很多资料也是抄来抄去,有的还有错误,就想按照自己的理解把MVP模式描述一下,方便他人理解,先说一下大家最熟悉的MVC设计模式吧</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/b99123558cb254ba457ee20cb5fae58c.png"></p>    <p>深度截图20161205163205.png</p>    <p>MVC模式解耦合了M层和V层,M层和V层通过C层来交互</p>    <p>然后看一下MVP,我下面的文字以I开头的是接口的意思(手打的图好累...)</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/107ada8d383fc13fb75bd6b7e680ddc8.png"></p>    <p>深度截图20161205160152.png</p>    <p>MVP和MVC最大的区别是P层代替了以前的C层,控制的不再是具体的实现而是接口,这样不管是多人开发还是频繁的UI更改,都不会影响P层,只要C和V层的接口不变,要改动的只是UI而已,这样代码就很清晰,而且方便测试,因为逻辑层和视图层完全分离了,下面用代码来说话,还是先来MVC模式的,用登录这个例子吧,android已经很好的把C层和V层分开了,我们写的xml相当于V层,Activity相当于C层</p>    <pre>  <code class="language-java">public interface ICallback{    void receive(boolean success);  }</code></pre>    <pre>  <code class="language-java">public class LoginModel{    public void login(String name,String password,ICallback callback){      WebApi.login(name,password,callback);    }  }</code></pre>    <pre>  <code class="language-java">public class LoginActivity extends Activity{    private LoginModel mLoginModel;    private EditText mUserNameEt;    private EditText mPasswordEt;    private Button mSubmitBtn;    public void onCreate(......){      mLoginModel = new LoginModel(...);      mSubmitBtn.setOnClickListener(new OnClickListener(View view){          mLoginModel.login(mUserNameEt.get...,mPasswordEt.get...,new Callback(){            public void receive(boolean success){              if(success){                startActivity(new Intent(this,MainActivity.class));                finish();              } else {                Toast.makeText(this,"登录失败",Toast.LENGTH_SHORT).show();              }            }          });      });    }  }</code></pre>    <p>我们再来看一下用MVP模式怎么写</p>    <pre>  <code class="language-java">public interface ILoginModel{    public void login(String name,String password,Callback callback);  }</code></pre>    <pre>  <code class="language-java">public class LoginModelImpl implements ILoginModel{    public void login(String name,String password,Callback callback){      WebApi.login(name,password,callback);    }  }</code></pre>    <pre>  <code class="language-java">public interface ILoginView{    public void showDialog();    public void dismissDialog();    public void showToast(String message);    public void navigateToMain();  }</code></pre>    <pre>  <code class="language-java">public interface IPresenter{    public void login(String name,String password);  }</code></pre>    <pre>  <code class="language-java">public class PresenterImpl implements IPresenter,ICallback{    private ILoginView mLoginView;    private ILoginModel mLoginModel;      public PresenterImpl(ILoginView loginView){      this.mLoginView = loginView;      this.mLoginModel = new LoginModelImpl();    }      public void login(String name,String password){      if(isEmpty(name)||isEmpty(password)){          this.mLoginView.showToast("用户名或密码不能为空");          return;      }      this.mLoginModel.login(name,password,this);    }      public void receive(boolean success){      if(success){        this.mLoginView.navigateToMain();      }else{        this.mLoginView.showToast("登录失败");      }    }      private boolean isEmpty(String text){      return text==null||"".equals(text)?true:false;    }  }</code></pre>    <pre>  <code class="language-java">public class LoginActivity extends Activity implements ILoginView{    private IPresenter mPresenter;    private EditText mUserNameEt;    private EditText mPasswordEt;    private Button mSubmitBtn;    public void onCreate(......){      mPresenter = new PresenterImpl(this);      mSubmitBtn.setOnClickListener(new OnClickListener(View view){          mLoginModel.login(mUserNameEt.getText().toString(),                            mPasswordEt.getText().toString());      });    }      public void showDialog(){      //显示一个转圈的dialog;    }      public void dismissDialog(){      //隐藏转圈的dialog;    }      public void showToast(String message){      Toast.makeText(this,message,Toast.LENGTH_SHORT).show();    }      public void navigateToMain(){      startActivity(new Intent(this,MainActivity.class));      finish();    }  }</code></pre>    <p>MVP的类和代码确实要多一些,但是这些是非常值得的,可以看出现在的代码逻辑要比MVC模式写起来更清晰,代码测试也更简单,甚至可以在没有页面效果图只有功能的时候完成功能,UI的改变也不会影响任何的业务代码。</p>    <p>以上MVP设计模式是个人理解,如果有误请指正,谢谢,共同探讨,共同进步</p>    <p> </p>    <p>来自:http://www.jianshu.com/p/4e2a1dfd4d95</p>    <p> </p>