**本文僅為個人在學習mvp模式中的一點個人見解
M:
model,實體層,此處不是傳統(tǒng)的實體,我們需要把實體視圖化,可以理解為Viewmodel,例如一個登陸視圖,含有用戶名、密碼,我們需要把model視圖化,并綁定到視圖上(我理解為該model的行為,如登陸、修改密碼)
V:
view,視圖層對應xml,Activity,Fragment
P:
Presenter,邏輯控制層,同時持有model與view對象
*采用MVP模式的優(yōu)勢是:
把業(yè)務邏輯抽離到Presenter層中,View層專注于UI的處理。
分離視圖邏輯與業(yè)務邏輯,達到解耦的目的。
提高代碼的閱讀性。
Presenter被抽象成接口,可以根據(jù)Presenter的實現(xiàn)方式進行單元測試。
可拓展性強。
*采用MVP模式的缺點:
項目結構會對后期的開發(fā)和維護有一定的影響。具體視APP的體量而定。
代碼量會增多,如何避免編寫過多功能相似的重復代碼是使用MVP開發(fā)的一個重點要處理的問題。
有一定的學習成本。
以用戶登陸為例:
model層的具體代碼
提供想要展示在view層的數(shù)據(jù)和業(yè)務邏輯實現(xiàn)
一、創(chuàng)建用戶model
public class User {
public String account;
public String pwd;
}
二、把model視圖化
創(chuàng)建user的行為接口
public interface UserApi {
interface LoginListener{
void onSuccess();
void onFail();
}
void login(User user, LoginListener listener);
}
三、實現(xiàn)行為接口
public class UserImpl implements UserApi{
@Override
public void login(final User user, final LoginListener listener) {
//模擬登陸
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
if (TextUtils.isEmpty(user.account)||TextUtils.isEmpty(user.pwd)){
return;
}
int i =new Random().nextInt(1);
if (i==0){
listener.onSuccess();
}else {
listener.onFail();
}
}
},2000L);
}
}
View層的具體代碼
負責數(shù)據(jù)顯示、題提供用戶交互;設置監(jiān)聽后把工作叫個Presenter,因此持有Presenter, 調用Presenter中的相關方法即可。
public class UserViewApi {
public interface Login{
void starLogin();
void loginEnd();
void loginSuccess();
void loginFail();
}
}
public class LoginActivity extends Activity implements UserViewApi.Login {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
new UserPresenter(this,new UserImpl()).loginToServer(new User());
}
@Override
public void starLogin() {
}
@Override
public void loginEnd() {
}
@Override
public void loginSuccess() {
}
@Override
public void loginFail() {
}
}
Presenter層具體代碼
Presenter在view與model中間層,獲得model數(shù)據(jù)后構建到view,可以決定view層的各種操作
public interface UserPresenterApi {
void loginToServer(User user);
}
public class UserPresenter implements UserPresenterApi, UserApi.LoginListener {
private UserViewApi.Login viewApi;
private UserImpl userImpl;
public UserPresenter(UserViewApi.Login viewApi, UserImpl user){
this.viewApi = viewApi;
this.userImpl = user;
}
@Override
public void loginToServer(User user) {
viewApi.starLogin();
userImpl.login(user,this);
}
@Override
public void onSuccess() {
viewApi.loginEnd();
viewApi.loginSuccess();
}
@Override
public void onFail() {
viewApi.loginEnd();
viewApi.loginFail();
}
}