對比MVC/MVP/MVVM
- MVC:經(jīng)典的模式,model,view,controller,比較好理解,但是有些缺點(diǎn),承擔(dān)View角色的模塊包含了過多的業(yè)務(wù)邏輯
- MVP:衍生于MVC,雖然View和業(yè)務(wù)解耦了,但是Presenter承擔(dān)了太多任務(wù)
- MVVM:采用DataBinding,數(shù)據(jù)的渲染自動反映在ViewModel上,同時也可以通過ViewModel獲取數(shù)據(jù),但是業(yè)務(wù)處理堆在一塊。
基于此,想讓處理不同事情的模塊獨(dú)立起來,通過接口解耦,Presenter只負(fù)責(zé)remote data/native data的獲取,然后由ViewModel把數(shù)據(jù)跟View綁定起來,汲取MVP和MVVM所長,于是有了MVPVM。
補(bǔ)充:對于架構(gòu)模式的搭建,沒法說哪種更好,只有哪種更合適,不要局限于架構(gòu),結(jié)合業(yè)務(wù)特性,現(xiàn)有的人力和任務(wù)時間(采用架構(gòu)代碼量一般會增加,但是結(jié)構(gòu)會清晰),選取適合的框架。
MVPVM
參照MVP模式,采取contract接口隔離的方式,分離出View,Presenter,ViewWapper;Activity/Fragment實現(xiàn)View接口,提供Context下的API調(diào)用等,Presenter實現(xiàn)當(dāng)前模塊的業(yè)務(wù)數(shù)據(jù)獲取,ViewWrapper則負(fù)責(zé)把數(shù)據(jù)傳遞給ViewModel實現(xiàn)數(shù)據(jù)綁定,以及View傳遞的Event處理。如下圖:

抽離出Base類。
- BaseView ——— 抽象出來的需要Context環(huán)境的調(diào)用接口
- Presenter ——— 為實現(xiàn)架構(gòu)搭建,由BasePresenter實現(xiàn)接口
- ViewWrapper ——— 為實現(xiàn)架構(gòu)搭建,由BaseViewWrapper實現(xiàn)接口
- BaseActivity ——— 抽象出來的Base,即可由MvpVmActivity繼承,也可由業(yè)務(wù)Activity繼承
- BasePresenter ——— 抽象出來的MvpVm架構(gòu)的Presenter基類
- BaseViewWrapper ——— 抽象出來的MvpVm架構(gòu)的ViewWrapper基類
- MvpVmActivity ——— 抽象出來的MvpVm架構(gòu)的Activity基類
- MvpVmFragment ——— 抽象出來的MvpVm架構(gòu)的Fragment基類
- DemoActivity
BaseView
public interface BaseView {
public void setTitle(int titleId);
public void setTitle(String title);
public void showToast(int resId);
public void showToast(String msg);
public void showWaitDialog(int resId);
public void showWaitDialog(String message);
....
}
Presenter
public interface Presenter<V, VW> {
void attachView(V view);
void setViewWrapper(VW viewWrapper);
void detachView();
}
ViewWrapper
public interface ViewWrapper<V, D> {
void attachView(V view);
void detachView();
void setBinding(D dataBinding);
void onBind();
}
BaseActivity
public class BaseActivity<D extends ViewDataBinding> extends AppCompatActivity implements BaseView {
...
protected D dataBinding;
protected BaseActivity activity;
private BaseActivityDataBinding baseBinding;
protected <D extends ViewDataBinding> D generateDataBinding(@LayoutRes int layoutResID) {
D binding;
if (hasToolBar()) {
baseBinding = DataBindingUtil.setContentView(this, R.layout.activity_base);
...
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
binding = DataBindingUtil.inflate(inflater, layoutResID, baseBinding.contentLayout, true);
} else {
binding = DataBindingUtil.setContentView(this, layoutResID);
}
activity = this;
...
return binding;
}
}
generateDataBinding替換一般情況下調(diào)用的setContentView(int layoutId),在業(yè)務(wù)Avtivity中第一步調(diào)用dataBinding = generateDataBinding(R.layout.xxx)即返回對應(yīng)layout的DataBinding,用法后面demo中將會介紹。
BasePresenter
public class BasePresenter<V, VW> implements Presenter<V, VW> {
public V view;
protected VW viewWrapper;
...
@Override
public void attachView(V view) {
this.view = view;
}
@Override
public void setViewWrapper(VW viewWrapper) {
this.viewWrapper = viewWrapper;
}
@Override
public void detachView() {
view = null;
viewWrapper = null;
...
}
...
}
BaseViewWrapper
public class BaseViewWrapper<V, D extends ViewDataBinding> implements ViewWrapper<V, D> {
protected V view;
protected D dataBinding;
@Override
public void attachView(V view) {
this.view = view;
}
@Override
public void detachView() {
view = null;
if (dataBinding != null) {
dataBinding.unbind();
dataBinding = null;
}
}
@Override
public void setBinding(D dataBinding) {
this.dataBinding = dataBinding;
onBind();
}
@Override
public void onBind() {
}
}
onBind方法由業(yè)務(wù)ViewWrapper實現(xiàn),具體操作為DataBinding的數(shù)據(jù)綁定,以及l(fā)istener等事件的設(shè)置,會在后續(xù)博客中詳細(xì)介紹。
MvpVmActivity
public abstract class MvpVmActivity<P extends BasePresenter, VW extends BaseViewWrapper, D extends ViewDataBinding>
extends BaseActivity<D> {
protected P presenter;
protected VW viewWrapper;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
presenter = createPresenter();
viewWrapper = createViewWrapper();
if (presenter != null && viewWrapper != null) {
presenter.setViewWrapper(viewWrapper);
}
}
protected abstract P createPresenter();
protected abstract VW createViewWrapper();
@Override
protected void onDestroy() {
if (presenter != null) {
presenter.detachView();
}
if (viewWrapper != null) {
viewWrapper.detachView();
}
if (dataBinding != null) {
dataBinding.unbind();
dataBinding = null;
}
super.onDestroy();
}
}
createPresenter和createViewWrapper由業(yè)務(wù)Activity繼承實現(xiàn),實例化對應(yīng)業(yè)務(wù)的Presenter和ViewWrapper,后續(xù)博客會詳細(xì)介紹。
MvpVmFragment
public abstract class MvpVmFragment<P extends BasePresenter, VW extends BaseViewWrapper, D extends ViewDataBinding>
extends BaseFragment<D> {
protected P presenter;
protected VW viewWrapper;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
presenter = createPresenter();
viewWrapper = createWrapper();
if (presenter != null && viewWrapper != null) {
presenter.setViewWrapper(viewWrapper);
}
}
protected abstract P createPresenter();
protected abstract VW createWrapper();
@Override
public void onDestroyView() {
if (presenter != null) {
presenter.detachView();
}
if (viewWrapper != null) {
viewWrapper.detachView();
}
if (dataBinding != null) {
dataBinding.unbind();
dataBinding = null;
}
super.onDestroyView();
}
}
createPresenter和createViewWrapper由業(yè)務(wù)Activity繼承實現(xiàn),實例化對應(yīng)業(yè)務(wù)的Presenter和ViewWrapper,但是DataBinding實例的獲取與在Activity中略有不同,是在onCreateView中獲取的,后續(xù)博客會詳細(xì)介紹。
DemoActivity
public class MvpVmDemoActivity extends MvpVmActivity<MvpVmDemoPresenter, MvpVmDemoViewWrapper, MvpVmDemoDataBinding>
implements MvpVmDemoContract.View {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
dataBinding = generateDataBinding(R.layout.activity_mvpvm_demo);
if (viewWrapper != null) {
viewWrapper.setBinding(dataBinding);
}
presenter.fetchData();
}
@Override
protected MvpVmDemoPresenter createPresenter() {
return new MvpVmDemoPresenter(this);
}
@Override
protected MvpVmDemoViewWrapper createViewWrapper() {
return new MvpVmDemoViewWrapper(this);
}
...
}
從代碼中可以看到,在onCreate第一步就是生成對應(yīng)的DataBinding實例(關(guān)于DataBinding會在后續(xù)博客中專門講一次),然后設(shè)置給ViewWrapper,實現(xiàn)數(shù)據(jù)綁定關(guān)系,在createPresenter和createViewWrapper中實例化對應(yīng)業(yè)務(wù)的presenter和viewWrapper。
截至到此,MVPVM的Base框架就大體搭起來了,后續(xù)還會更新基于此框架的業(yè)務(wù)細(xì)節(jié)實現(xiàn)(Adapter、RecyclerView、DataBinding的高級用法以及網(wǎng)絡(luò)請求框架Retrofit二次封裝等)
才疏學(xué)淺,板磚輕拍