本周工作思考
- 课程市场1.4的开发
- 组件和逻辑的封装与拆分
课程1.4的开发过程中,有部分功能需要之前的功能上迭代,有一个问题比较突出,就是业务组件拆分,逻辑封装和隔离的太差,本质上是在开发迭代过程中没有做好关注点隔离,典型的情况是一个业务组件里包含了不少于3个小的业务交互逻辑,产生这种情况的原因我分析主要原因有以下3个:
- 迭代过程中直接在原有组件内填充式的增加新的功能和优化点,导致组件功能膨胀,这种情况常见,而不易发觉,越是迭代久的组件越容易出现这种情况,其直接后果就是组件代码膨胀,难以阅读和维护,功能繁杂,逻辑臃肿,使用成本提升,组件在系统中的价值急剧降低, 这类组件最终通过重构或“打入冷宫永不叙用”的方式,结束在系统中的生命延续。每个组件都是一个小生命,它希望被合理的迭代,每次迭代都要经过合理的设计,而不是每次被填充。
- 组件起初设计不合理,设计不合理是一个表象,其真实因素又有不少,如,需求分析不深入,导致组件划分的时候,赋予组件过重的职责,随着开发深入,内部状态线性增多,而此时工期将近,没法完成设计的纠偏和优化,只能将错就错,导致巨型组件的产生,还有一个情况就是将就,本质上就不追求技术工程上的最优解,只求省事
- 技术能力不足以将组件和逻辑拆分的足够可持续迭代,这种情况是冰山下的,可能没有工程师会承认自己在组件设计上会有大的系统性问题和认知上的问题,这个确实非常难评估,这个有很强的主观性,只有历经几个迭代之后才能证明当初的设计质量到底如何,不过通过一些浅显的信号,我们大概可以判断是否在业务组件迭代时可以进行逻辑拆分,设计纠偏或者组件拆分
- 单个组件多余5个以上的状态判断,这个数字是我个人的判断,复杂业务组件5个状态比较常见,我觉得也是极限,当多于5个就非常不利于后续的理解和迭代,试想你在维护一个组件时,你同时要把握5个状态的各种变化时,其实挺费劲的
- 出现推导状态时,在响应式编程范式里,状态驱动UI,这个状态应该是确保唯一的,且是最原始的,比如某个状态是从其他状态推导出来的,那这个状态就不要放在useState里或者Store里,而应该放在service里,helper里,业务obj里甚至是useEffect里
- 组件里涉及到的UI功能占到了页面里的⅓, 这个也是我的经验值,我认为一个页面至少有3个组件构成,不管这个页面多么的简单,这也是极端情况,当你看到一个组件占到页面的⅓功能时,需要认真考虑下这个页面的组件划分思路了
- 出现5个以上的useEffect,当时一个组件出现5个以上的useEffect,你需要认真考虑两件事,需要拆分自定义hooks,或者直接拆分组件
- 某个组件你认真看了一遍,发现没有看懂,也不知道该如何增加代码,这个时候先不要自责,很可能是组件本身出了问题,因为组件存在的最大价值就是为了让代码好阅读好理解,如果这点没有做到,那就是组件的问题,不是你代码阅读能力问题,后面你需要做的就是多认真读几遍,看看能不能调优下;
- react组件内逻辑拆分的一些思考
- 结合上面想到的,逻辑拆分和封装其实是一个很重要的问题,特别是我们这样的SaaS类的系统,因为它的一个很大的特点是需要长周期性的深耕和打磨业务,很多业务规则是行业内既有的趋于稳定成熟的规则,也有不少是快速变化的创新性规则,我们需要做大量的整合和快速的迭代,这样的特点给研发带来的一个原则就是既要坚持快速迭代交付,又要关注可持续迭代和合理的设计演化,这其实是比较有挑战的事情,也是软件开发领域内长久不衰的研究课题,不过我觉得还是有一些行动可以帮助我们应对这种挑战:
- 多用自定义hooks,这其实是个意识问题,当有这个意识时,在逻辑封装上你会发现很多新玩法,新思路
- 严格区分业务逻辑和UI逻辑,业务逻辑放在service,helper或者业务model类了里,复杂的组件在目录结构上除了典型的tsx,scss,需要增加useHoos文件和组件service文件,将逻辑分类是降低代码复杂度最有效的办法
- 多用方法封装关注点,哪怕只有一行代码,只要就认为它和现有的业务不在一个逻辑层次,就可以放在方法里,方法的作用就是封装,隔离,复用,注释说明,不要担心方法多,很可能你设计这个这个一行代码的方法就是下次迭代的一扇方便之门
- 用好hooks,多总结一些hooks的设计模式,我们对hooks使用还是比较浅,缺乏可自用的hooks工程沉淀,比如,获取数据,比如判断显隐,useCallbac,useMemo的最佳实践等等
- 组件宜小不宜大,从原则上说,组件再小都不为过,这个我想大家都认可,在工程上可能欠缺快速创建组件或者重构组件的工具,影响了大家拆分小颗粒度组件的耐心和效率,不过组件粒度上还是要保持小巧
- 组件和逻辑的封装与拆分