Android 架构MVC MVP MVVM+实例

  • 1.View 接收用户交互请求

  • 2.View 将请求转交给ViewModel

  • 3.ViewModel 操作Model数据更新

  • 4.Model 更新完数据,通知ViewModel数据发生变化

  • 5.ViewModel 更新View数据

View/Model的变动,只要改其中一方,另一方都能够及时更新到

MVVM的优点


  • 1.提高可维护性。Data Binding可以实现双向的交互,使得视图和控制层之间的耦合程度进一步降低,分离更为彻底,同时减轻了Activity的压力。

  • 2.简化测试。因为同步逻辑是交由Binder做的,View跟着Model同时变更,所以只需要保证Model的正确性,View就正确。大大减少了对View同步更新的测试。

  • 3.ViewModle易于单元测试。

MVVM的缺点


  • 1.对于简单的项目,使用MVVM有点大材小用。

  • 2.对于过大的项目,数据绑定会导致内存开销大,影响性能。

  • 3.ViewModel和View的绑定,使页面异常追踪变得不方便。有可能是View出错,也有可能是ViewModel的业务逻辑有问题,也有可能是Model的数据出错。

MVP和MVC的最大区别

============

在MVP中View并不直接使用Model,它们之间的通信是通过Presenter 来进行的,所有的交互都发生在Presenter内部,而在MVC中View直接从Model中读取数据而不是通过 Controller。

如何选取框架

======

本来是要每个模式写一个适用场景,最后想想每个人都有自己的理解,别被他人束缚了。

一句话:适合自己的才是最好的!

实例

==

就这么一个界面咱通过MVC、MVP、MVVM分别搭建一下。

MVC实例


代码结构

1.在layout创建一个布局文件

<LinearLayout

…>

<EditText

android:id=“@+id/et_account”

…/>

<LinearLayout

…>

<EditText

android:id=“@+id/et_password”

…/>

<Button

android:id=“@+id/btn_login”

…/>

<Button

android:id=“@+id/btn_back”

…/>

2.实体类(User)

public class User {

private String name;

private String password;

public User() {}

//set or get …

public User(String name, String password) {

this.name = name;

this.password = password;

}

}

3.MVCLoginActivity

//用户点击事件

mvcBinding.mcvLogin.btnLogin.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

user.setName(mvcBinding.mcvLogin.etAccount.getText().toString());

user.setPassword(mvcBinding.mcvLogin.etPassword.getText().toString());

login(user);

}

});

//逻辑处理

private void login(User user){

if(!user.getName().isEmpty()&&!user.getPassword().isEmpty()){

if(user.getName().equals(“scc001”)&&user.getPassword().equals(“111111”))

{

Toast.makeText(this,“登录成功”,Toast.LENGTH_SHORT).show();

}else{

Toast.makeText(this,“登录失败”,Toast.LENGTH_SHORT).show();

}

}else {

Toast.makeText(this,“登录失败”,Toast.LENGTH_SHORT).show();

}

}

MVP实例


代码结构

1.Model层

实体类bean,同MVC中的User类,就不贴代码浪费大家时间了。

Model层所要执行的业务逻辑

/**

* 功能:接口,表示Model层所要执行的业务逻辑

*/

public interface LoginModel {

//User实体类;OnLoginFinishedListener presenter业务逻辑的返回结果

void login(User user, OnLoginFinishedListener listener);

}

实现类(实现LoginModel接口)

/**

* 功能:实现Model层逻辑

*/

public class LoginModelImpl implements LoginModel {

//第4步:验证帐号密码

@Override

public void login(User user, OnLoginFinishedListener listener) {

if(user.getName().isEmpty()||!user.getName().equals(“scc001”)){

//第5步:Model层里面回调Presenter层listener

listener.onUserNameError();

}else if(user.getPassword().isEmpty()||!user.getPassword().equals(“111111”)){

//第5步:Model层里面回调Presenter层listener

listener.onPasswordError();

}else {

//第5步:Model层里面回调Presenter层listener

listener.onSuccess();

}

}

}

2.Presenter层

当Model层得到请求的结果,回调Presenter层,让Presenter层调用View层的接口方法。

/**

* 功能:当Model层得到请求的结果,回调Presenter层,让Presenter层调用View层的接口方法。

*/

public interface OnLoginFinishedListener {

void onUserNameError();

void onPasswordError();

void onSuccess();

}

完成登录的验证,以及销毁当前View。

/**

* 功能:登录的Presenter的接口,实现类为LoginPresenterImpl,

* 完成登录的验证,以及销毁当前View。

*/

public interface LoginPresenter {

//完成登录的验证

void verifyData(User user);

//销毁当前View

void onDestroy();

}

Presenter实现类,引入 LoginModel(model)和LoginView(view)的引用

/**

* 功能:实现类,引入 LoginModel(model)和LoginView(view)的引用

*/

public class LoginPresenterImpl implements OnLoginFinishedListener, LoginPresenter {

//View层接口

private LoginView loginView;

//Model层接口

private LoginModel loginModel;

public LoginPresenterImpl(LoginView loginView) {

this.loginView = loginView;

this.loginModel = new LoginModelImpl();

}

//第6步:通过OnLoginFinishedListener验证结果回传到Presenter层

@Override

public void onUserNameError() {

if (loginView != null) {

//第7步:通过loginView回传到View层

loginView.setUserNameError();

loginView.hideProgress();

}

}

//第6步:通过OnLoginFinishedListener验证结果回传到Presenter层

@Override

public void onPasswordError() {

if (loginView != null) {

//第7步:通过loginView回传到View层

loginView.setPasswordError();

loginView.hideProgress();

}

}

//第6步:通过OnLoginFinishedListener验证结果回传到Presenter层

@Override

public void onSuccess() {

if (loginView != null) {

//第7步:通过loginView回传到View层

loginView.success();

loginView.hideProgress();

}

}

@Override

public void verifyData(User user) {

if (loginView != null) {

loginView.showProgress();

}

//第3步:调用model层LoginModel接口的login()方法

loginModel.login(user,this);

}

@Override

public void onDestroy() {

loginView = null;

}

}

3.View层

布局文件同MVC中的View层,就不贴代码浪费大家时间了。

Presenter与View交互是通过接口。

/**

* 功能:Presenter与View交互是通过接口。

* 接口中方法的定义是根据Activity用户交互需要展示的控件确定的。

*/

public interface LoginView {

//login是个耗时操作,加载中(一般用ProgressBar)

void showProgress();

//加载完成

void hideProgress();

//login账号失败给出提示

void setUserNameError();

//login密码失败给出提示

void setPasswordError();

//login成功

void success();

}

MVPLoginActivity

/**

* 功能:需要实现LoginView接口。

*/

public class MVPLoginActivity extends AppCompatActivity implements LoginView {

LoginPresenterImpl loginPresenterImpl;

@Override

protected void onCreate(@Nullable Bundle savedInstanceState) {

//创建一个Presenter对象

loginPresenterImpl = new LoginPresenterImpl(MVPLoginActivity.this);

//第1步:用户点击登录

mvpBinding.mvpLogin.btnLogin.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

User user = new User();

user.setName(mvpBinding.mvpLogin.etAccount.getText().toString());

user.setPassword(mvpBinding.mvpLogin.etPassword.getText().toString());

//第2步:调用Presenter接口中的验证方法

loginPresenterImpl.verifyData(user);

}

});

}

@Override

public void showProgress() {

//加载中

}

@Override

public void hideProgress() {

//加载完成

}

@Override

public void setUserNameError() {

//第7步:通过loginView回传到View层

//账号错误

Toast.makeText(this,“登录失败”,Toast.LENGTH_SHORT).show();

}

@Override

public void setPasswordError() {

//第7步:通过loginView回传到View层

//密码错误

Toast.makeText(this,“登录失败”,Toast.LENGTH_SHORT).show();

}

@Override

public void success() {

//第7步:通过loginView回传到View层

Toast.makeText(this,“登录成功”,Toast.LENGTH_SHORT).show();

//登录成功

}

@Override

protected void onDestroy() {

super.onDestroy();

loginPresenterImpl.onDestroy();

}

}

MVVM实例


1.Model层

实体类bean,继承BaseObservable

public class User extends BaseObservable{

private String name;

private String password;

public User() {

}

《960全网最全Android开发笔记》

《379页Android开发面试宝典》

《507页Android开发相关源码解析》

因为文件太多,全部展示会影响篇幅,暂时就先列举这些部分截图

加入社区》https://bbs.csdn.net/forums/4304bb5a486d4c3ab8389e65ecb71ac0
resenterImpl.onDestroy();

}

}

MVVM实例


1.Model层

实体类bean,继承BaseObservable

public class User extends BaseObservable{

private String name;

private String password;

public User() {

}

《960全网最全Android开发笔记》

[外链图片转存中…(img-dl1Q3QHc-1725661608838)]

《379页Android开发面试宝典》

[外链图片转存中…(img-2ssPHZvN-1725661608838)]

《507页Android开发相关源码解析》

[外链图片转存中…(img-lp7Povy4-1725661608839)]

因为文件太多,全部展示会影响篇幅,暂时就先列举这些部分截图

加入社区》https://bbs.csdn.net/forums/4304bb5a486d4c3ab8389e65ecb71ac0

### 回答1: Android MVVM Demo 是一个基于 MVVM(Model-View-ViewModel)设计模式的 Android 应用示例。这个 Demo 可以让开发者学习 MVVMAndroid 开发中的应用。 这个 Demo 的视图部分、模型部分以及 ViewModel 部分都是独立的。视图部分只用来展示数据及响应用户操作,模型部分只用来管理业务逻辑和数据操作,而 ViewModel 部分则是中间人,负责协调视图和模型之间的交互。 ViewModel 应该提供给视图数据绑定的 Observable 对象,这些 Observable 对象实际上是可观察的数据源。当 ViewModel 中的可观察数据源中的数据发生变化时,这些数据则会自动更新到视图中,从而达到实时同步的效果。 这个 Demo 的视图部分使用了 Android 原生的 Data Binding 技术,来实现视图与 ViewModel 的绑定。当视图需要更新 ViewModel 的数据时,只需要将这些数据绑定到视图上。而对于用户输入的操作,则由 ViewModel 中的命令类来监听并作出相应的反应。 总的来说,这个 Demo 给开发者提供了一个简单、可读性高、封装性强的 MVVM 示例。这个示例既可以为 MVVM 模式的初学者提供基础知识,也可以为实际应用场景的开发提供不少参考。 ### 回答2: Android MVVM(Model-View-ViewModel)是一种设计模式,其中视图通过数据绑定与ViewModel进行通信。ViewModel处理从Model获取的数据,并将其暴露给View,以便视图可以更新其状态。此外,ViewModel可以在用户界面和后端之间充当中间人,并处理业务逻辑。 Android MVVM demo演示了如何在Android应用程序中使用MVVM设计模式。这个demo使用了Android的数据绑定库和LiveData组件。在这个demo中,我们创建一个简单的登录应用程序,在用户输入用户名和密码之后验证用户凭据。我们使用ViewModel来存储和管理用户输入和验证状态,以及LiveData来观察ViewModel中的数据变化并将其更新到用户界面。在用户输入凭据时,ViewModel负责更新LiveData,从而更新UI组件。此外,我们还使用了数据绑定库,它允许我们直接将UI组件绑定到ViewModel中的属性,以便它们可以自动更新。 通过使用MVVM设计模式,我们可以将UI逻辑与业务逻辑分离,从而使我们的代码更易于管理和测试。此外,使用LiveData来观察ViewModel中的数据变化还可以减少我们的代码量和逻辑复杂度。通过观察LiveData,我们可以在需要更新UI时自动更新UI组件,而不必手动处理每个UI组件。这使得我们的代码更加简单,易于维护。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值