别被你的框架框住了

by Teobler on 19 / 11 / 2021

views

我短暂的职业生涯被 React 充斥着。

还没毕业前我从 Vue 2.x 入手开始学习框架,在一个我当时觉得还行现在回看完全不行的状态进了公司。然后开启了跟 React 死磕的状态,从 class 组件到函数式组件,从 Redux 到 Recoil,从 Antd 到 MUI...

不久前一个呆了2年多的项目成功结束,接下来要去一个新项目,新项目要用 Angular,于是我开始告别从毕业就开始用的 React,开始学习这个大家少有提及的框架。

回顾这几年,要说 React 带给我最多的是什么,我觉得可能是思想,是一种编程范式。为了理解 React 新的函数式组件,我去学习 FP,但我并不是一个原教旨主义者,所以我当然也不认同你想学 FP 就得去学 Lisp 的说法。

在这期间我发现小黄书的作者 Kyle Simpson 也写了一本专门为 JSer 介绍 FP 的,书中前言部分我深以为然:

The way I see it, functional programming is at its heart about using patterns in your code that are well-known, understandable, and proven to keep away the mistakes that make code harder to understand.

是的,编程范式的作用是为了让人们更好地组织和理解代码,编程范式应该去服务写代码的人,而不是人去事无巨细地遵循编程范式的每一个规则,理解每一个晦涩难懂的概念。

I believe that programming is fundamentally about humans, not about code. I believe that code is first and foremost a means of human communication, and only as a side effect (hear my self-referential chuckle) does it instruct the computer.

敏捷需要以人为本,写代码其实也一样。我们要做的应该是理解编程范式本身以及它背后的作用,或许在未来的某天你会突然发现,原来我用了这么久的这个玩意儿有一个这么有意思的名字,亦或者你可能永远也解释不清楚那个概念到底是什么:

A monad is just a monoid in the category of endofunctors.

一个单子不过是自函子范畴上的幺半群

那是不是搞不懂我就不能玩 FP 了?然后我就得站在鄙视链底端,被 Haskell、Lisp 玩家们指着鼻子嘲笑:你们看那家伙,其实啥也不懂,他那也叫 FP?

这个问题我没有答案,或许可以留给大家来讨论。但是到这里我至少明白了 React Hooks 为什么要叫 "hook";为什么有一个 hook 叫 "useEffect";我也理解了为什么大家都说不要用 hook 去实现 class 组件的生命周期。

除了写好 React 本身,我也尝试了纯函数、偏函数、柯里化、组合和 Point-free 风格的代码,确实得到了一些好处,也确实带来了一些不便。

可能这些思想就是学习 React 带给我最大的 side effect 吧(笑。

与 React 准备 all in FP 相反的是,与 Angular 短暂接触的我发现它全面拥抱 OOP。与当时 React 从 class 组件切换到函数式组件一样,首先你得把编程范式思想完全转变过来才能很好地理解 Angular。这又促使我不得不去复习许多被我丢弃很久的 OOP 思想。

到这我不禁想起一次公司内 TDD 训练营,作业完成后去找 coach 讲解,讲解过程中 coach 讲到了抽象能力、隔离层、防腐层。那时我才发现自己 OO 的抽象能力和一起的后端小伙伴一比实在是差到不行,只有大学时候的能力。反思过后像是被 React 给“惯”坏了,几乎已经丢掉了这部分能力。

老实说我接触 React class 组件时间并不长,第一个项目只有短短几个月。后面两个项目虽然去写 Java 了,但是第一个都是一些修修补补的工作,更像是在做 DevOps,后来的项目去写 Java BFF,毫无抽象可言,全是数据 mapping。然后又进到了一个将“追求技术卓越”贯彻执行的项目,成了那批最早吃函数式组件螃蟹的人。

于是我接触 class 组件的时间就只有作为毕业生的那短短几个月而已。

然后当我看到 Angular 文档中的依赖注入时,我脑子只能零星蹦出一些概念:SOLID、解耦。别说细节,我甚至不知道我蹦出来的这些东西是不是对的。于是我又只能凭着自己的记忆去邮件里搜相关的博客大赛的文章。

我好像已经丢掉了 OOP 了。

种下一棵树最好的时间是十年前,其次是现在。

跳出all in FP 的 React 我发现世界不是非黑即白的。说是全面拥抱 OOP,但其实你可以很轻易的在 Angular 中发现 FP 的影子 -- 用 pipe 来处理数据,用 Rx 来处理请求。

既然是以人为本,编程范式本就不应该对立,它们明明可以互补,在自己擅长的领域处理自己擅长的事情,哪怕是同一个项目。看惯了两个阵营吵架的场景,好像这样的场景才是我想要的。

于是我又回忆起某天在项目上和大家讨论的项目分包问题,最后的结论是 OOP 的以对象和 domain 分包的策略在大多数时候要优于单纯的 FP 的方式。它能让功能更集中,让大家更容易找到自己想要找的东西。

但是回过头来静静思考,我虽然会好好学习 OOP,但是我目前大概率不会去深入学习相关的建模方法。因为在目前我的工作环境下,我没看到有前端同学需要深刻理解建模方法的场景,大多数情况浅尝辄止即可。

以我自身的经历来看,DDD 我看过也参加过培训,也跟着项目后端小伙伴在搭建项目时从零到一实践过。但是在实践不多的情况下,整个过程逃脱不了学了忘忘了学的魔咒。大概唯一的用处就是当我被抓到后端去干活能看懂他们为什么要这么组织代码,至于建模的那个过程,被抓去干活的我是大概率不会参与的。(当然如果你有相关的经历还请喷醒我,比如你作为偏前端的小伙伴就是要熟练掌握建模方法,不然工作就做不下去了)

不要被技术栈限制住了自己,其实以前一直对这句话一知半解,虽然可能现在的理解也没有很强。可是当你从一个框里跳出来以后,去思考画框这个人的想法,你可能能够得到一些不一样的思考。对于 Thoughtworker 来说学习一个新框架,一门新语言可能不是什么问题,那我们是不是可以更进一步,想想那些看起来“虚无缥缈”的东西呢。

别被你的框架框住你了。