前言
MVP的架構(gòu)模式是由傳統(tǒng)的MVC演變而來(lái),是一種為了簡(jiǎn)化Activity或Fragment等C層繁重的事務(wù)操作的架構(gòu)模式,代碼深度解藕(這里說(shuō)的解耦主要是縱向解耦),可讀性大大提高,但同時(shí)增加了代碼量。view層與model層各有對(duì)應(yīng)接口的引用在presenter層中,通過(guò)presenter層搭建“橋梁”實(shí)現(xiàn)無(wú)耦合。
了解
- 國(guó)際慣例,先貼圖抽象一下(圖片來(lái)自參考文獻(xiàn))

如上圖所示,在MVP模式中,視圖層與數(shù)據(jù)模型層無(wú)耦合,它們間接的通過(guò)P層來(lái)實(shí)現(xiàn)通信(就是在p層的引用中形成通信),圖片說(shuō)的比較抽象,下面上簡(jiǎn)易代碼。
需求設(shè)定在大部分app都需要的登錄模塊,假設(shè)登錄頁(yè)面有用戶信息輸入EditText,與確定登錄按鈕。
-
Model 層
public interface ILoginModel{
void login(String name, String Password,CallBack callBack);
}
Model業(yè)務(wù)實(shí)現(xiàn)層(callBack為登錄結(jié)果回調(diào)):
public class LoginModel implememt ILoginModel{
@Override
public void login(String name, String Password,CallBack callBack){
Api.login(name,password,callBack);
}
}
-
View
public interface ILoginView {
void loginSuccess();
void loginFailed(String error);
}
LoginActivity (View層):
public class LoginActivity extends Activity implement ILoginView{
Button btn;
...
@Override
public void onCreate(Bundle bundle){
}
@Override
public void loginSuccess(){
}
@Override
public void loginFailed(String error){
}
}
-
Presenter 層
public class LoginPresenter {
private ILoginModel loginModel;
private ILoginView loginView;
public LoginPresenter(ILoginView view){
this.loginView = view;
this.loginModel = new LoginModel();
}
public void login(String name,String password){
loginModel.login(name,password,new CallBack(){
@Override
public void success(){
//通知view層更新ui
loginView.loginSuccess();
}
@Override
public void failed(String error){
//通知view層更新ui
loginView.loginFailed(error);
}
}
}
}
在presenter中model層的業(yè)務(wù)實(shí)現(xiàn)方法由presenter間接調(diào)用,并根據(jù)不同的結(jié)果調(diào)用view的不同接口,所以,接下來(lái)view層應(yīng)該這么寫(xiě):
LoginActivity (View層):
public class LoginActivity extends Activity implement ILoginView{
private Button btn;
private LoginPresenter mPresenter;
...
@Override
public void onCreate(Bundle bundle){
mpresenter = new LoginPresenter(this);
...
btn.setOnClickListener(new OnClickListener(){
public void OnClick(View view){
String name = nameEditText.getText().toString();
String password = passwordEditText.getText().toString();
mPresenter.login(name,password);
}
});
}
@Override
public void loginSuccess(){
Log.d(TAG,"login success!");
}
@Override
public void loginFailed(String error){
Log.d(TAG,"login failed! reason:" + error );
}
}
這樣一來(lái),各層之間的職責(zé)就變得十分清晰,view層只管繪制,model層只管數(shù)據(jù)處理,而presenter層則是它們之間的橋梁。
進(jìn)階
其實(shí)在真正的MVP架構(gòu)模式設(shè)計(jì)的項(xiàng)目中,可能會(huì)有多個(gè)xxxModel,xxxView等接口類,如果命名不規(guī)范加上分包不明顯,代碼塊就會(huì)變得臃腫,不雅觀。為了避免這種問(wèn)題,可以將各自的model,view,presenter放在同一個(gè)類下,形成契約類,各自依賴關(guān)系,一目了然。
public interface LoginContract{
interface ILoginView extends BaseView{
void loginSuccess();
void loginFailed(String error);
}
interface ILoginModel extends BaseModel{
void login(String name, String Password,CallBack callBack);
}
abstract static class Presenter extends
BasePresenter<ILoginView , ILoginModel > {
public abstract void login();
}
}
上面出現(xiàn)的基類中,BaseView,BaseModel只是簡(jiǎn)單的接口繼承,下面讓我們來(lái)看一下BasePresenter:
public BasePresenter<T,E>{
private T mModel ;
private E mView;
public setVM(T m,E v){
this.mModel = m;
this.mView = v;
}
}
既然有了契約類,LoginPresenter就可以這樣寫(xiě)了:
public LoginPresenter extends LoginContract.Presenter {
public LoginPresenter(ILoginView view){
setVM(new LoginModel(),view);
}
@Override
public void login(){
}
}
總結(jié)
MVP模式是Android官方推薦的架構(gòu)模式,但是在這里建議大家不要為了MVP而MVP咯,只有在C層業(yè)務(wù)繁重,代碼耦合度高的情況下才會(huì)設(shè)計(jì)成mvp,像文章中的登錄案例就只是案例。

第一次寫(xiě)技術(shù)文章,覺(jué)得寫(xiě)的不錯(cuò)的同學(xué),點(diǎn)個(gè)贊支持下唄。哈哈 !