MVP架構是為了讓各個模塊之間降低耦合,方便維護,也可以讓代碼更簡潔,讓代碼簡潔的意思是讓代碼更清晰,並不是讓代碼更少;MVP契約者是為了進一步的低耦合、接口統一管理。
M(Model層) ——> 業務數據
V(View層)——> 視圖(activity,layout,自定義布局)
P(Presenter層)——> Model 和 View 之間的交互
MVP架構優點
- 降低耦合度,View層和Model層完全分離
- 所有View層和Model層的交互都交給Presenter層
- 后續擴展性和可維護性強
MVP架構缺點
- 復雜的業務會導致presenter層過大
- 通過UI事件的觸發對數據進行處理,activity 需要編寫大量的事件。通過事件調用 presenter 的業務處理方法,UI改變后牽扯的邏輯耦合度太高。
- 如果 Presenter 過多地渲染了視圖,往往會使得它與特定的視圖的聯系過於緊密,一旦視圖需要變更,那么 Presenter 也需要變更了。
分包
- base 包:基類
- common包:存放一些常量,接口,公用的東西
- contract包:契約者
- model包:M層
- presenter包:P層
- ui包:V層
- utils包:工具類
- widget包:存放自定義的組件
Base 基類
放到 base 包里
BaseActivity
/**
* V層Activity的一個基類
* @param <P>
* @param <CONTRACT>
*/
public abstract class BaseActivity<P extends BasePresenter, CONTRACT> extends AppCompatActivity implements Contract<CONTRACT>, View.OnClickListener {
//P層引用
public P mPresenter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(getContentViewId());
initView();
initData();
initListener();
mPresenter = getPresenterInstance(); //綁定P層
mPresenter.bindView(this);
}
/**
* 獲取布局id
* @return 返回布局id
*/
public abstract int getContentViewId();
/**
* 綁定組件
*/
public abstract void initView();
/**
* 設置監聽器
*/
public abstract void initListener();
/**
* 綁定數據
*/
public abstract void initData();
/**
* 獲取P層實例
*/
public abstract P getPresenterInstance();
@Override
protected void onDestroy() {
super.onDestroy();
destroy();
}
/**
* activity 銷毀時執行的操作
*/
public abstract void destroy();
}
BaseModel
/**
* Model層的一個基類
* @param <P>
* @param <CONTRACT>
*/
public abstract class BaseModel<P extends BasePresenter, CONTRACT> implements Contract<CONTRACT> {
/**
* 關聯P層
*/
public P mPresenter;
/**
* 綁定Presenter
* @param mPresenter
*/
public BaseModel(P mPresenter) {
this.mPresenter = mPresenter;
}
}
BasePresenter
/**
* P層的一個基類
* @param <V>
* @param <M>
* @param <CONTRACT>
*/
public abstract class BasePresenter<V extends BaseActivity, M extends BaseModel, CONTRACT> implements Contract<CONTRACT> {
//V層引用
public V mView;
//M層引用
public M mModel;
/**
* 綁定M層
*/
public BasePresenter() {
this.mModel = getModelInstance();
}
/**
* 綁定V層
* @param mView
*/
public void bindView(V mView) {
this.mView = mView;
}
/**
* 解綁V層
*/
public void unBindView() {
this.mView = null;
}
/**
* 獲取 M 層實例
* @return
*/
public abstract M getModelInstance();
}
Contract
/**
* 獲取契約者的接口
* @param <CONTRACT>
*/
public interface Contract<CONTRACT> {
/**
* 獲取契約者
* @return
*/
CONTRACT getContract();
}
契約
MVP的契約者(Contract)主要統一了接口管理,讓代碼看起來更清晰。
舉例
/**
* 登錄契約接口
*/
public interface ILogin {
/**
* V層和P層接口
*/
interface VP {
void requestLoginContract(String name, String pwd);
void responseLoginContract(boolean result);
}
/**
* M層接口
*/
interface M {
void requestLoginContract(String name, String pwd) throws SQLException;
}
}