MVP模式
- Model:數(shù)據(jù)層谣辞。其中應(yīng)該包括數(shù)據(jù)的請求以及相應(yīng)的處理趋惨。
- View:視圖層惭缰。在Android中應(yīng)該是指Activity
- Presenter:管控層。其主要負(fù)責(zé)協(xié)調(diào)Model層和View層的工作。
View層
區(qū)別于MVC的是MVP模式將Activity劃到了View層定踱,它只負(fù)責(zé)更新視圖,并且接收視圖的操作,交給對應(yīng)的Presenter去執(zhí)行對應(yīng)的具體邏輯懒闷。以下是一個(gè)登陸MVP模式實(shí)例。
//視圖的總接口
public interface IView {
}
public interface ILoginView extends IView {
String getUserName();
String getPassword();
void onLoginSeccess();
void onLoginFails();
}
public class LoginActivity extends AppCompatActivity implements ILoginView{
private EditText mUserNameEdit;
private EditText mPasswordEdit;
private Button mLoginBtn;
private LoginPresenter mPresenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setView();
setData();
}
private void setView() {
this.mUserNameEdit = findViewById(R.id.login_act_edit_user_name);
this.mPasswordEdit = findViewById(R.id.login_act_edit_user_pass);
this.mLoginBtn = findViewById(R.id.login_act_btn_login);
mLoginBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mPresenter.login();
}
});
}
private void setData() {
this.mPresenter = new LoginPresenter(this);
}
@Override
public String getUserName() {
return mUserNameEdit.getText().toString();
}
@Override
public String getPassword() {
return mPasswordEdit.getText().toString();
}
@Override
public void onLoginSeccess() {
Toast.makeText(getApplicationContext(), "登陸成功栈幸!", Toast.LENGTH_LONG).show();
}
@Override
public void onLoginFails() {
Toast.makeText(getApplicationContext(), "登錄失敺吖馈!", Toast.LENGTH_LONG).show();
}
@Override
protected void onDestroy() {
super.onDestroy();
//記得在銷毀的時(shí)候斷掉引用鏈速址,養(yǎng)成良好的習(xí)慣
this.mPresenter = null;
}
}
Presenter
MVP模式中的Presenter主要是將MVC模式中的Controller的邏輯部分抽了出來單獨(dú)實(shí)現(xiàn)玩焰,其主要職責(zé)是接受View的消息,調(diào)用Model去處理這個(gè)消息并根據(jù)處理結(jié)果去主動刷新View壳繁,一個(gè)View可以對應(yīng)一個(gè)或多個(gè)Presenter震捣。
public class PresenterFather {
protected IModel mIModel;
//此處View個(gè)人感覺最好用一個(gè)弱引用。
protected WeakReference<IView> mViewReference;
}
public class LoginPresenter extends PresenterFather {
public LoginPresenter(ILoginView loginView) {
this.mIModel = new LoginMode();
this.mViewReference = new WeakReference<IView>(loginView);
}
public void login() {
if (mIModel != null && mViewReference != null && mViewReference.get() != null)
ILoginView loginView = (ILoginView) mViewReference.get();
String name = loginView.getUserName();
String passWord = loginView.getPassword();
loginView = null;
//此時(shí)LoginListener作為匿名內(nèi)部類是持有外部類的引用的闹炉。
((LoginMode)mIModel).login(name, passWord, new LoginLisentener() {
@Override
public void onSeccess() {
if (mViewReference.get() != null) {
((ILoginView)mViewReference.get()).onLoginSeccess();
}
}
@Override
public void onFails() {
if (mViewReference.get() != null) {
if (mViewReference.get() != null) {
((ILoginView)mViewReference.get()).onLoginFails();
}
}
}
});
}
}
}
Model
model層和MVC差不多蒿赢,都是用來獲取數(shù)據(jù)并對數(shù)據(jù)做一些處理的。在目前Android中其實(shí)大多是已經(jīng)封裝好的網(wǎng)絡(luò)請求庫渣触,個(gè)人覺得不用單獨(dú)抽出來羡棵。一個(gè)Presenter中可以有多個(gè)model,一個(gè)model也可以被多個(gè)Presenter引用嗅钻。
public interface IModel {
}
public class LoginMode implements IModel {
//model 負(fù)責(zé)數(shù)據(jù)以及業(yè)務(wù)邏輯皂冰。
private String mUserName = "yayali";
private String mPassWord = "123";
public void login(String username, String password, LoginLisentener lisentener) {
if (lisentener == null) {
return;
}
if (mUserName.equals(username) && mPassWord.equals(password)){
lisentener.onSeccess();
} else {
lisentener.onFails();
}
}
}
個(gè)人評價(jià)
MVP面向接口編程店展,Model,View秃流,Presenter只處理單一的邏輯赂蕴,很好的做到了解耦。將MVC中Activity的邏輯處理抽出來由一個(gè)或者多個(gè)Presenter處理舶胀,只負(fù)責(zé)視圖的響應(yīng)和更新概说,其中的Activity的代碼減少了很多。但是最大的問題在于嚣伐,會出現(xiàn)很多的接口糖赔、類文件,一般人在開發(fā)過程中恐怕不愿意去做“這么麻煩”的事轩端。