背景
对于我们日常工作来说,写代码可能占去了大部分时间,但当我们回头看以前代码的时候,我们往往会觉得以前自己写的很糟糕。
或者在向前看看资历比较老的同事,往往都可以写出比较清晰的代码,有一种莫名的优雅。
也许通过时间的历练,在几年之后自己也可以达到对方的水平,但是这个时间太久。
可不可以总结出一些可以复制的方法、套路,让新人也能尽早写出一套漂亮的代码?
本篇文章就是针对前端的研发情况,讨论这些方法、套路的。
现状
我们往往都会陷入这样一种循环,在拿到需求文档时候,我们会大致看一下,感觉开发上没有什么太大的问题,然后就看看交互、UI 稿上有哪些页面,接下来就开始着手写了。
在写代码的过程中,我们也许会发现有些实现不合理的地方,这时我们会稍微动一下我们的大脑,然后抽象一下流程和模块,重构一下部分代码。遇到简单点的情况,我们发现加个参数传过去做一下判断也能实现,于是我们也就这么做了。
开发完后,我们会觉得比较满足,代码在脑中的逻辑比较清晰,里面也许有些地方写的不太妥当,但是也无妨吧。
然后项目就开始测试了,QA 会针对各种边界问题给我们提 bug,在改 bug 的过程中我们痛苦不堪,之前的代码逻辑变得支离破碎,我们不得不为了各种 bug 去为代码修修补补,方法的参数加了一个又一个,逻辑里的条件判断加了又加。往往到这个时候,我们开始对 QA 提出的 bug 表示质疑,我们会用“现在的表现是符合逻辑的”,“这种情况没问题”等等这样的说辞来避免对代码的更改。
过去几个月之后,我们接到一个需求,要对这部分代码增加几个新功能,翻开代码的时候,整个人都崩溃了。以前代码的逻辑自己早就忘记了,面对自己已经看不懂的代码,我们会问“这个方法什么意思?为什么逻辑这么复杂?”,“代码在不同页面之间跳来跳去,他们的逻辑到底是什么样的?”,“为什么会有这么多标识位,他们都是干嘛的?”。注释什么的是不存在的,即使存在,也不明白在讲些什么。
在经历过阅读源码的痛苦过程之后,我们看了看排期,嗯。。。还有 30% 的 buffer,于是我们决定把这部分代码重写掉,然后再重复这个痛苦的循坏。
那么我们应该如何从这个循环里跳出来呢?
对比
我们相比一下后端,会发现他们在写代码之前都会做方案设计。方案设计是软件工程里的一个最佳实践,通常做技术方案的过程中会体现出软件整体的架构,当对核心流程梳理完成之后,最后基本都能落实到代码上。也就是说好的技术方案能体现出最后代码的逻辑,通过看方案就能知道代码怎么写。这样就防止了在写代码过程中边写边改,最后导致代码结构混乱的问题。
但是我们尝试按照后端的方法来做方案设计发现根本写不出来什么内容:
- 后端的流程图是系统间交互的流程,而我们大都数场景下只需要和一个后端交互
- 后端需要列举出来数据库表结构,而我们都是把数据丢给后端
- 后端有业务模型,而对我们来说,从后端拿数据就行了
- 后端有核心业务流程,而我们调用他们 API 就行了
从上面我们可以看出,前端只运行在浏览器里,业务上只和后端有交互,而且 API 都是后端定好的,所以按照后端方案设计的套路,前端是写不出来什么东西的。
所以我们会发现,我们大多数设计文档都是偏 Node 层的东西,因为我们往往都是按照后端设计方案的模式去做的,但是浏览器内部运行的代码却没有文档去描述。
分析
这时候我们要重新审视方案设计的套路,来发现前后端的不同:
- 业务分析
- 业务模型
- 核心流程
- 逻辑架构、类图、部署图
- 接口
- 实施方案
- 风险控制
业务分析与业务模型可能前后端都是一致的,毕竟我们是解决同一个业务问题。但其中也有稍许差别,前端有些数据不是从后端获取的,或者说不一定非要从后端获取,这点我们需要在做设计的时候考虑进去,比如同样是获取地理位置,我们可以通过 GPS 也可以通过访问后端服务通过 IP 地址来判断,google 甚至有通过 WIFI 唯一识别码来定位的。
前后端对于「核心流程」的定义也不同,对于后端来说核心流程是数据的产生、流转、消费,但是提到流程,在前端来说更多的是页面的流转、组件的交互。同样一件事情,在前后端来看完全是两个东西,比如保存一项数据,后端需要关注的可能是如何校验,如何存储,如何索引,如何关联。但前端要关注的却是校验结果的展现形式如何,生成一个结构化数据需要调用多少页面,这些页面在不同的屏幕下面如何展现,是跳转还是覆盖或者弹窗。
后端其实更注重逻辑架构与部署图,因为后端需要为服务化,服务间边界的定义要非常清晰、具体,对于一个服务内的代码后端有 Spring 等明确的框架去规范如何写。前端与微服务对应的,应该就是组件 了,但是组件覆盖的范围太广,从一个按钮到一个页面都可以称之为组件,所以前端的组件需要被划分成模块、控件等不同封装水平的单位。在这个划分的过程中,逻辑架构和类图就自然体现出来了。同时前后端解决的问题不同,导致关注点也不同,前端需要关注页面的还原,比如页面的元素应该如何抽象,样式应该如何复用,这个是后端不用考虑的。
后端需要关注暴露出去的 thrift 或者 http 接口,因为这体现了系统间交互的逻辑。而对于前端来说对应的也应该明确独立模块或者页面之间的交互逻辑,所以也就需要明确这些接口。
关于实施方案和风险控制,各方的关注点也有稍许不同,后端更关心系统之间的集成,旧数据的兼容。而前端应该关心的是和移动 Native 的集成,或者微信、支付宝的集成,如果是桌面 web 的话就该考虑 iframe 集成的场景。
结论
作为软件工程的最佳实现,方案设计在前端开发过程中还是十分必要的,那么为什么前端领域长时间不注重这个事情呢,我觉得有以下原因:
- 方案设计依赖技术能力,而前端技术栈变化太快,今天的设计套路放在明天可能就失效了
- 前端业务变化太快,经过半年的迭代之后,可能第一版的方案就反应不出现有代码逻辑了
- 前端的业务流程、交互流程比后端复杂太多,而且可复用性差,需要花费大量时间去思考和整理,而且对抽象能力有比较高的要求
- 前端开发效率高,不会有历史包袱,有时候直接重写的效率反而更高
但是这些原因其实都不是我们不做方案设计的理由,方案设计是个结构化思维的过程,他不光是能让项目更好执行,也能提升开发者本身的架构能力和宏观意识。
所以同学们在平时开发的时候多想一想如何做设计吧。