Android架构之MVC、MVP、MVVM

2023-11-02

转载请注明链接:https://blog.csdn.net/feather_wch/article/details/79729132

Android架构(MVC/MVP/MVVM与模块化、组件化)

版本:2019/3/2-1(10:00)

MVC

1、Android中MVC是什么?特点?

  1. Model:针对业务模型建立的数据结构和类(与View无关,只与业务相关)
  2. View:XML/JAVA或者JS+HTML进行页面的显示。
  3. Controller:Android的控制层通常在Activity、Fragment之中。
    本质就是Controller操作Model层的数据,并且将数据返回给View层展示。
    MVC

2、Android的MVC的缺点:

  1. Activity并不是MVC中标准的Controller,既有Controller的职责也有View的职责,导致Activity的代码过于臃肿。
  2. View层Model层互相耦合,不易于开发和维护。

MVP

3、Android中的MVP模式

  1. MVP(Model-View-Presenter)
  2. Model:主要提供数据的存储功能。Presenter需要通过Model存取数据。
  3. View: 负责处理点击事件和视图展示(Activity、Fragment或者某个View控件)
  4. Presenter: View和Model之间的桥梁,从Model检索数据后返回给View层。使得M/V之间不再有耦合关系。
    MVP

4、MVP和MVC的区别

  1. MVP中绝对不允许View直接访问Model
  2. 本质是增加了一个接口降低一层耦合度

5、MVP的特点

  1. Presenter完全将ModelView分离,主要逻辑处于Presenter中。
  2. Presenter具体View没有直接关联,通过定义好的接口进行交互。
  3. View变更时,可以保持Presenter不变(符合面向对象编程的特点)
  4. View只应该有简单的Set/Get方法、用户输入、界面展示的内容,此外没有更多内容。

6、MVP的缺点

  1. MVP的中使用了接口的方式去连接view层presenter层,如果有一个逻辑很复杂的页面,接口会有很多,导致维护接口的成本非常大。
  2. 解决办法:尽可能将一些通用的接口作为基类,其他的接口去继承。

7、MVP的实现

Model层

//Model层-数据的实体类:NetInfo.java
public class NetInfo {
    private int code;
    private String msg;
    public NetInfo(int code, String msg){
        this.code = code;
        this.msg = msg;
    }
    public int getCode() {
        return code;
    }
    public void setCode(int code) {
        this.code = code;
    }
    public String getMsg() {
        return msg;
    }
    public void setMsg(String msg) {
        this.msg = msg;
    }
}
//Model层-请求数据时View和Model的交互接口(中间层Presenter去实现):LoadTasksCallBack.java
public interface LoadTasksCallBack<T> {
    void onSuccess(T data);
    void onFailed();
}
//Model层-任务抽象基类【业务接口】: NetTask.java
public interface NetTask<T> {
    void execute(T data, LoadTasksCallBack callBack);
}
/**=============================================
 * Model层核心-具体任务【业务的实际操作】:
 *   1. 实现Model层获取数据的操作.
 * //NetInfoTask.java
 *=============================================*/
public class NetInfoTask implements NetTask<String>{
    @Override
    public void execute(String ip, LoadTasksCallBack callBack) {
        if("192.168.1.1".equals(ip)){
            callBack.onSuccess(new NetInfo(1, "This is a Msg from " + ip));
        }else{
            callBack.onFailed();
        }
    }
}

Presenter层

/**===========================================
 * 契约接口:
 *    存放相同业务的Preenter和View-便于查找和维护
 * //NetInfoContract.java
 *=============================================*/
public interface NetInfoContract{
    //1、Presenter定义了获取数据的方法
    interface Presenter{
        void getNetInfo(String ip);
    }
    //2、View中定义了与界面交互的方法
    interface View extends BaseView<Presenter> {
        void setNetInfo(NetInfo netInfo);
        void showError(String msg);
    }
}
/**=========================================
 * Presenter具体实现:NetInfoPresenter.info
 *   1. 分别与View层和Model层Task关联起来(持有了两者的对象)
 *   2. 实现接口getNetInfo()用于View层从Model层获取数据
 *   3. * 次要实现了Task执行中需要的回调接口-代理完成了View与Model的交互(避免了M/V的直接交互)
 *========================================*/
public class NetInfoPresenter implements NetInfoContract.Presenter, LoadTasksCallBack<NetInfo>{
    //1. View层
    private NetInfoContract.View mView;
    //2. Model层任务
    private NetTask mNetTask;
    //3. 分别与View和Model建立关联
    public NetInfoPresenter(NetInfoContract.View view, NetTask netTask){
        mNetTask = netTask;
        mView = view;
    }
    //4. 能让View层获取到Model层数据
    @Override
    public void getNetInfo(String ip) {
        mNetTask.execute(ip, this);
    }
    //5. 实现Model层需要的回调接口-作用是将Model层数据交给View层
    @Override
    public void onSuccess(NetInfo netInfo) {
        mView.setNetInfo(netInfo);
    }
    @Override
    public void onFailed() {
        mView.showError("error");
    }
}

View层

//BaseView.java
//View层的基类:定义了设置Presenter的接口
public interface BaseView<T> {
    void setPresenter(T presenter);
}
//HttpActivity.java
//  View层的具体实现:可以是Activity也可以是Fragment
public class HttpActivity extends Activity implements NetInfoContract.View{
    //1. 中间代理人
    private NetInfoContract.Presenter mPresenter;
    Button mGetButton, mSetButton;
    TextView mTitleTxtView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout_activity_http);
        mGetButton = findViewById(R.id.get_fromnet_button);
        mSetButton = findViewById(R.id.set_button);
        mTitleTxtView = findViewById(R.id.title_textview);

        /**==============================================
         *  1、给View层设置Presenter和Model层的Task(获取数据)
         *===============================================*/
        setPresenter(new NetInfoPresenter(this, new NetInfoTask()));

        /**==============================================
         *  2、View层通过Presenter去获取数据
         *===============================================*/
        mGetButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //TODO 从网络请求到数据
                mPresenter.getNetInfo("192.168.1.1");
            }
        });
        mSetButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mTitleTxtView.setText("Local Msg = Hello");
            }
        });
    }

    /**=====================================
     * 3、实现View层的三个接口:设置Presenter和View界面相关功能
     *====================================*/
    @Override
    public void setPresenter(NetInfoContract.Presenter presenter) {
        mPresenter = presenter;
    }
    @Override
    public void setNetInfo(NetInfo netInfo) {
        mTitleTxtView.setText(netInfo.getMsg());
    }
    @Override
    public void showError(String msg) {
        mTitleTxtView.setText(msg);
    }
}

MVVM

10、MVVM模式的作用和特点?

  1. Model-View-ViewModel,将Presenter替换为ViewModel
  2. ViewModelModel/View进行了双向绑定。
  3. View发生改变时,ViewModel会通知Model进行更新数据
  4. Model数据更新后,ViewModel会通知View更新
  5. Google发布了MVVM支持库Data Binding
    MVVM

模块化和组件化

11、什么是模块化

Modular programming is a software design technique that emphasizes separating the functionality of a program into independent, interchangeable modules, such that each contains everything necessary to execute only one aspect of the desired functionality.

  1. 一种软件设计技术
  2. 项目的功能拆分为独立可交换的模块
  3. 每个模块都包含执行单独功能必要内容

12、什么是组件化

  1. 组件化软件工程也被成为组件化开发,是一种软件工程的分支。
  2. 强调将一个软件系统拆分为独立的组件(组件可以使模块也可以是web资源等等)

13、模块化和组件化的区别

  1. 两者目的都是重用和解耦
  2. 主要是叫法不同
  3. 模块化侧重于重用,组件化更侧重于业务解耦

14、组件化优点

  1. 组件间可以灵活组建
  2. 一个组件的更改,只要对外提供的接口没有变化,则其他组件不需要再测试。
  3. 缺点:对技术、业务理解度有更高要求。

15、模块化的层次拆分

  1. 基础库
  2. 通用业务层
  3. 应用层

16、模块间通信

  1. 可以自己实现但比较麻烦
  2. 建议用阿里巴巴的开源库。

参考和学习资料

  1. 认清Android框架 MVC,MVP和MVVM
  2. Data Binding
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android架构之MVC、MVP、MVVM 的相关文章

随机推荐

  • python求两个整数的最大公约数_求两个数最大公约数的三种方法(Python实现),两数,python...

    求两个数的最大公约数 有三种方法 分别是 短除法 辗转相除法 更相减损法 短除法 运用短除法找到两个数的最大公约数 具体过程是逐步找出两个数的所有公约数 再把这些公约数累乘起来 就得到两个数的最大公约数 def func1 a int in
  • CEEMDAN代码,自适应噪声完备集合经验模态分别,C++代码下载

    CEEMDAN Complete Ensemble Empirical Mode Decomposition with Adaptive Noise 的中文名称是自适应噪声完备集合经验模态分解 要注意这个方法并不是在CEEMD方法上改进而来
  • npm install 报错

    困扰很久的问题终于解决 由于要在前端导出excel文件 需要xlsx模块 于是就使用npm来导入 npm install save xlsx file saver 但是尝试了很多次均报错 信息如下 由于报错信息很长 所以只能尝试截取不同的报
  • 功能测试基础之操作测试

    功能测试基础之操作测试 文章目录 功能测试基础之操作测试 操作测试简述 操作测试的验证标准 操作测试简述 操作测试主要是检验系统中的操作对象 菜单 按钮和输入框等 的设计是否符合软件设计标准和用户的操作习惯 页面内的各对象焦点是否顺序一致
  • vue 监听返回按钮

    移动端当用户使用默认返回按钮的时候 或左滑 或点击返回键 这时候需要监听返回按钮 1 挂载完成后 判断是否支持popstate mounted if window history window history pushState histo
  • 给出两个有序的整数数组A和B,请将数组B合并到数组A中,变成一个有序的数组。

    题目 一 给出两个有序的整数数组A和B 请将数组B合并到数组A中 变成一个有序的数组 注意 可以假设A数组有足够的空间存放B数组的元素 A和B中初始的元素数目分别为m和n public void merge int A int m int
  • Ubuntu 创建本地 Git 并与 Github(私有库) 交互(上传与下载)

    1 创建本地git并上传至github 首先先附上基础的教程 写的挺靠谱的 有一点值得注意 如果还不想公开自己的代码 记得在github上创建新库的时候点那个私有的选项 https www cnblogs com sawyer22 p 92
  • eclipes快捷键使用说明

    Ctrl 1 快速修复 最经典的快捷键 就不用多说了 Ctrl D 删除当前行 Ctrl Alt 复制当前行到下一行 复制增加 Ctrl Alt 复制当前行到上一行 复制增加 Alt 当前行和下面一行交互位置 特别实用 可以省去先剪切 再粘
  • Error during artifact deployment. See server log for details.

    实体类的double改成Double竟然启动报错这个 你敢信 感觉是这get的问题 还以为是打包出问题了 浪费好多时间 服 public Integer getOrderY return int y 5 public void setOrd
  • C#web启用目录查询功能

    当出现如下情况 直接找到iis安装目录 C Program Files IIS Express 然后cmd打开黑窗口 进入iis安装目录 cd C Program Files IIS Express 然后执行命令 把如图提示的命令 appc
  • 11个点告诉你 如何用Docker+jenkins 运行 python 自动化

    一 实现思路 在 Linux 服务器安装 docker 创建 jenkins 容器 根据自动化项目依赖包构建 python 镜像 构建自动化 python 环境 运行新的 python 容器 执行 jenkins 从仓库中拉下来的自动化项目
  • 浩辰CAD2021中文版

    教程 1 下载解压压缩包文件 得到64 32位安装包及文件 根据系统选择合适的安装包运行 进入安装引导界面 资源地址在评论区 2 进入安装引导后 选择软件的安装目录 正常默认即可 有需要的话也可自行更改 别忘记勾选同意软件许可协议 3 点击
  • 资深java软件工程师给大家的忠告

    java学习这一部分其实也算是今天的重点 这一部分用来回答很多群里的朋友所问过的问题 那就是我你是如何学习Java的 能不能给点建议 今天我是打算来点干货 因此咱们就不说一些学习方法和技巧了 直接来谈每个阶段要学习的内容甚至是一些书籍 这一
  • tomcat 虚拟节点

  • ContextLoaderListener作用详解

    ContextLoaderListener作用详解 1 目的 了解ContextLoaderListener的作用 2 作用 2 1 ContextLoaderListener监听器 1 ContextLoaderListener监听器的作
  • python利用opencv进识别行红绿灯

    目录 一 使用步骤 1 引入库 2 读入数据 3 获取帧率 4 创建函数将鼠标在图片中点击的坐标储存 5 逐帧采集视频并显示一帧图片来选择roi区域 6 最后逐帧采集视频并且放入循环一帧一帧的判断感兴趣区域中亮起的灯是哪个 二 全部代码 总
  • ChatGPT入门教程大纲

    第一部分 ChatGPT基础知识 ChatGPT概述 什么是ChatGPT ChatGPT的应用领域 ChatGPT的工作原理 语言模型和深度学习的概念 Transformer架构的介绍 预训练和微调的过程 ChatGPT的应用案例 与Ch
  • Linux·libusb源码编译

    libusb系列 Linux下libusb源码编译 源码下载及解压 下载源码 解压下载的源码压缩包 打开终端 准备编译环境 安装make dh autoreconf 安装 libudev dev sudo autogen sh sudo c
  • 使用函数指针,实现一个实用的C语言框架

    在上一篇 Qt动态库加载之 QLibrary 一文中 和大家分享了Qt 编译和调用C动态库的方法 在动态库中 我们使用了函数指针 借用函数指针实现C语言中的 多态 其次 在库中我们实现固定的算法和业务 将可能会更改的部分以接口的形式抛出 用
  • Android架构之MVC、MVP、MVVM

    转载请注明链接 https blog csdn net feather wch article details 79729132 Android架构 MVC MVP MVVM与模块化 组件化 版本 2019 3 2 1 10 00 文章目录