大型项目数据状态管理摸索

讲一个悲伤的故事

本来这篇文章应该是上周写完的。

故事发生在一周前,我在segmentfault在线编辑文章,写了差不多两个小时,在贴了一张图片失败之后,然后ctrl+z撤销了一步,结果整个文档被瞬间清空了,编辑器还自动保存了清空态。

这一刻,有点心凉,仿佛突然被浇了一桶冷水。

第一时间,打开浏览器控制台,去翻缓存,结果localStorage里面空空如也,当时就感觉希望不大了,幻想着他们服务端能保存某个时刻的记录。

微信联系了他们的客服小姐姐,晚饭后回复我:“技术人员下班了,明天帮忙查看,问我急不急?”。还能怎样?开发何必为难开发,当时就放过了她。

第二天,经过他们一番追踪,服务端没有任何记录......

结局就是现在这样,我再重新写一遍。

通过这个事件,也可以看出,segmentfault的数据状态管理机制还是有缺陷的,容错机制不太好,至少缓存机制不太行,共勉!

概述

有个头痛的问题,什么是爱情?

噢噢,状态错乱了,“状态混乱”就这个头痛的问题。

随着前端应用的规模越来越庞大,业务复杂度直线拉升。状态管理也成为了重中之重,DDD领域驱动模型也逐渐盛行。

随着项目发展,单元测试也变成了很重要的一个环节,随着业务逻辑复杂度的增加,问题关注点直接爆炸,人力心智负担越来越高。

所以不管是 为了更好地开发模型 还是 更容易的单元测试,如何更好地管理数据状态都 成了一个 核心环节。

比如,领域状态 要和 UI状态分离;依照DDD领域驱动模型构建 数据Store,而不是依据UI来构建。

状态数据构建 是 全局的还是 局部的,衍生数据 如何自动生成,副作用变更逻辑如何书写?

数据逻辑 如何 和 UI视图 解耦,又如何方便注入UI使用,怎样进行方便的通信?

社区有那么多套 所谓成熟的解决方案,我们到底改用那套?

项目问题

回归现实,聚焦到目前业务项目上。一个三年左右的项目了,技术栈是非常常规的React框架搭建,初期是使用Redux做的的状态管理;后来React发布了Hook特性,看代码记录,大家果断抛弃了Redux,拥抱Hook,项目从某个节点开始,成了清一色的Function式。

好了,现在随便找个项目开发者咨询一下,项目存在什么技术问题,开发体验如何?瞬间就能开启吐槽模式:

  • 状态 凌乱 ,没有 领域状态 UI状态区分
  • 全局状态 和 局部状态 设计不合理
  • 数据流逻辑处理 耦合 UI视图 (CodeReview难,bug不好追踪,单元测试困难)
  • props drilling 而且传递过程 命名多变
  • props 传递粒度 不够精细 (渲染频率增加)
  • hook使用方式 近乎demo方式,极其不合理,无抽离,无封装
  • Redux 样板代码较多;使用繁琐;
  • 性能产生了问题,频繁渲染,无法追踪什么操作 导致变更
  • 开发方式 对人的要求较高,心智负担较高
  • 看起来做了一系列性能优化,还不如vue不优化
  • ......不一一列举了

那有解决方案吗?有,大家拉个会议一讨论,指定编码开发规范,严格CodeReview,该优化的优化。
OK,问题解决了吗?没有,一段时间过后,代码风格统一了,可是这个真的不重要,问题还是那些问题,旧的代码能不动就不动,新代码就直接往上堆砌。

代码风格统一了,eslint跑过了,可是相比系统架构而言,这些流于形式的东西权重就很低了,重要性微乎其微。

如果不做演化改进,熵增继续,系统势必走向崩溃。

这个时候,我们必须思考,出现问题的本质原因到底是什么?
是历史遗留问题吗,是技术栈问题吗?
都不是,思前想后,还是人的问题,开发者自身的问题。

过度的自由必然导致混乱。

React设计理念 和 哲学思考都是很高的,本身是为了解决UI渲染问题;这就像一把神器,境界高的使用者如臂使指,用来所向披靡,事半功倍;境界不及者,就会感觉深陷泥潭,拿不起来挥不动,终被反噬。

屠龙少年终成恶龙!

大型项目数据状态管理摸索_第1张图片
一个没什么开发经验,设计模式也不懂,框架立意也不清晰,读了几个api用来写项目的人,怎么能掌控好呢?
React可能连开发多年的老鸟都不一定能玩明白,上手难度高也不是空穴来风啊,大家可能只是习惯无脑的知道大家这么说,哦,那就上手难度高。
可是为什么上手难度高,到底难点在哪里?照着api开发,难吗,一点也不对吧

Vue技术栈为什么就没有这些问题?为什么很少出现性能问题?
尤雨溪尤大 设计框架的时候,面向的使用群体是那些人?框架里帮我们解决了什么问题?

所以,本质原因是什么,这里就很明白了,但是对于”人“,非常难以掌控。

我们不可能招到的开发者都是非常完美合格的,另一方面,人进步是很困难的,成长曲线都是漫长的S曲线。

那到底有么有一种方案能 降低人的因素,防止人 对系统架构造成侵蚀和破坏呢?下面我们分析一下

各种解决方案

vue全家桶

vue的响应式设计模式,粒度非常精细,而且 依赖收集 和 依赖派发 逻辑全都有框架自动完成。开发者专注于业务逻辑即可,什么时候渲染,渲染频率控制 框架都帮我们处理好了。
单文件模式,把js ,css,html集合在一起的组织方式,本身也是一种功能解耦.

vuex专门为vue框架设计的状态管理库,无缝接入。

整体来说,开发体验还是非常好的,受众群体非常庞大,尤其对于初中级开发者来说,根本没有心智负担。

既然框架为我们考虑了大部分功能,随着失去的就是 自定义的灵活性和扩展性,这可能是制约顶级大佬们发挥自我的一个制约点,但是我们不能人云亦云,做拿来主义。对于绝大多数开发者来讲,还远远达不到触发这个制约点的高度。

关于vue技术栈相关的讲解,这里就不展开说明了,网上有一大堆分析资料。

react (hook) + redux

React本身只是一个 构建用户界面的javascript库,官方也是这么说明的。它的核心两点是 虚拟dom以及非常高效的diff算法,这才是它的底层竞争优势。Vue后期的迭代优化也有相关参考,比如引入了虚拟dom机制。

初期全局状态管理,官方推出了Redux,纯函数式编程,功能扩展通过中间件模式。
正如大家烦躁的一点,使用redux,需要大量的模板代码,使用非常繁琐;还引入了其他各种概念,比如connect高阶组件,容器组件等概念;总之就是使用繁琐,样板代码庞大。

正是上述缺点,所以Hook推出之后,大家弹冠相庆,马上抛弃redux模式。然后hook依然需要很高的理解成本,甚至比Redux要求更高。但是大家可能不假思索的照着api就开始开发了,导致清一色的Function产生,内部堆积了大量的state,effect,函数体急剧膨胀。hook的状态设计分层 更是乱七八糟。props传递混乱。

讲道理,Redux 和 Hook本身都是很好的,大家说起来可能觉得自己都懂,然而落到实处,生产出来的代码却远远不够水准。说到底,还是没懂相关技术的核心设计理念,以及想要解决的问题,思维高度不足导致滥用。

那有没有想使用 React来构建UI,又想拥有vue的开发体验呢?答案是肯定的,那就是React + mobx

react + mobx

核心理念:回归初心,各自解决各自的问题,React专注于构建用户界面UI,mobx专注于数据逻辑管理,尘归尘,土归土。

使用方式请参考

咋一看,react + mobx不就是 繁琐版的vue吗?没毛病,看起来确实是这样,但又不止于此。

我们用mobx来设计 数据Store以及衍生数据和副作用action的变更,用React构建用户界面。最明显的一点就是 mobx接管了 React组件的渲染逻辑,把开发者从 渲染的问题上 解放了出来,降低了心智负担。

数据逻辑内敛到 mobx里,自然实现了 数据状态逻辑 和 UI的解耦;也方便各自进行单元测试。

mobx不同于Redux,而是可以多Store实例存在,非常灵活,同时也解决了 数据props传递和 组件通信的问题。

在这种模式下开发,那怕一个没有经验的开发者随便开发,也不会对系统的架构造成侵蚀和破坏。

最佳实践

到了这里,差不多该有个结论了。

还是那句话,没有银弹,也没有屠龙刀,没有放之四海而皆准的解决方案。

如果你是个新手开发者,各种设计模式和框架理念理解不是很透彻,又想快速构建应用,那么vue全家桶可能很适合你上手。

如果你开发经验非常丰富,做很多底层抽象封装的工作,需要高度复用定制一些能力,需要专业,那么React技术栈可能比较适合你,因为你很强。

如果你喜欢使用React,然而又想拥有Vue的开发体验,那么React + mobx将非常适合你,你值得拥有。

总结

这篇碎碎念写的比较多,深度也欠缺,尤其后面很多技术细节,直接没有;不过无所谓了,这篇也不是讲解技术使用的,就是吐吐槽,产生一些想法。

有关技术深度使用的话题,后续有时间再聊!

你可能感兴趣的:(大型项目数据状态管理摸索)