MVP是從MVC演變過來的。M即Model層負責提供數據,V即View層負責顯示,P指Presenter層負責邏輯處理。在MVP中View不直接使用Model,它們通過Presenter來通信,它們之間的交互都在Presenter內部進行。實現了View和Model的耦合。<! more 在MVP中 ...
MVP是從MVC演變過來的。M即Model層負責提供數據,V即View層負責顯示,P指Presenter層負責邏輯處理。在MVP中View不直接使用Model,它們通過Presenter來通信,它們之間的交互都在Presenter內部進行。實現了View和Model的耦合。
在MVP中,目前體會到的有點有:
因為Presenter把Model和View進行了完全的分離。邏輯都放在Presenter里實現。而Presenter是通過定義好的介面與View進行交互的,從而使得View出現改變的時候,Presenter也可以保持不變!
在測試方面,因為邏輯都是寫在Presenter當中的,我們完全可以在Model和View的介面實現還沒有具體內容的時候,就對presenter中的邏輯進行測試。
甚至,我們也可以把Presenter可以用於多個視圖,而不需要改變Presenter的邏輯。
不過,若是Presenter與某個View的聯繫過於緊密,往往View有大的變更的話,Presenter也是需要變更的。
接下來,我們通過一個簡單的一睹MVP的真容吧。首先,有個需求,需要一個登陸界面,用戶需要輸入用戶名和密碼後點擊登錄按鈕進行登錄。
簡單的做一個界面:
創建項目後,為了便於理解,我們把包結構分成了三層,如下:
- 定義一個view介面:
```
/** - 這邊定義頁面需要的介面
- 比如登錄頁面,用戶名和密碼的輸入框的獲取和輸入的方法,按鈕的點擊方法及登錄失敗提示方法
Created by Administrator on 2015/12/30.
*/
public interface ILoginView {void setUserName(String userName);
void setPassword(String password);
String getUserName();
String getPassword();
void loginClick(onclickListen listener);
}
```在Activity對介面進行實現,代碼如下:
public class LoginActivity extends Activity implements ILoginView {
EditText userName,password;
Button login;
private onclickListen listener;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout);
initView();
}
private void initView() {
userName = (EditText) findViewById(R.id.user);
password = (EditText) findViewById(R.id.pwd);
login = (Button) findViewById(R.id.btn_login);
login.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
listener.click();//自定義的按鈕監聽介面
}
});
}
@Override
public void setUserName(String userNames) {
userName.setText(String.valueOf(userNames));
}
@Override
public void setPassword(String passwords) {
password.setText(String.valueOf(passwords));
}
@Override
public String getUserName() {
if (TextUtils.isEmpty(userName.getText().toString().trim()))
return null;
return userName.getText().toString().trim();
}
@Override
public String getPassword() {
if (TextUtils.isEmpty(password.getText().toString().trim()))
return null;
return password.getText().toString().trim();
}
@Override
public void loginClick(onclickListen listener) {
this.listener = listener;
}
@Override
public void showError() {
Toast.makeText(this,"賬號或密碼輸入錯誤",Toast.LENGTH_SHORT).show();
}
這邊的按鈕監聽事件也是自己定義的一個介面,代碼如下
public interface onclickListen {
void click();
}
- view成的實現到這邊就完成,接著是model的實現,我們要創建一個login的實現介面,
/**
* model中的介面,登錄功能主要是實現根據賬號密碼驗證是否正確。
*/
public interface ILoginOnServer {
boolean login(String userName,String userPassword);
}
- 實現介面方法
public class LoginOnServer implements ILoginOnServer{
@Override
public boolean login(String userName, String userPassword) {
//在這邊實現驗證的功能
return true;
}
}
- 最後,在presenter中實現業務邏輯
**
* 邏輯業務都在這邊實現
*/
public class LoginPresenter {
private ILoginView loginView;
private ILoginOnServer loginOnServer;
public LoginPresenter(ILoginView view){
loginView = view;
userLogin();
}
private void userLogin() {
loginOnServer = new LoginOnServer();
boolean isTrue = loginOnServer.login(loginView.getUserName(),loginView.getPassword());
if(isTrue){//通過驗證進入首頁
}else{//驗證失敗提示
loginView.showError();
}
}
}
從這個簡單的案例可以看出,MVP模式是把邏輯業務提取到Presenter中實現,避免view層中的代碼過於雜亂。
這篇文章之所以是入門篇,是因為這隻是大致介紹下MVP的概念,真正實戰開發的時候還需要考慮到其他問題,比如Activity的生命周期以及異常重啟的情況等情況。
更多文章也可關註我的靜態博客,更新相對會優先些傳送門