73

前后端分裂 - Rei

 6 years ago
source link: http://chloerei.com/2018/01/07/front-end-split/?
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

前后端分裂

Rei 写于 07 Jan 2018

让我先讲一个真实故事。

有一天,我接到一个业务需求,给某个表单的下拉框增加一个选项。比较特别的是,这是一个前后端分离的项目,分离得非常彻底——维护前端的人甚至不跟我在同一个项目组,前端页面独立开发独立部署,我能够修改的只有 API,并且前端页面不会把内容直接提交到后端,而是经过一层 node.js 中转……

我试图搞明白这个表单怎么工作,发现当初设计这个表单的人非常“聪明”,已经预料到下拉框内容要改动的情况了,所以这个下拉框内容是动态的,根据后端另一个 API 的输出来渲染。那么看起来我只要修改这个 API 的输出,前端就能自动更新下拉框内容。于是我找到前端同事确认是不是能这么改,得到答复是:

“不行,前端这边加了缓存,你如果更改了 API 输出,需要通知我刷新缓存。”

好吧,为了性能考虑,加缓存是非常正确的选择。那么接下来我想先在测试环境修改联调一下,不要影响生产环境。这时候我才发现,测试环境是坏的!于是我又开始修测试环境。联调过程有点像乒乓球,我改一点东西,让前端刷新,然后发个请求测一下,如果有问题,再重复这个流程。

猜猜我完成这个需求花了多少时间?前前后后一共花了……3 天!这里面还有一个原因是前端同事并不是 100% 投入这个项目,有很多时间我都在等待他空出时间处理,而等待时间我也可以处理别的问题。但是,WTF 我居然改一个下拉框用了三天时间,这正常么?

从这故事可以得到的教训有:

  1. 不要把核心业务功能交给项目外的人负责。
  2. 不正确的分离会大大降低开发效率。

这篇博客主要想讲第二点。

现在对前后端分离的追捧已经到了狂热的程度。虽然“现代前端”拥护者会告诉你,什么样的场景用什么样的工具,前端框架是为复杂场景考虑的,并且给你展示一个复杂的、很适合用前端框架的场景。但是当你要编写一个简单应用的时候,这些拥护者这又会告诉你最好选用 Blabla 框架,因为这是市场“主流”,开发者众多,而你的应用总有一天会变得复杂的。

如果只是一昧鼓吹什么是主流和现代还不至于有很多人上当,真正戳中技术管理者痛点的地方是分工。当我们要处理一个很庞大的问题,以至于一个人、一个团队不能掌控的时候,自然会想到将系统拆解为几个模块进行分工。但问题是,前后端分离分错了方向。

人们很容易认为前后端是个不同的领域,因为一个在浏览器执行,一个在服务器执行,它们不是两个东西吗?

这是不对的,前端和后端都属于 Web 应用的一部分,不能脱离对方存在,前端代码需要通过后端发送。对于大多数内容型网站,如官网、电商、视频等等,为了 SEO,需要后端渲染。为了性能,需要后端缓存。为了安全,需要通盘考虑浏览器的安全机制,包括 CSRF、CROS、CSP 等。前后端分离的项目,都会由前端维护一个 node.js 中间层,就是证明了这一点。如果拍脑袋前后端分离,不协调就会出现在开发、测试、部署,功能开发的整个生命周期。

如果认为前后端分离可以增加并行投入的人力,从而加快开发进度,很遗憾,根据我的观察并不能达到这个目的。我曾经目睹一个功能用前后端分离的方案,轻易估算出了 150 人天的工作量,并且这又是合理的。前后端分离的项目一开始就要基于远程调用进行设计,而这是一般软件设计中极力避免的。开发过程中有很多逻辑是重复开发,前端实现一次,后端也实现一次,然后还要考虑远程调用的错误处理。最后,测试联调的时候也会出现大量问题。这个项目如果用传统集成式的方式开发,根据我的经验应该在 50 人天左右的工作量。

最后,还有一种观点是认为开发者是可以轻易替代的,并且职责分得越细,越容易替代。所以前后端分离描绘出一种梦幻情景:前端和后端只处理一部分,任何成员离开都可以轻易补上。事实上,分离后的项目变得更难理解了,前端不知道后端的处理,后端不知道前端的实现。调用关系越简单,层级越少,才会越容易理解。

正确的分割方法是按功能划分,一个人员负责某个功能的整个流程,前至用户如何填写表单,后至数据如何写入数据库和执行后台任务。如果单个项目过于巨大,就把一些业务独立的功能提取成项目。(很容易想到 Microservice,但这又做过头了,具体看 Martin Fowler 的 MonolithFirst,不在这里展开)

“现代”前端已经成功把自己逼迫到非常窘迫的地步:前端框架层出不穷,曾经大热的 Angular 已经边缘化;为了处理请求不得不引入 Node.js Server,但是很谨慎将自己称为全栈,而是叫做“中间层”,因为前不久才用“全栈就是坏”的口号带歪了不少全栈程序员;为了 SEO 不得不引入服务端渲染,但又不能走传统模版渲染的老路,发展出来同构——把前端框架放到后端渲染,开发难度指数上升。

isomorphic-javascript.png

我已经听到有前端开发说不想碰 Node.js Server 了,他们想专注于处理交互(这也是前端职位的本意)。后端开发一开始很乐意把工作分出去,觉得工作量少了,实际开发才发现一点没少,以前一个变量传递就能完成的事情,现在要写一个 API。需求没完成,没有人会是轻松的。

现在这个境地,与其说是前后端分离,不如说是前后端分裂。大家都觉得不对,但是沟壑已经很深。一旦分开,融合就不是容易的事。

那怎么办……

出路其实每个人都看见过,但有的人选择视而不见,因为这会让人怀疑这几年是不是浪费掉了。

回想一下前后端分离被炒热之前的那个时代,我们是这样做 Web 应用:以服务端渲染为基础,加上少量 JavaScript 交互,对于特别复杂的组件使用前端框架,这就已经满足绝大部分 Web 应用的需求。

part.svg

这个方案的问题是,不像前后端分离那样有浏览器/服务器这么明显的界限,没有一个简单标准判断哪一部分应该占多少比例,这取决于场景。另一个问题是,优秀的全栈工程师是稀缺品,培养起来需要时间。这就让人犯难了,一不小心就会掉入分离的陷阱。但是,能正确划分系统的人更是稀缺品……

现在是全栈开发备受质疑的日子,分离方案占据了制高点。但是技术潮流就像钟摆,说不定过两年又会摆回来。不要一直追着热点,而是要看清自己的需求。

软件开发没有银弹。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK