Android中MVP模式與MVC模式比較(含示例)
MVP
介紹
MVP模式(Model-View-Presenter)是MVC模式的一個衍生。主要目的是為了解耦,使項目易于維護。
- Model 依然是業務邏輯和實體模型
- View 經常由Activity實現,包含Presenter的引用。所要做的就是當有交互時,調用Presenter里的對應方法。
- Presenter 負責完成View于Model間的交互,從Model里取數據,返回給View處理好的數據。
為什么使用MVP
在以往的Android開發中,Activity并不是一個標準的MVC模式中的Controller, 它的加載應用的布局和初始化用戶界面,接受并處理來自用戶的操作請求,進而作出響應。但是隨著界面及其邏輯的復雜度不斷提升,Activity類的職責不斷增加,以致變得龐大臃腫。當我們將其中復雜的邏輯處理移至另外的一個類(Presneter)中時,Activity其實就是MVP模式中View,它負責UI元素的初始化,建立UI元素與Presenter的關聯(Listener之類),同時自己也會處理一些簡單的邏輯(復雜的邏輯交由Presenter處理)。
對于測試來說,在MVP模式中,處理復雜邏輯的Presenter是通過interface與View(Activity)進行交互的。我們可以通過自定義類實現這個interface來模擬Activity的行為對Presenter進行單元測試,省去了大量的部署及測試的時間。
MVC介紹
- Model 是應用程序中用于處理應用程序數據邏輯的部分。
- View 是應用程序中處理數據顯示的部分。
- Controller是應用程序中處理用戶交互的部分。
具體介紹請戳這里
比較
MVP模式:
- View不直接與Model交互 ,而是通過與Presenter交互來與Model間接交互
- Presenter與View的交互是通過接口來進行的,更有利于添加單元測試
- 通常View與Presenter是一對一的,但復雜的View可能綁定多個Presenter來處理邏輯
MVC模式:
- View可以與Model直接交互
- Controller是基于行為的,并且可以被多個View共享
- 可以負責決定顯示哪個View
示例
一個登陸注冊的例子。
目錄結構
Model
Model為User的信息,項目里省略了,當然你也可以新建一個User類
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 ; } }
View
public class LoginActivity extends Activity implements LoginView, View.OnClickListener { private ProgressBar progressBar; private EditText username; private EditText password; private LoginPresenter presenter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_login); progressBar = (ProgressBar) findViewById(R.id.progress); username = (EditText) findViewById(R.id.username); password = (EditText) findViewById(R.id.password); findViewById(R.id.button).setOnClickListener(this); presenter = new LoginPresenterImpl(this); } @Override public void onClick(View v) { presenter.validateCredentials(username.getText().toString(), password.getText().toString()); } ... ...
可以看到LoginActivity implements了兩個接口,LoginView, View.OnClickListener。LoginView是在Presenter中用來與Activity通信的。在onClick()方法中調用了presenter進行事務處理。
LoginView.java
public interface LoginView { void showProgress(); void hideProgress(); void setUsernameError(); void setPasswordError(); void navigateToHome(); }
Presenter
public class LoginPresenterImpl implements LoginPresenter, OnLoginFinishedListener { private LoginView loginView; private LoginInteractor loginInteractor; public LoginPresenterImpl(LoginView loginView) { this.loginView = loginView; this.loginInteractor = new LoginInteractorImpl(); } @Override public void validateCredentials(String username, String password) { if (loginView != null) { loginView.showProgress(); } loginInteractor.login(username, password, this); } @Override public void onUsernameError() { if (loginView != null) { loginView.setUsernameError(); loginView.hideProgress(); } } ... ...
可以發現,在onUsernameError()方法中,把處理好的結果通過LoginView接口返還給Activity進行顯示。
到此為止,整個流程就跑通了,M存儲數據,V交互,P處理邏輯。V和P之間通過接口通信。
示例源碼戳這里
來自: http://blog.csdn.net/l664675249/article/details/50542524