在MVP模式里通常包含4个要素:
(1)
View:负责绘制UI元素、与用户进行交互(在Android中体现为Activity);
(2
)View interface:需要View实现的接口,View通过View interface与Presenter进行交互,降低耦合,方便进行单元测试;
(3)
Model:负责存储、检索、操纵数据(有时也实现一个Model interface用来降低耦合);
(4)
Presenter:作为View与Model交互的中间纽带,处理与用户交互的负责逻辑。
MVP模式:
- View不直接与Model交互,而是通过与Presenter交互来与Model间接交互
- Presenter与View的交互是通过接口来进行的,更有利于添加单元测试
- 通常View与Presenter是一对一的,但复杂的View可能绑定多个Presenter来处理逻辑
转变:
转变为:
MVC与MVP的区别
可以发现,Presenter与Model、View都是通过接口来进行交互的,既降低耦合也方便进行单元测试。
(1)UserBean,用来保存用户信息
package test.ban.com.myapplication.bean;/** * Created by apple on 16/8/18. */ /** * 作者:ban on 16/8/18 15:43 */ public class UserBean { private String mFirstName; private String mLastName; public UserBean(String firstName, String lastName) { this.mFirstName = firstName; this.mLastName = lastName; } public String getFirstName() { return mFirstName; } public String getLastName() { return mLastName; } }(2)View接口:
package test.ban.com.myapplication.view; /** * Created by apple on 16/8/18. */ public interface IUserView { int getID(); String getFristName(); String getLastName(); void setFirstName (String firstName); void setLastName (String lastName); }
(3)Model接口:
package test.ban.com.myapplication.model; import test.ban.com.myapplication.bean.UserBean; /** * Created by apple on 16/8/18. */ public interface IUserModel { void setID (int id); void setFirstName (String firstName); void setLastName (String lastName); UserBean load (int id);//通过id读取user信息,返回一个UserBean }(4)Presenter: Presenter就能通过接口与View及Model进行交互了:
package test.ban.com.myapplication.persenter;/** * Created by apple on 16/8/18. */ import test.ban.com.myapplication.bean.UserBean; import test.ban.com.myapplication.model.IUserModel; import test.ban.com.myapplication.model.UserModel; import test.ban.com.myapplication.view.IUserView; /** * 作者:ban on 16/8/18 15:47 */ public class UserPresenter { private IUserView mUserView; private IUserModel mUserModel; public UserPresenter(IUserView view) { this.mUserView = view; mUserModel = new UserModel(); } public void saveUser(int id,String firstName,String lastName){ mUserModel.setID(id); mUserModel.setFirstName(firstName); mUserModel.setLastName(lastName); } public void loadUser(int id){ UserBean userBean = mUserModel.load(id); mUserView.setFirstName(userBean.getFirstName()); mUserView.setLastName(userBean.getLastName()); } }
UserModel类
package test.ban.com.myapplication.model;/** * Created by apple on 16/8/18. */ import android.util.SparseArray; import test.ban.com.myapplication.bean.UserBean; /** * 作者:ban on 16/8/18 15:50 */ public class UserModel implements IUserModel { private String mFirstName; private String mLastName; private int mID; private SparseArray<UserBean> mUserArray = new SparseArray<UserBean>(); @Override public void setID(int id) { mID = id; } @Override public void setFirstName(String firstName) { mFirstName = firstName; } @Override public void setLastName(String lastName) { mLastName = lastName; UserBean userBean = new UserBean(mFirstName, mLastName); mUserArray.append(mID, userBean); } @Override public int getID() { return 0; } @Override public UserBean load(int id) { mID = id; UserBean userBean = mUserArray.get(mID, new UserBean("not found", "not found")); return userBean; } }
(5)Activity:
package test.ban.com.myapplication; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.Button; import android.widget.EditText; import test.ban.com.myapplication.persenter.UserPresenter; import test.ban.com.myapplication.view.IUserView; public class MainActivity extends AppCompatActivity implements View.OnClickListener, IUserView { private EditText mFirstNameEditText, mLastNameEditText, mIdEditText; private Button mSaveButton, mLoadButton; private UserPresenter mUserPresenter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mFirstNameEditText = (EditText) findViewById(R.id.first_name_edt); mLastNameEditText = (EditText) findViewById(R.id.last_name_edt); mIdEditText = (EditText) findViewById(R.id.id_edt); mSaveButton = (Button) findViewById(R.id.saveButton); mLoadButton = (Button) findViewById(R.id.loadButton); mUserPresenter = new UserPresenter(this); mSaveButton.setOnClickListener(this); mLoadButton.setOnClickListener(this); } @Override public int getID() { if (mIdEditText.getText().toString().isEmpty()) { mIdEditText.setText("123"); } return Integer.parseInt(mIdEditText.getText().toString()); } @Override public String getFristName() { return mFirstNameEditText.getText().toString(); } @Override public String getLastName() { return mLastNameEditText.getText().toString(); } @Override public void setFirstName(String firstName) { mFirstNameEditText.setText(firstName); } @Override public void setLastName(String lastName) { mLastNameEditText.setText(lastName); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.saveButton: mUserPresenter.saveUser(getID(), getFristName(), getLastName()); break; case R.id.loadButton: mUserPresenter.loadUser(getID()); break; default: break; } } }总结: v iew只负责处理与用户交互,并把与数据相关的数据仍给了presenter去处理。
这时presenter去调用model处理完数据后,在通过view的接口iuserview更新view的显示信息。