编程进阶网编程进阶网
  • 基础组成体系
  • 程序编程原理
  • 异常和IO系统
  • 六大设计原则
  • 设计模式导读
  • 创建型设计模式
  • 结构型设计模式
  • 行为型设计模式
  • 设计模式案例
  • 面向对象思想
  • 基础入门
  • 高级进阶
  • JVM虚拟机
  • 数据集合
  • Java面试题
  • C语言入门
  • C综合案例
  • C标准库
  • C语言专栏
  • C++入门
  • C++综合案例
  • C++专栏
  • HTML
  • CSS
  • JavaScript
  • 前端专栏
  • Swift
  • iOS入门
  • 基础入门
  • 开源库解读
  • 性能优化
  • Framework
  • 方案设计
  • 媒体音视频
  • 硬件开发
  • Groovy
  • 常用工具
  • 大厂面试题
  • 综合案例
  • 网络底层
  • Https
  • 网络请求
  • 故障排查
  • 专栏
  • 数组
  • 链表
  • 栈
  • 队列
  • 树
  • 递归
  • 哈希
  • 排序
  • 查找
  • 字符串
  • 其他
  • Bash脚本
  • Linux入门
  • 嵌入式开发
  • 代码规范
  • Markdown
  • 开发理论
  • 开发工具
  • Git管理
  • 百宝箱
  • 开源协议
  • 技术招聘
  • 测试经验
  • 职场提升
  • 技术模版
  • 关于我
  • 目标清单
  • 学习框架
  • 育儿经验
  • 我的专栏
  • 底层能力
  • 读书心得
  • 随笔笔记
  • 职场思考
  • 中华历史
  • 经济学故事
  • 基础组成体系
  • 程序编程原理
  • 异常和IO系统
  • 六大设计原则
  • 设计模式导读
  • 创建型设计模式
  • 结构型设计模式
  • 行为型设计模式
  • 设计模式案例
  • 面向对象思想
  • 基础入门
  • 高级进阶
  • JVM虚拟机
  • 数据集合
  • Java面试题
  • C语言入门
  • C综合案例
  • C标准库
  • C语言专栏
  • C++入门
  • C++综合案例
  • C++专栏
  • HTML
  • CSS
  • JavaScript
  • 前端专栏
  • Swift
  • iOS入门
  • 基础入门
  • 开源库解读
  • 性能优化
  • Framework
  • 方案设计
  • 媒体音视频
  • 硬件开发
  • Groovy
  • 常用工具
  • 大厂面试题
  • 综合案例
  • 网络底层
  • Https
  • 网络请求
  • 故障排查
  • 专栏
  • 数组
  • 链表
  • 栈
  • 队列
  • 树
  • 递归
  • 哈希
  • 排序
  • 查找
  • 字符串
  • 其他
  • Bash脚本
  • Linux入门
  • 嵌入式开发
  • 代码规范
  • Markdown
  • 开发理论
  • 开发工具
  • Git管理
  • 百宝箱
  • 开源协议
  • 技术招聘
  • 测试经验
  • 职场提升
  • 技术模版
  • 关于我
  • 目标清单
  • 学习框架
  • 育儿经验
  • 我的专栏
  • 底层能力
  • 读书心得
  • 随笔笔记
  • 职场思考
  • 中华历史
  • 经济学故事
  • 基础入门
  • 开源库解读
  • 性能优化
  • Framework
  • 方案设计
  • 媒体音视频
  • 硬件开发
  • Groovy
  • 常用工具
  • 大厂面试题

目录介绍

  • 01.整体概述
    • 1.1 项目背景
    • 1.2 架构有哪几种
    • 1.3 架构演变过程
    • 1.4 多种架构对比
    • 1.5 设计目标
    • 1.6 产生收益分析
  • 02.MVC架构设计
    • 2.1 MVC简单介绍
    • 2.2 MVC应用场景
    • 2.3 通俗理解MVC
    • 2.4 MVC缺陷分析
    • 2.5 MVC架构演进
  • 03.MVP架构设计
    • 3.1 MVP简单介绍
    • 3.2 MVP应用场景
    • 3.3 MVP缺陷分析
    • 3.4 MVP常规实践
    • 3.5 MVP架构演进
  • 04.MVVM架构设计
    • 4.1 MVVM简单介绍
    • 4.2 MVVM应用场景
    • 4.3 MVVM缺陷分析
    • 4.4 MVVM常规实践
    • 4.5 MVVM架构演进
  • 05.方案基础设计
    • 5.1 整体架构图
    • 5.2 UML设计图
    • 5.3 关键流程图
    • 5.4 接口设计图
    • 5.5 模块间依赖关系
  • 06.其他设计说明
    • 6.1 性能设计
    • 6.2 稳定性设计
    • 6.3 灰度设计
    • 6.4 降级设计
    • 6.5 异常设计

01.整体概述

1.1 项目背景

1.2 架构有哪几种

  • MVC架构
    • MVC全名是Model View Controller,如图,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。
  • MVP架构
    • MVP从更早的MVC框架演变过来,与MVC有一定的相似性:Controller/Presenter负责逻辑的处理,Model提供数据,View负责显示。
  • MVVM架构
    • 待完善

1.3 架构演变过程

  • MVP模式是从MVC模式演变来的
    • 它们的基本思想有相通的地方:Controller/Presenter负责逻辑的处理,Model提供数据,View负责显示,所以他们之间并没有特别大的不同,都是用来将View和Model之间松耦合。
  • MVP与MVC有着一个重大的区别:
    • 在MVP中View并不直接使用Model,它们之间的通信是通过Presenter (MVC中的Controller)来进行的,所有的交互都发生在Presenter内部,而在MVC中是允许Model和View进行交互的。
    • 还有重要的一点就是Presenter与View之间的交互是通过接口的。
  • MVVM是通过MVP演变而来的
    • 主要用了data binding来实现双向交互,这就使得视图和控制层之间的耦合程度进一步降低,关注点分离更为彻底,同时减轻了Activity的压力。

1.4 多种架构对比

  • 关键点总结:
  • MVC
    • Controller是基于行为,并且能够在view之间共享
    • Controller负责接收用户交互等操作,并且决定需要显示的视图。
  • MVP
    • View和Model更加的解耦了,Presenter负责绑定Model到View。
    • 复杂的View可以对应多个Presenter。
    • Presenter保留有View层的事件逻辑,所有的点击之类的事件都直接委托给Presenter。
    • Presenter通过接口直接和View层解耦,所以更加方便的进行View的单元测试。
    • Presenter和其他两层都是双向调用的。
    • MVP有两种实现方式:”Passive View”,View基本包含0逻辑, Presenter作为View和Model的中间人,View和Model相互隔离,View和Model没有直接的数据绑定,取而代之的是View提供相关的setter方法供Persenter去调用,这么做的好处是View和Model干净的分离开了,所以更好的进行相关测试,缺点是需要提供很多的setter方法;”Supervising Controller”,Persenter处理用户交互等的操作,View和Model直接通过数据绑定连接,这种模式下,Persenter的任务就是将实体直接通过Model层传递给View层,这种方法的好处就是代码量少了,但是缺点就是测试难度增大,并且View的封装性变低。
  • MVVM
    • 用户直接交互的是View。
    • View和ViewModel是多对一的关系。
    • View有ViewModel的引用,但是ViewModel没有任何关于View的信息。
    • 支持View和ViewModel的双向数据绑定。

1.4 设计目标

1.5 产生收益分析

02.MVC架构设计

2.1 MVC简单介绍

  • Model View Controller
    • 是软件架构中最常见的一种框架,简单来说就是通过controller的控制去操作model层的数据,并且返回给view层展示。
  • 工作原理
    • 当用户出发事件的时候,view层会发送指令到controller层,接着controller去通知model层更新数据,model层更新完数据以后直接显示在view层上,这就是MVC的工作原理。

2.2 MVC应用场景

  • 视图层(View)
    • 处理界面的显示结果。一般采用XML文件进行界面的描述,这些XML可以理解为AndroidApp的View。使用的时候可以非常方便的引入。同时便于后期界面的修改。逻辑中与界面对应的id不变化则代码不用修改,大大增强了代码的可维护性。
  • 控制层(Controller)
    • 起到桥梁的作用,来控制V层和M层通信以此来达到分离视图显示和业务逻辑层。Android的控制层的重任通常落在了众多的Activity的肩上。这句话也就暗含了不要在Activity中写代码,要通过Activity交割Model业务逻辑层处理,这样做的另外一个原因是Android中的Activity的响应时间是5s,如果耗时的操作放在这里,程序就很容易被回收掉。
  • 模型层(Model)
    • 处理数据,业务逻辑等。针对业务模型,建立的数据结构和相关的类,就可以理解为AndroidApp的Model,Model是与View无关,而与业务相关的。对数据库的操作、对网络等的操作都应该在Model里面处理,当然对业务计算等操作也是必须放在的该层的。
  • MVC三者之间的关系
    • 箭头→代表的是一种事件流向,并不一定要持有对方,比如上图中model→view的事件流向,view可以通过注册监听器的形式得到model发来的事件。在设计中model view controller之间如果要通讯,尽量设计成不直接持有,这样方便复用,也符合mvc的设计初衷。

2.3 通俗理解MVC

  • 当用户触发事件的时候
    • view层会发送指令到controller层,接着controller去通知model层更新数据,model层更新完数据以后直接显示在view层上,这就是MVC的工作原理。
  • 具体到Android上是怎么样一个情况呢?
    • 大家都知道一个Android工程有什么对吧,有java的class文件,有res文件夹,里面是各种资源,还有类似manifest文件等等。对于原生的Android项目来说
    • layout.xml里面的xml文件就对应于MVC的view层,里面都是一些view的布局代码
    • 各种java中bean,还有一些类似repository类就对应于model层
    • 至于controller层嘛,当然就是各种activity咯。
  • 大家可以试着套用我上面说的MVC的工作原理是理解。
    • 比如你的界面有一个按钮,按下这个按钮去网络上下载一个文件,这个按钮是view层的,是使用xml来写的,而那些和网络连接相关的代码写在其他类里,比如你可以写一个专门的networkHelper类,这个就是model层,那怎么连接这两层呢?是通过button.setOnClickListener()这个函数,这个函数就写在了activity中,对应于controller层。是不是很清晰。

2.4 MVC缺陷分析

  • xml作为view层,控制能力实在太弱
    • 你想去动态的改变一个页面的背景,或者动态的隐藏/显示一个按钮,这些都没办法在xml中做,只能把代码写在activity中,造成了activity既是controller层,又是view层的这样一个窘境。
  • view层和model层是相互可知的
    • 这意味着两层之间存在耦合,耦合对于一个大型程序来说是非常致命的,因为这表示开发,测试,维护都需要花大量的精力。
  • Activity并不是一个标准的MVC模式中的Controller
    • 它的首要职责是加载应用的布局和初始化用户界面,并接受并处理来自用户的操作请求,进而作出响应。随着界面及其逻辑的复杂度不断提升,Activity类的职责不断增加,以致变得庞大臃肿。
    • 所以的逻辑都在activity里面。完美的体现了MVC的两大缺点:View对Model的依赖,会导致View也包含了业务逻辑;Controller会变得很厚很复杂。

03.MVP架构设计

3.1 MVP简单介绍

  • MVP作为MVC的演化,解决了MVC不少的缺点
    • 对于Android来说,MVP的model层相对于MVC是一样的,而activity和fragment不再是controller层,而是纯粹的view层,所有关于用户事件的转发全部交由presenter层处理。

3.2 MVP应用场景

  • MVP框架由3部分组成:在MVP模式里通常包含3个要素(加上View interface是4个)
    • View:负责绘制UI元素。与用户进行交互(在Android中体现为Activity)
    • Model:Model提供数据。负责存储、检索、操纵数据(有时也实现一个Model interface用来降低耦合)
    • Presenter:Presenter负责逻辑处理。作为View与Model交互的中间纽带,处理与用户交互的负责逻辑。
    • View interface:需要View实现的接口,View通过View interface与Presenter进行交互,降低耦合,方便进行单元测试
  • 最明显的差别就是view层和model层不再相互可知
    • 完全的解耦,取而代之的presenter层充当了桥梁的作用,用于操作view层发出的事件传递到presenter层中,presenter层去操作model层,并且将数据返回给view层,整个过程中view层和model层完全没有联系。
    • 看到这里大家可能会问,虽然view层和model层解耦了,但是view层和presenter层不是耦合在一起了吗?
    • 其实不是的,对于view层和presenter层的通信,我们是可以通过接口实现的,具体的意思就是说我们的activity,fragment可以去实现实现定义好的接口,而在对应的presenter中通过接口调用方法。
    • 不仅如此,我们还可以编写测试用的View,模拟用户的各种操作,从而实现对Presenter的测试。这就解决了MVC模式中测试,维护难的问题。
  • 其实最好的方式是使用fragment作为view层
    • activity则是用于创建view层(fragment)和presenter层(presenter)的一个控制器。

3.3 MVP常规实践

  • 第一步:首先定义两个Base接口类
    • BaseView与BasePresenter,两类分别是所有View和Presenter的基类。
  • 第二步:定义了契约类(接口)
    • 也就是contract接口类,主要是activity和presenter中起到桥接作用。
    • 使用契约类来统一管理view与presenter的所有的接口,这种方式使得view与presenter中有哪些功能,一目了然,维护起来也很方便。
    • AppContract中的View接口定义了该界面(功能)中所有的UI状态情况,AppActivity作为View层,实现了该接口,如此AppActivity只关注UI相关的状态更新,所有事件操作都调用AppPresenter来完成。
    • Presenter 接口则定义了该界面(功能)中所有的用户操作事件,AppPresenter作为Presenter层,实现了该接口,如此AppPresenter则只关注业务层的逻辑相关,UI的更新只需调用View的状态方法。
    //contract起到桥接的作用
    public interface AppContract {
        interface View extends BaseView {
            void setDataView();
        }
        interface Presenter extends BasePresenter {
            void getData();
        }
    }
  • 第三步:Activity/Fragment在MVP中的作用
    • Activity在项目中是一个全局的控制者,负责创建view以及presenter实例,并将二者联系起来。AppActivity的onCreate()回调中创建并绑定AppPresenter实例,AppPresenter的构造函数中实现了View和Presenter的关联。

3.4 MVP缺陷分析

  • MVP优点:
    • 1,Model与View完全分离,彻底解耦
    • 2,Presenter复用,可以将一个Presenter用于多个视图,而不用改变Presenter的逻辑
    • 3,可以实现View接口进行逻辑测试(Presenter的单元测试)
  • MVP的缺点及优化:
    • 1,View层过大,Activity复杂,加入模板方法,分离出BaseActivity用于处理公共逻辑
    • 2,Model层过大,做好模块划分,进行接口隔离,在内部进行分层。
    • 3,还有一个问题是,MVP额外的增加了很多类和接口,这个可以根据项目实际情况进行相应地优化

3.5 MVP架构演进

04.MVVM架构设计

4.1 MVVM简单介绍

  • 它和MVP的区别貌似不大,只不过是presenter层换成了viewModel层,还有一点就是view层和viewModel层是相互绑定的关系,这意味着当你更新viewModel层的数据的时候,view层会相应的变动ui。

4.2 MVVM应用场景

4.3 MVVM缺陷分析

4.4 MVVM常规实践

4.5 MVVM架构演进

01.什么是MVP?什么是MVC?

  • 什么是MVP?什么是MVC?
    1、什么是MVP?
    M:数据层(数据库、网络、文件存储等等...)
    V:View和Activity和Fragment以及它们的子类
    P:中介->Presenter(作用:将M层数据和UI层进行关联和交互中介)
    
    2、什么是MVC?
    M:单纯Model(Java Bean对象)
    V:View以及子类
    C:Fragment和Activity以及子类

02.开始进行MVP搭建

  • 如何操作,如下所示
    内容一:MVP入门?
    第一步:看一个基本案例?->普通代码实现
    第二步:MVP实现->简单案例->分层次设计
    第三步:MVP实现->优化->优化第1步->方法绑定
    分析问题:因为当我们的Activity关闭的时候,但是网络请求还正在进行,然而我们希望是不要刷新UI了,因为销毁了,解除UI层和数据层关联?
    
    解决方案:方法绑定(绑定、解绑) 
    attachView->绑定
    detachView->解绑
    
    第四步:MVP实现->优化->优化第2步->抽象
    分析问题:现在写一个功能,你觉没什么,但是如果我写了20个类(写了100个类),那么你是不是要绑定(解除绑定)100次?会想死。目的就是为了不需要这么麻烦,统一管理即可(统一绑定)
    解决方案:抽象类(抽象类->抽取)->BasePresenter
    
    第五步:MVP实现->优化->优化第3步->BaseView解决
    分析问题:BasePresenter类型类死了,如果你有很多的模块,那么没发抽象。然而希望动态。
    解决方案:通过BaseView解决。成立
    
    第六步:MVP实现->优化->优化第4步->泛型设计
    分析问题:每一次强制类型转换,想死,一个类还好,100个类,强制类型转换100次。
    解决方案:泛型设计
    
    第七步:MVP实现->优化->优化第5步->抽象类BaseActivity->具体实现
    分析问题:现在有一个Activity你需要绑定,还好,如果我有30个Activity,50个Fragment,怎么办?代码冗余?
    解决方案:抽象类->抽象出绑定和解除绑定
    
    第八步:MVP实现->优化->优化第6步->BaseActivity中抽象->抽象实现(BasePresneter和BaseView)
    分析问题:父类BaseActivity写死了,还是没有满足要求?只能够用LoginPresenter_6,然而我们的目的是能够兼容所有的模块
    解决方案:抽象实现(BasePresneter和BaseView)

03.MVP进阶处理逻辑

  • 如下所示
    第二步:MVP进阶?
    内容二:MVP进阶?
    第九步:MVP实现->优化->优化第8步->Fragment登录功能
    分析问题:对Fragment进行操作(Fragment抽象)
    解决方案:抽象
    
    第十步:MVP实现->优化->优化第9步—>Fragment抽象
    分析问题:对Fragment进行操作(Fragment抽象)
    解决方案:抽象->泛型设计
    
    第十一步:MVP实现->优化->优化第10步->针对LinearLayout、Button集成MVP
    需求:集成->实现登录功能
    
    第十二步:MVP实现->优化->优化第11步->抽象为一个类
    分析问题:每一个模块基类都需要绑定和解除绑定,很多代码冗余。
    解决方案:抽象一下(抽象为一个类)
    
    第十三步:MVP实现->优化->优化第12步
    分析问题:能够满足开发要求?针对Activity做一些处理,生命周期中控制(数据缓存、状态处理)针对Fragment做一些处理,生命周期->MVP框架进行缓存?
    Activity、Fragment、View等等...处理是不一样,然而我们之前的抽象没发满足要求
    解决方案:针对不同模块,针对性的处理->代理模式

04.优化工作介绍

  • 如何优化?
    代理一:
    代理->针对的是->MVP绑定和解绑
    分析角色划分?
    目标接口:绑定和解除绑定回调接口(MvpCallback)
    目标对象:具体实现(ActivityCallbackImpl、FragmentCallbackImpl等等...)->Activity实现->MvpActivity
    分析:创建presenter、创建view等等...
    代理对象:代理实现(MvpCallbackProxy)
    
    代理二:
    代理->针对的是->Activity整体代理->生命周期代理
    
    分析角色划分?
    目标接口:ActivityMvpDelegate
    目标对象:ActivityMvpDelegateImpl
    代理对象:MvpActivity(Activity)
    
    功能实现:
    第一个部分:绑定和解绑->目标对象(生命周期)
    第二个部分:实现MVP绑定和解绑->目标对象(MvpActivity)
    第三步部分:测试

参考案例代码

  • 链接地址:https://github.com/yangchong211
  • 字节一次关于架构的“嘴炮”:https://juejin.cn/post/7078249602410889247
贡献者: yangchong211