目录介绍
- 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