您的位置:首页 > 运维架构 > 网站架构

【编程素质】三层架构、MVC、MVP、MVVM

2017-07-12 11:53 218 查看

1,对比

1)MVC和三层架构

是完全不同的2种设计规范。但核心一致:分层,解耦。



2,MVC (Model View Controller)





工作原理:当用户出发事件的时候,view层会发送指令到controller层,接着controller去通知model层更新数据,model层更新完数据以后直接显示在view层上。

1)概念:

①M - 模型(model) :

应用程序核心,处理应用程序数据和逻辑。

负责在数据库中存取数据。

②V - 视图(view):

处理数据显示;

依据模型数据创建的、用于显示数据。

③C - 控制器(controller):

处理用户交互(输入)

负责从视图读取数据,控制用户输入,并向模型发送数据。比如:写入数据库记录

2)MVC与设计模式

MVC是复合模式,结合了:观察者模式、策略模式、组合模式。

①复合模式:

结合两个或两个以上的模式,组成一个解决方案,解决一再发生的一般性问题。

②从设计模式的角度看待M、V、C关系



③观察者模式:

模型是被观察者。

同一个模型可同时使用多个视图,当状态改变时,相关对象将持续更新。

④策略模式:

控制器是视图的策略。

视图只关心系统中可视的部分,对于任何界面行为,都委托给控制器处理。

控制器负责和模型交互来传递用户请求,对于工作是怎么完成的,视图毫不知情。

⑤组合模式:

视图使用组合模式实现用户界面。

用户界面通常组合了嵌套的组件,像面板、框架和按钮。

3)优缺点

缺点:view层和model层相互可知,可能存在耦合。(演化出了MVP、MVVM这两种框架)

3,三层架构

1)概念

①UIL - 界面层(User Interface layer):

显示数据和接收用户输入的数据,为用户提供一种交互式操作的界面。

表示为WEB方式、WINFORM方式。

②BLL - 业务逻辑层(Business Logic Layer):

对数据层的操作,对数据业务逻辑处理。

③DAL - 数据访问层(Data access layer):

对数据库的操作。

4,android框架MVC

1)MVC框架

对于原生的android项目:

①model层

java bean,类似repository类(spring中的注解:@Repository用于标注数据访问组件,即DAO组件)

注意:

对数据库的操作、网络等操作都应该放在model里面处理,当然对业务计算等操作也应该放在该层。

②view层

layout.xml、JS+html

③controller层

各类activity。

**注意:

不要在activity中写代码,要通过activity交割model业务逻辑处理,这样避免了activity执行耗时操作。**

5,MVP框架



1)View

activity和fragment。用于显示数据。

2)Presenter

负责逻辑的处理,处理关于用户事件的转发。

view层和presenter层的通信是通过接口实现的:activity、fragment可以去实现定义好的接口,而在对应的presenter中通过接口调用方法。

如果要实现的UI比较复杂,而且相关的显示逻辑还跟Model有关系,就可以在View和Presenter之间放置一个Adapter。由这个 Adapter来访问Model和View,避免两者之间的关联。而同时,因为Adapter实现了View的接口,从而可以保证与Presenter之间接口的不变。这样就可以保证View和Presenter之间接口的简洁,又不失去UI的灵活性。

3)Model | bean

提供数据。

4)与MVC区别

view层和model层不再相互可知,解耦。Presenter完全把Model和View进行了分离。通过MVP模式,可以编写测试用的View,模拟用户的各种操作,从而实现对Presenter的测试。这就解决了MVC模式中测试,维护难的问题。

在MVP模式里,View只应该有简单的Set/Get的方法,用户输入和设置界面显示的内容,除此就不应该有更多的内容,绝不容许直接访问Model–这就是与MVC很大的不同之处。

5)Android中MVP写法



BasalView

所有View的基类。以接口形式实现。

i>其中方法:

getContext方法必须有。

余下方法可根据需要自行创建。笔者这创建的其余3个方法是对话框方法。是为了在CouponPresenter中可以直接调用对话框:
basalView.showCircleProgressDialog();


ii>关联性

BasalAcivity、BasalFragment实现该接口和其中所有方法,避免在每个Acitivity中实现这些方法。

iii>代码

public interface BasalView {
Context getContext();
void showCircleProgressDialog();
void showToastShort(String message);
void dismissCircleProgressDialog();
void clearCircleProgressDialog();
}


BasalContract

契约类。所有Contract基类。

contract包定义了一系列的接口,用于联系View层和Presenter层。

i>方法:

两个方法,顾名思义,用来绑定和解除View。

ii>关联性:

所有contract接口实现该接口。

iii>代码:

public interface BasalContract<T extends BasalView> {
void attachView(T basalView);
void detachView();
}


BasalActivity

Acitivity基类。

i>关联性:

a.实现BasalView接口及其中方法

b.泛型类,绑定Presenter。

重点在于在initialize方法种绑定了Presenter,在onDestroy方法中解绑了Presenter。其余方法可根据需求自定义添删。

在具体的Acitivity中,通过initPresenter方法返回具体的Presenter.

c.抽象类。所有Activity继承此类。

ii>代码:

public abstract class BasalActivity<T extends BasalContract> extends AppCompatActivity implements BasalView {
public T presenter;
/**
* 获取布局资源
*
* @return
*/
protected abstract int getLayoutId();

/**
* 初始化布局控件
*/
protected abstract void initView();

/**
* 初始化Presenter
*
* @return
*/
protected abstract T initPresenter();

/**
* 加载数据
*/
protected abstract void loadData();

/**
* 为控件绑定事件
*/
protected abstract void viewOption();

@Override
protected void onCreate(Bundle savedInstanceState) {
// removeStatusBar();
super.onCreate(savedInstanceState);
setContentView(getLayoutId());
initialize();
}

private void initialize() {
presenter = initPresenter();
if (presenter != null) {
presenter.attachView(this);
}
initView();
loadData();
viewOption();
}

@Override
public Context getContext() {
return getActivity();
}

protected Activity getActivity() {
return this;
}

@Override
protected void onDestroy() {
if (presenter != null) {
presenter.detachView();
}
clearCircleProgressDialog();
super.onDestroy();
}

//转圈
private CircleProgressDialog circleProgressDialog;

@Override
public void showToastShort(String message) {

Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
}

@Override
public void showCircleProgressDialog(){
if (null == circleProgressDialog){

circleProgressDialog = new CircleProgressDialog(this);
circleProgressDialog.setCancelable(false);
}else{

dismissCircleProgressDialog();
}
circleProgressDialog.showDialog();
}
@Override
public void dismissCircleProgressDialog(){

if (null != circleProgressDialog) {
circleProgressDialog.dismiss();
}
}
@Override
public void clearCircleProgressDialog(){

if (null != circleProgressDialog) {
circleProgressDialog.dismiss();
}
circleProgressDialog = null;
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}

protected void removeStatusBar() {
// 当系统版本为4.4或者4.4以上时可以使用沉浸式状态栏
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
}
}
}


BasalFragment

Fragment基类。类似BasalActivity。

在此处仅贴出重要部分代码。

public abstract class BasalFragment<T extends BasalContract> extends Fragment implements BasalView {
protected T presenter;
Context context = null;
private View rootView;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = inflater.inflate(getLayoutId(), container, false);
ButterKnife.bind(this, rootView);
context = getActivity();
initialize();
return rootView;
}

protected void initialize() {
presenter = initPresenter();
if (presenter != null) {
presenter.attachView(this);
}
initView();
loadData();
viewOption();
}

@Override
public void onDestroyView() {
if (presenter != null) {
presenter.detachView();
}
super.onDestroyView();
}

/**
* 初始化presenter
*
* @return
*/
protected abstract T initPresenter();

/**
* 初始化视图控件
*/
protected abstract void initView();

/**
* 加载数据
*/
protected abstract void loadData();

/**
* 绑定事件
*/
protected abstract void viewOption();

/**
* 获取布局资源文件
*
* @return
*/
protected abstract int getLayoutId();

@Override
public Context getContext() {
return getActivity();
}


BasalPresenter

Presenter基类。

public abstract class BasalPresenter<T extends BasalView> implements BasalContract<T>{
protected Context context;
protected  T baselView;

@Override
public void attachView(T basalView) {
this.baselView = basalView;
context = baselView.getContext();
}

@Override
public void detachView() {
baselView = null;
}
}


CouponContract

该处举例一个优惠券功能的获取,并填充界面的功能。

i>关联性

由于在BasalPresenter中已经实现了BasalContract,对View已经绑定,在此不再实现。

在这个方法中定义其对应的Presenter中具体应该做什么方法。

ii>代码

public interface CouponContract {
void getCouponData(final int page, String typeStr);
}


CouponPresenter

这个类

i>关联性

实现对应的Contract接口。继承BasalPresenter,并传入对应的View(如CouponView)。

获取到数据后,进行处理,然后通过
basalView.方法
,传给对应界面(如实现了CouperView的CouponFragment)

ii>代码

public class CouponPresenter extends BasalPresenter<CouponView> implements CouponContract {
@Override
public void getCoupon(GetCouponRequest getCouponRequest,final int page, String typeStr) {

basalView.showCircleProgressDialog();

getCouponRequest.request(context, page + "", typeStr).setOnRequestListener(new OnRequestListener() {
@Override
public void resultBack(RequestDataBean requestDataBean) {

basalView.dismissCircleProgressDialog();
basalView.getCouponListSuccess(page,requestDataBean);
}
@Override
public void onError(Throwable e) {

basalView.dismissCircleProgressDialog();
basalView.getCouponListFall();
}
});
}
}


CouponView

i>方法:

对应Fragment或Acitivity中,需要填充数据的地方。

ii>代码

public interface CouponView extends BasalView {
void getCouponListSuccess(int page, RequestDataBean requestDataBean);
void getCouponListFall();
}


CouponFragment

具体显示界面的类。

i>方法

initPresenter()方法中返回具体的Presenter。

ii>关联性

继承BasalFragment,并指定泛型CouponPresenter。

实现CouponView,并实现其中方法。在这些方法中我们会获取对应的数据,只需要进行数据的填充即可。需要进行的逻辑处理可在对应的Presenter中进行。

iii>代码

仅显示关键部分代码:

public class CouponFragment extends BasalFragment<CouponPresenter> implements CouponView {
@Override
protected void loadData() {
presenter.getCoupon(getCouponRequest, pageList, couponType);
}
@Override
protected void viewOption() {

}
@Override
protected int getLayoutId() {
return R.layout.fragment_coupon;
}
@Override
protected CouponPresenter initPresenter() {
return new CouponPresenter();
}
@Override
protected void initView() {
setCouponRecyclerView();
}
@Override
public void getCouponListSuccess(int page, RequestDataBean requestDataBean) {

resultSuccess(page, requestDataBean);
}
@Override
public void getCouponListFall() {
}
}


6,MVVM

最早由微软提出的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: