MVP简介
相信大家对 MVC 都是比较熟悉了:M-Model-模型、V-View-视图、C-Controller-控制器,MVP作为MVC的演化版本,也是作为用户界面(用户层)的实现模式,那么类似的MVP所对应的意义:M-Model-模型、V-View-视图、P-Presenter-表示器。从MVC和MVP两者结合来看,Controlller/Presenter在MVC/MVP中都起着逻辑控制处理的角色,起着控制各业务流程的作用。而MVP与MVC最不同的一点是M与V是不直接关联的也是就Model与View不存在直接关系,这两者之间间隔着的是Presenter层,其负责调控View与Model之间的间接交互,MVP的结构图如下所示,对于这个图理解即可而不必限于其中的条条框框,毕竟在不同的场景下多少会有些出入的。在Android中很重要的一点就是对UI的操作基本上需要异步进行也就是在MainThread中才能操作UI,所以对View与Model的切断分离是合理的。此外Presenter与View、Model的交互使用接口定义交互操作可以进一步达到松耦合也可以通过接口更加方便地进行单元测试。
MVP之Model
Model 是用户界面需要显示数据的抽象,也可以理解为从业务数据(结果)那里到用户界面的抽象(Business rule, data access, model classes)。本文 Demo 为了简单处理就直接把业务放到了对应的 Model 之中。
MVP之View
视图这一层体现的很轻薄,负责显示数据、提供友好界面跟用户交互就行。MVP下Activity和Fragment体现在了这一层,Activity一般也就做加载UI视图、设置监听再交由Presenter处理的一些工作,所以也就需要持有相应Presenter的引用。例如,Activity上滚动列表时隐藏或者显示Acionbar(Toolbar),这样的UI逻辑时也应该在这一层。另外在View上输入的数据做一些判断时,例如,EditText的输入数据,假如是简单的非空判断则可以作为View层的逻辑,而当需要对EditText的数据进行更复杂的比较时,如从数据库获取本地数据进行判断时明显需要经过Model层才能返回了,所以这些细节需要自己掂量。
MVP之Presenter
MVP之Presenter
Presenter这一层处理着程序各种逻辑的分发,收到View层UI上的反馈命令、定时命令、系统命令等指令后分发处理逻辑交由业务层做具体的业务操作,然后将得到的 Model 给 View 显示
小结
综上MVP小结如下:
- View 对应于Activity,负责View的绘制以及与用户交互
- Model 依然是业务逻辑和实体模型
- Presenter 负责完成View于Model间的交互
视图如下:
项目展示
框架:
界面视图:
图中明显的三层:Model包、Presenter包、UI包,其中,三者都实现各自的结构,Model为UserModel、Presenter为UserPresenter、View为UserActivity;其中每个接口都有具体实现类。
数据Model
首先我们需要一个Note ,用来保存用户信息
public class Note {
private Long id;
/** Not-null value. */
private String text;
private String comment;
private java.util.Date date;
public Note() {
}
public Note(Long id) {
this.id = id;
}
public Note(Long id, String text, String comment, java.util.Date date) {
this.id = id;
this.text = text;
this.comment = comment;
this.date = date;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
/** Not-null value. */
public String getText() {
return text;
}
/** Not-null value; ensure this value is available before it is saved to the database. */
public void setText(String text) {
this.text = text;
}
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
public java.util.Date getDate() {
return date;
}
public void setDate(java.util.Date date) {
this.date = date;
}
}
定义Model相关接口IDataModel,以UserModel实现,用来为Presenter 层调用。
public interface IDataModel {
void setUserName (String userName);
void setComment (String comment);
Note load (String userName);
}
public class UserModel implements IDataModel{
private String mUserName;
private String mComment;
@Override
public void setUserName(String userName) {
mUserName=userName;
}
@Override
public void setComment(String comment) {
mComment=comment;
Note note=new Note();
note.setText(mUserName);
note.setComment(comment);
DBManager.getInstance().getNoteDao().insert(note);
}
@Override
public Note load(String userName) {
Note note=DBManager.getInstance().getNote(userName);
return note;
}
}
View层
基于项目需要展示用户、评论,并由GreenDao 数据库读写,定义以下接口:
public interface IUserView {
String getUserName();
String getComment();
void setUserName(String userName);
void setComment(String comment);
}
Activity持有Presenter对象,便于操作数据及UI。
public class UserActivity extends Activity implements View.OnClickListener,IUserView{
private EditText mUserName , mComment ;
private Button mSaveButton , mLoadButton ;
private UserPresenter userPresenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_querydb_main);
findWidgets();
userPresenter=new UserPresenter(this);
}
void findWidgets() {
mUserName = (EditText) findViewById(R.id.first_name_edt);
mComment = (EditText) findViewById(R.id.last_name_edt);
mSaveButton = (Button) findViewById(R.id.saveButton);
mLoadButton = (Button) findViewById(R.id.loadButton);
mSaveButton.setOnClickListener(this);
mLoadButton.setOnClickListener(this);
}
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.saveButton:
userPresenter.saveUser(getUserName(),getComment());
break;
case R.id.loadButton:
userPresenter.loadUser(getUserName());
break;
}
}
@Override
public String getUserName() {
return mUserName.getText().toString();
}
@Override
public String getComment() {
return mComment.getText().toString();
}
@Override
public void setUserName(String userName) {
mUserName.setText(userName);
}
@Override
public void setComment(String comment) {
mComment.setText(comment);
}
}
Presenter层
同时持有View、Model层接口,并提供saveUser,loadUser接口,提供View_Model数据传递及展示UI的桥梁。
public interface IUserPresenter {
void saveUser(String userName,String comment);
void loadUser(String userName);
}
public class UserPresenter implements IUserPresenter{
private IUserView iUserView;
private IDataModel iDataModel;
public UserPresenter(IUserView iUserView){
this.iUserView=iUserView;
this.iDataModel=new UserModel();
}
@Override
public void saveUser(String userName, String comment) {
iDataModel.setUserName(userName);
iDataModel.setComment(comment);
}
@Override
public void loadUser(String userName) {
Note note=iDataModel.load(userName);
iUserView.setUserName(note.getText());
iUserView.setComment(note.getComment());
}
}
希望能助你解惑
Git项目源码