MVP框架设计详解
Model是MVP中的模型层,在MVP中,通常我会用来定义功能。而在MVC中,Model的主要部分就在于Domain的定义,由于Activity中交缠了太多的东西,mvc虽然常常在分包时显得清晰,但事实上的编码部分却非常的复杂。而MVP部分将Model的职责定义的更加清晰,也就让各层的就够更加明显易见。
mode层
'首先是接口' public interface LoginModel{ //用于回调登录进程 interface LoginListener{ void onLogining(); void onSuccess(); void onFaield() } void login(String username, String password, OnLoginListener listener); }
/*接着是实现部分*/ public class LoginModelImpl implements LoginModel{ public void login(String username, String password, OnLoginListener listener){ //登录逻辑... listener.onLogining(); if(....) listener.onSuccess(); if(....) listener.onFaield(); } }
先从定义的接口讲起,LoginModel作为接口定义Login这一功能模型,同时在接口中定义一个接口,用于监听登录的过程,作为回调使用。
之后是接口实现,在实现类中完成功能的实现,并且在过程中根据不同情况进行回调操作。
从这里可以初步看出,MVP模式是将各层更加清晰的进行分离了。Model的主要工作就是进行功能执行,其余的工作将会交付给Presenter完成。
view层
public interface LoginView{ void showProgress(); void hideProgress(); void inputError(String error); }
可以看出,在LoginView中定义的方法都是和显示有关的方法,也就是涉及到Login这一过程中将会出现的几种View表现方式。接口中所定义的所有方法,最终都是由Activity来实现的,所以在接口中的方法应该尽量考虑好参数与返回值。
Presenter层
MVP中的Presenter层,称它为主持我觉得也挺贴切,作为一个中间人主持Model与View之间的交互,在MVC中Activity内关于Model及View之间的交互都可以移入Presenter中,由Presenter完成这两层之间的交互。那么可以这么说,Presenter层在MVP中占着大比重。
首先来看看接口定义
'看着接口定义很简单,只有一个方法定义' public interface LoginPresenter{ void loginCheck(String username, Stirng password); }
接着是接口的实现类
public class LoginPresenterImpl implements LoginPresenter, LoginModel.OnLoginListener{ private LoginView loginView; private LoginModel loginModel; //非常重要的构造方法,联系Model和View的关键 public LoginPresenterImpl(LoginView loginView){ this.loginView = loginView; this.loginModel = new LoginModelImpl(); } public void loginCheck(String username, String password){ loginView.showProgress(); ...... loginView.input("错误信息"); ...... loginModel.login(username, password); } public void onLogining(){ } public void onSuccess(){ loginView.hideProgress(); } public void onFaield(){ loginView.hideProgress(); } }
Activity(View)
Activity是应该分类到View层中的,而在本文中为了构建的整体思路更加完整丝滑,所以讲Activity中的定义部分放到最后完成。但务必注意,Activity在MVP中不是单属一层,而是属于View层。
来看一下Activity的编写方式:
public class LoginActivity implements LoginView, View.OnClickListener{ private LoginPresenter loginPresenter; pretected void onCreate(Bundle saveInstance){ '...' //init //findViewById '...' loginPresenter = new LoginPresenterImpl(this); } public void showProgress(){ progressBar.setVisiable(View.Visiable); } public void hideProgress(){ progressBar.setVisiable(View.InVisiable); } public void inputError(String error){ Toast.makeText(this, error, Toast.LENGTH_SHORT).show(); } public void onClick(View v){ switch(v){ case R.id.bt_login: loginPresenter.checkLogin(username, password); break; } } }
MVP各层关系梳理
先看张图。我可是专门下了个axure
这张图可以说已经把MVP各层的关系讲述的淋漓尽致了,当然,关于各个层之间是怎样产生联系的这一点,我也会做一个详细的解析。事实上这已经在PresenterImpl的代码中体现的比较明显了。
Model与Presenter
在PresenterImpl的构造方法中,实例化一个ModelImpl类,完成在PresenterImpl中获取Model对象的步骤。这一部非常简单,同时有效。
View与Presenter
在PresenterImpl中直接以参数形式获取View对象,这一点甚至比实例化简单。通常的做法是在Activity中,实例化PresenterImpl对象,同时将this(也就是Activity本身)作为参数传入PresenterImpl的构造方法。
Presenter完成的交互
Presenter作为MVP中的主持层,保证Model与View两层之间的相互交流。在PresenterImpl内部能够依照Model对象的状态调用View对象的方法,同时也能够在调用View对象方法之后修改Model对象状态。在Presenter中的实现就完成了Model与View之间的交互。
Model与View之间的交互
MVP中不应该存在Model与View直接交互的情况,这部分讲的是Model与View通过Presenter进行的间接交互,在没有黑科技的情况下(后面会提到),一般使用Listener来做一个监听,在Model中定义Listener,监听Model中各个阶段,之后通过PresenterImpl来在各个回调中处理View的动作。
总结:
这一次解析MVP可以说是又一次深有体会,感触良多,很多细节方面的东西都有了新的认识,让我们共同在技术的海洋里畅游,既然青春留不住,就让它尽情翱翔吧!有不足之处还望辅正。。。