当前位置:网站首页>Mvc, Mvp and Mvvm
Mvc, Mvp and Mvvm
2022-08-04 00:20:00 【slow cavalry】
一.概念
1.Framework patterns and design patterns
- 简单理解,Frameworks are geared towards the reuse of a set of code that behaves the same,Design patterns, on the other hand, face the reuse of a series of code with the same structure;
- Three levels of reuse in software development
- 内部重用,An abstract block that can be used publicly in the same application;
- 代码重用,Common modules are grouped into libraries or utility classes,and reusable across multiple applications and domains;
- 应用框架的重用,Specialized domains provide general-purpose or off-the-shelf infrastructure,以获得最高级别的重用性;
二.Mvc
1.全称:Model–View–Controller
- 模型(Model)-视图(View)-控制器(Controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界
The face shows the separation of methods to organize the code; - 视图层(View)
- 对应于Xml布局文件和Java代码动态View部分;
- 控制层(Controller)
- MVC中Android的控制层是由Activity来承担的;
- Activity本来主要是作为初始化页面,展示数据的操作,但是因为XML视图功能太弱,所以Activity既要负责视图的显示又要加入控制逻辑,承担的功能过多;
- 模型层(Model)
- 针对业务模型,建立的数据结构和相关的类,它主要负责网络请求,数据库处理,I/O的操作;
- 通信方式(所有通信都是单向的)
- View 传送指令到 Controller;
- Controller 完成业务逻辑后,要求 Model 改变状态;
- Model 将新的数据发送到 View,用户得到反馈;
2.mvc在android中的代码实现
2.1.BaseModel,所有业务逻辑model的父类
public interface BaseModel {
//用于跟activity或者fragment生命周期同步,在destroy做一些销毁操作
void onDestroy();
}
2.2.Callback:根据View或者Controller调用Model时回调的参数个数选择使用
public interface Callback1<T> {
void onCallBack(T t);
}
public interface Callback2<T,P> {
void onCallBack(T t,P p);
}
2.3.具体的SampleModel
public class SampleModel implements BaseModel{
public void getUserInfo(String uid,Callback1<UserInfo> callback)
{
UserInfo userInfo= new HttpUtil<UserInfo>().get(uid);
callback.onCallBack(userInfo);
}
@Override
public void onDestroy() {
}
public class UserInfo
{
private int age;
private String name;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}
2.4.SampleActivity:充当View和Controller
public class SampleActivity extends AppCompatActivity {
private SampleModel sampleModel;
Button button;
EditText textView;
TextView tvAge,tvName;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sample);
sampleModel=new SampleModel();
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
getUserInfo(textView.getText().toString());
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
sampleModel.onDestroy();
}
/** * 获取用户信息 * @param uid */
private void getUserInfo(String uid)
{
sampleModel.getUserInfo(uid, new Callback1<SampleModel.UserInfo>() {
@Override
public void onCallBack(SampleModel.UserInfo userInfo) {
setDataToView(userInfo);
}
});
}
/** * 设置用户信息到view */
private void setDataToView(SampleModel.UserInfo userInfo)
{
tvAge.setText(userInfo.getAge());
tvName.setText(userInfo.getName());
}
}
3.Mvc总结
- 3.1.控制器Activity
- The main function is decoupling,将视图View和Model进行分离;
- View和Model在ActivityBind or complete other logic in;
- 3.2.优点
视图View和Model进行分离,降低耦合度; - 3.3.缺点
- Activity类过于臃肿;
- View 无法组件化.View 是强依赖特定的 Model 的,如果需要把View 抽出来作为一个另外一个应用程序可复用的组件就困难了;
二.Mvp
1.特点
- MVP 模式将 Controller 改名为 Presenter,同时改变了通信方向;
- 各部分之间的通信,都是双向的;
- View 与 Model 不发生联系,都通过 Presenter 传递;
- View 非常薄,不部署任何业务逻辑,称为"被动视图"(Passive View),即没有任何主动性,而 Presenter非常厚,所有逻辑都部署在那里;
2.Mvp代码示例
2.1.BasePresenter:类似于MVC中的BaseModel
public interface BasePresenter {
void onDestroy();
}
2.2.BaseView:是所有View的父类
- 将android中的viewabstracted out,只有跟view相关的操作都由baseView的实现类去完成.
public interface BaseView<P extends BasePresenter> {
void setPresenter(P presenter);
}
2.3.Contract 契约类
- 用于定义同一个界面的view的接口和presenter的具体实现.
- 好处是通过规范的方法命名和注释可以清晰的看到整个页面的逻辑.
public class SampleContract {
public static class Presenter implements BasePresenter
{
public void getUserInfo(String uid,Callback1<SampleModel.UserInfo> callback)
{
SampleModel.UserInfo userInfo= new HttpUtil<SampleModel.UserInfo>().get(uid);
callback.onCallBack(userInfo);
}
@Override
public void onDestroy() {
}
}
public interface View extends BaseView<Presenter>
{
void setDataToView(SampleModel.UserInfo userInfo);
}
}
2.4.SampleActivity
- SampleActivity实现了SampleContract.View只是作为View存在的
public class SampleActivity extends AppCompatActivity implements SampleContract.View{
private SampleContract.Presenter mPresenter;
Button button;
EditText textView;
TextView tvAge,tvName;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sample);
setPresenter(new SampleContract.Presenter());
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mPresenter.getUserInfo(textView.getText().toString(), new Callback1<SampleModel.UserInfo>() {
@Override
public void onCallBack(SampleModel.UserInfo userInfo) {
setDataToView(userInfo);
}
});
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
mPresenter.onDestroy();
}
@Override
public void setDataToView(SampleModel.UserInfo userInfo) {
tvAge.setText(userInfo.getAge());
tvName.setText(userInfo.getName());
}
@Override
public void setPresenter(SampleContract.Presenter presenter) {
mPresenter=presenter;
}
}
3.Mvp总结
- 通过引入接口BaseView,让相应的视图组件如Activity,Fragment去实现BaseView,实现了视图层的独立;
- 通过中间层Preseter实现了Model和View的完全解耦;
- 优点
- mvp解决了mvc的Controller和ViewIt is difficult to completely decouple the problem;
- View 可以进行组件化.在 MVP 当中,View 不依赖 Model.这样就可以让 View Detach from a specific business scenario
离出来,可以说 View 可以做到对业务逻辑完全无知.它只需要提供一系列接口提供给上层操作.这样就可
to be highly reusable View 组件;
- 缺点
随着业务逻辑的增加,一个页面可能会非常复杂,UI的改变是非常多,会有非常多的case,这样就会造成View的接口会很庞大.
三.Mvvm
- MVVM 模式将 Presenter 改名为 ViewModel,基本上与 MVP 模式完全一致;
- 唯一的区别是,它采用双向绑定(Mvvm的核心data-binding):View的变动,自动反映在 ViewModel,反之亦然;
- mvpWith the increase of business logic,UI的改变多的情况下,会有非常多的跟UI相关的case,这样就会造成View的接口会很庞大. mvvm解决了mvp的这个问题,通过双向绑定的机制,实现数据和UI内容,只要想改其中一方,另一方都能够及时更新的一种设计理念,这样就省去了很多在View层中写很多case的情况,只需要改变数据就行;
- Activity和xml layout充当View,ViewModel处理业务逻辑以及获取数据,弱化Model;
1.代码示例
1.1.BaseViewModel
- ViewMode层主要处理业务逻辑和获取数据,mViewDataBinding是通过View层传递过来.
public interface BaseViewModel {
void onDestroy();
}
public abstract class AbstractViewModel<T extends ViewDataBinding> implements BaseViewModel {
public T mViewDataBinding;
public AbstractViewModel(T viewDataBinding)
{
this.mViewDataBinding=viewDataBinding;
}
@Override
public void onDestroy() {
mViewDataBinding.unbind();
}
}
public class SampleViewModel extends AbstractViewModel<ActivitySampleMvvmBinding> {
public SampleViewModel(ActivitySampleMvvmBinding viewDataBinding) {
super(viewDataBinding);
}
public void getUserInfo(String uid, Callback1<SampleModel.UserInfo> callback)
{
//从网络或缓存获取信息
SampleModel.UserInfo userInfo=new SampleModel.UserInfo();
userInfo.setName("tom");
userInfo.setAge(18);
callback.onCallBack(userInfo);
}
}
2.Mvvm总结
- 解决MVP中View层好多接口的问题,让View变得更简洁;
- View的变动,自动反映在 ViewModel,反之亦然;
- 看起来MVVM很好的解决了MVC和MVP的不足,但是由于数据和视图的双向绑定,导致出现问题时不太好定位来源,有可能数据问题导致,也有可能业务逻辑中对视图属性的修改导致.如果项目中打算用MVVM的话可以考虑使用官方的架构组件ViewModel、LiveData、DataBinding去实现MVVM(项目中已经使用,至今有一年多,待,待改善、Organized into open source projects);
- 优点
- 提高可维护性.解决了 MVP 大量的手动 View 和 Model同步的问题,提供双向绑定机制.提高了代码的可维护性;
- 简化测试.mvp中View与ModelThe synchronization is handed overPresenter去做的,在mvvm中,No need to do it manually,交由databinding实现.Model变化,View会跟着Model同时变更,所以只需要保证Model的正确性,View就正确.大大减少了对 View 同步更新的测试;
- 缺点
- 过于简单的图形界面不适用,或说牛刀杀鸡;
- 对于大型的图形应用程序,视图状态较多,ViewModel的构建和维护的成本都会比较高;
- 数据绑定的声明是指令式地写在 View 的模版当中的,这些内容是没办法去打断点 debug 的;
四.Mvc/Mvp/Mvvm比较
- MvpNot a standardized pattern,它有很多种实现方式,You can modify it according to your needs or the way you think is rightMvp的实现方式,可以随Presenterchanges in complexity.Just make sure to passPresenter将View和Model解耦;
- 通过以上可以看出,MvcThe coupling is still relatively high,View可以直接访问Model,lead to the formation of a loop between the three;
- Mvc与Mvp的主要区别:Mvp的View不能直接访问Model,需要通过Presenter发出请求,View与Model不直接通信;
- Mvp和Mvvm的结构非常相似,唯一的区别是View和Model进行双向绑定,Changes in one of the two will be reflected in the other.而Mvp和Mvvm的主要区别是Mvp的View更新需要通过Presenter,而Mvvm不需要;
五.总结
- The project is simple,维护性不高,Package the module,No architecture or design patterns are required,只需要将每个模块封装好,方便调用即可,不要为了使用设计模式或架构方法而使用;
- Small projects can be usedMvc;
- Focus on data presentation and interaction(对于偏向展示型的App,绝大多数业务逻辑都在后端,App主要功能就是展示数据,交互等),建议采用Mvvm;
- 大型项目,Business complex adoptionMvp;
- 对于工具类或者需要写很多业务逻辑App,Mvp或者Mvvm都可,The architecture can be flexibly selected according to the specific project(如:混合架构)等;
六.参考
- 阮一峰-MVC,MVP 和 MVVM 的图示
- 任玉刚-MVC、MVP、MVVM,我到底该怎么选?
- 《Android源码设计模式解析与实战》
- Gityuan-Android技术架构演进与未来
边栏推荐
猜你喜欢
电子邮件安全或面临新威胁!
免费的公共WiFi不要乱连,遭中间人攻击了吧?
The world's first mass production, with the most fixed points!How does this AVP Tier1 lead?
研究生新生培训第四周:MobileNetV1, V2, V3
利用matlab求解线性优化问题【基于matlab的动力学模型学习笔记_11】
Nanoprobes Mono- Sulfo -NHS-Nanogold的使用和应用
After building the pytorch environment, the pip and conda commands cannot be used
pcl点云数据 转化为 Eigen::Map
ML18-自然语言处理
建木DevOps流程的快速运用
随机推荐
C语言 函数递归
代码重构:面向单元测试
POE交换机全方位解读(下)
The super perfect layout has shortcut keys and background replacement
状态机实验
Jmeter-参数化
孙宇晨受邀参加36氪元宇宙峰会并发表主题演讲
OpenCV 图像拼接
After building the pytorch environment, the pip and conda commands cannot be used
共享新能源充电桩充电站建设需要些什么流程及资料?
Install third-party packages via whl
微服务的简单介绍
高斯推断推导
corn表达式 具体详解与案例
米哈游--测试开发提前批
2022-08-03: What does the following go code output?A: 2; B: 3; C: 1; D: 0.package main import "fmt" func main() { slice := []i
The Beijing E-sports Metaverse Forum was successfully held
Justin Sun was invited to attend the 36氪 Yuan Universe Summit and delivered a keynote speech
因为一次bug的教训,我决定手撕Nacos源码(先撕客户端源码)
浅谈我国产业园区未来的发展方向