objc app架构阅读笔记

说实话这本书买了这么久,我都没有好好花时间看完和总结过,所以新冠阳性以后,我决定坚持把它看完,不再留下什么遗憾。这里记录一些看完后的想法和感想,主要总结了以下几个架构:

  • MVC
  • MVVM+C
  • 网络
  • MVC+VS
  • MAVB
  • Elm (TEA)

官方源码下载 https://github.com/objcio/app-architecture

MVC

Model-View-Controller是最常见的架构模式,Model负责数据(更新发通知),View负责视图(事件回调走代理),Controller作为桥梁负责衔接Model和View的交互和交流。

我觉得印象深刻的地方在于,作者即使在MVC的案例中依然保持使用单向数据流,比如删除列表中的文件目录代码实现,只更新了Model的删除,然后通过发送通知的方式来更新列表。这让我觉得在项目中使用一致的数据交互约定进行开发尤为重要,这样即使选择了结构松散和自由度高的MVC架构来开发程序,也能提升代码管理和可读性。这点在我看来是值得学习的精髓。

优点:

  • 架构简单,自由度高,苹果认证
  • 适合快速上手,开发阻力低

缺点:

  • 逻辑耦合程度高,状态越多,越容易出bugs
  • 项目逻辑逐渐复杂时,会变成Massive-View-Controller
  • 没有严谨的观察者模式,通知和代理容易被滥用
  • 不适合单元测试

适用场景:

  • 快速迭代,原型开发,需求灵活扩展

MVVM+C

Model-View-ViewModel跟MVC类似,只是ViewModel接替了Controller的工作,由于不同视图相关逻辑被分散至不同的ViewModel中,这样就减少了Controller的负担,使其不再复杂和臃肿。另外还有一个协调器Coordinator负责controller之间的跳转,这种架构使得vc和view、vc之间减少耦合。除此之外,MVVM的最大价值在于引入响应式编程(比如RxSwift),响应式的好处在于让数据流变得清晰可控,你可以通过建立ViewModel和View的绑定关系清楚地看到数据来源和数据转换,从而避免了其他太多选择造成的混乱。

优点:

  • 缓解MVC中Controller过于复杂的问题
  • 适合响应式编程
  • 方便接口测试

缺点:

  • 响应式框架学习曲线陡峭

使用场景:

  • 业务复杂,MVC开始膨胀的时候

MVVM去Rx版

如果在项目中使用MVVM,但是又觉得引入Rx框架负担太重,也可以选择轻量化的响应式框架或者自己实现。比如KVO或者封装一下Notification,做到既可以实现订阅,又不至于滥用的程度。当然我认为响应式本质是一种数据交互的方式,即使不用框架,也可以自己约定,而框架的用处就是用统一的方式严格去执行这种约定,这就意味着从代码层面可以避免逻辑混乱不清的情况。

网络

关于网络章节部分,主要是讨论网络请求逻辑放在Controller层还是Model层。

网络逻辑放在Controller层是很常见的,加载页面时网络请求数据,删除数据时等待网络请求返回成功后再删除本地数据并刷新UI,这些都是响应网络优先的流程。

网络逻辑在Model层的话,除了让Controller减负以外,还有个原因我理解是弱化网络的存在感。网络在Model层的作用只是用来同步数据而已,这与上面的区别在于:

  • Model可以先从本地缓存中获取,而不用等待网络回调
  • 网络服务类可以注册本地Model变更的通知,维护一个队列来把变更操作依次入队并同步给服务端
  • 离线模式下也允许本地修改Model,等有网络的时候再同步给云端
  • 网络更新了Model数据,也会通过Model发送变更通知给订阅者来,保持数据流交互一致

看了网络部分的架构,我觉得是在强调两种理念:云端优先还是本地优先。而作者的观点是,两种架构的不同取决于希望谁拥有数据,Controller还是Model,而谁拥有的关键在于该数据是否希望被共享。

MVC+VS

全称Model-View-Controll + ViewState,特点在于单向数据流和ViewState(书里例子是ViewStateStore,我这里简称VS),它不仅仅是记录view状态的对象,而是扩展成了记录app状态处理逻辑的全局对象,比如app进入到哪个页面,用户执行的播放、删除或保存操作,都会由VS来管理。相对于MVC来说,我觉得这种架构更像是“集权式管理”,虽然每个vc都有自己的model,但是数据变更和流向都是严格上报全局的VS(其实是更新了每个vc自己专属的ViewState),然后再下发通知来更新UI。

优点:

  • 单向数据流:相对于MVC,数据的改动不会直接导致vc来更新view,而是借由更新ViewState,通过订阅的方式来从ViewState收到变更通知来更新view。无论是用户触发view的操作,还是网络请求的model更新,都会通过更新ViewState来通知变更,数据流向统一且清晰。
  • 订阅:数据的更新是通过订阅ViewState来得到的
  • 时光机:因为VS是个全局的状态集,这就意味着每次改动都可以保存一份快照,相当于时光机一样,你可以让app回退到之前某个时刻的状态。
  • 调试:相比于时光机,更加实际的应用是调试,因为在当下就可以输出app此时的状态集,甚至历史状态。
  • 测试:因为分层和数据流都相对严谨,所以测试方面大多集中在VS,应该比较省心
  • 状态恢复:恢复了全局VS相当于恢复了app的所有状态
  • vc间通信:由全局VS定义所有跳转action,再由订阅了跳转事件的对象来创建加载vc

缺点:

  • 对于体量大、逻辑复杂的app来说,全局的VS应该会过于庞大和繁重,可能需要拆分和调整,或者更换其他架构(个人观点)
  • 每个vc的创建都需要全局的VS,耦合性其实挺高的(书里把VS封装成context,作为参数传递给每个vc,也提到可以直接访问单例对象)
  • 对于需求多变、快速迭代的要求下,没有MVC灵活。

适用场景:

  • 需要状态集中管理的场景
  • 数据流动严格统一的场景
  • App版Time Machine
  • 在任意时刻打断点,都能调试看到app任何vc当下的状态
  • 即使不适合用在管理全局状态的话,应该也可以作为app中某项功能的全局状态管理(虽然目前没有尝试过),用混合的方式来搭配其他架构开发app也许会更加灵活

MAVB

ModelAdapter-ViewBinder,其中ModelAdapter体现的是响应式编程,把model数据流转换成信号来输入输出;而ViewBinder体现的是声明+响应式编程,用声明式代码创建布局,然后绑定数据信号。MAVB架构的特点是没有Controller,直接建立Model和View之间的关联,看上去相对轻量一些。

书里的例子用了CwlViews库作为MAVB技术支持,代码风格很极简,我一眼看去感觉很像SwiftUI+Combine的结合。令我印象深刻的是,创建View的时候即绑定数据源的风格,强制让你放弃命令式的思维,这样就避免了在工程里到处维护状态更新,理论上是可以避免程序里绝大部分的bugs。另外CwlViews响应式数据流符号也很直观,也不需要像RxSwift声明DisposeBag来管理生命周期。数据流传递的部分既是重点,也相对复杂,连切换一个播放按钮或者列表里删除某个条目都要围着View->ViewBinder->ModelAdapter->Model->ModelAdapter->ViewBinder->View绕一整圈,不过这也体现了数据流单向和统一的特点。

优点:

  • 精简的声明式语法
  • 单一数据流
  • 支持与MVC混用

缺点:

  • 学习曲线陡峭
  • 团队维护成本高
  • 调试难

适用场景:

  • CwlViews不是用来写生产代码的,但是学习CwlViews也许可以更好的帮助我们了解MAVB的理念。
  • 对于在项目中使用响应式的话,还是得使用现有的响应式框架,比如ReactiveCocoa, RxSwift, Combine等等。

Elm

The Elm Architecture也简称是TEA,我觉得可以用一句话来描述它:消息-更新-渲染。App在任何地方的任何状态发生变化,其整个状态和model数据将会被传递到一个函数中,他会构建一个新的、不可变的虚拟View层级。框架本身的核心是Driver,通过把虚拟View层级的描述来渲染出实际的UIKit视图,同时也把UIKit事件转化成消息,发送给driver的update函数;框架还把例如弹窗和网络请求等事件封装成了Command对象,给予外部使用。Elm就像一个桥梁一样位于AppState和UIKit之间,你无需接触系统API,而是更新AppState,然后框架会根据app状态来构建虚拟视图层级,再去调用系统API来渲染或创建实际的视图。

与MAVB相比,Elm给我感觉更接近SwiftUI,比如虚拟View的构建更像是ViewBuilder,视图的构建是根据虚拟视图的描述来生成的;而MAVB更加强调的是视图与数据之间的关系,即创建视图的时候就需要定义好数据的流向,从哪里来或到哪里去,充分体现了响应式思想。

优点:

  • 声明式构建UI
  • 在前端已得到验证
  • 减少状态bugs

缺点:

  • 对框架封装要求高

适用场景:

  • 直接用SwiftUI吧

总结

我看完了整本书,也还没有打算尝试用新架构来重新写点什么,所以暂时无法对它们有深层次的认识。我目前的工作也只是接触过MVC和MVVM,连响应式也很少见到在项目中投入使用。一方面是因为苹果本身推荐MVC,而且对于互联网公司来讲,敏捷开发和快速迭代是符合前期产品发展趋势的,这就无疑在不断巩固着MVC的地位。而学习了其他架构,我发现确实可以开阔视野、增加见识,比如MVC+VS可以创造出时光机的概念,MAVB的数据流向可以如此简洁和优雅,Elm也让我对SwiftUI的实现有了好奇。我觉得书里的某些看法值得提倡,就是这些架构只是工具利器,实际项目中其实很难用单一架构来解决问题,所以其实也可以混合架构,重点在于学习思想和理念,学会分清Model和View,学会用新的思路来解决问题,知道什么场景适合什么架构,而不是无脑完成需求后又得面对数不完的bugs。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值