2

一个Web应用在其生命周期里,都要经历搭建开发环境、创建构建系统、编写代码、进行数据分析等等,直至最后使用新的系统来替换这个遗留系统。

Web应用的生命周期

在我所经历的项目以及我所看到的Web应用里,它们都有相同的很有意思的生命周期。我们经常在网上看到某个知名的网站使用某个新的技术、语言来替换旧的系统,某个APP使用开发新的框架来替换现有的APP。我们所看到的都只是这些公司正在重构现有的系统,这实际上是一个周期的结束,以及一个新的周期的开始。其过程如下图所示:

仔细一想就会发现:我们所经历的项目,都在以不同的时间长度经历相同的生命周期。

遗留系统与新架构

在我开始工作的时候,接触的第一个项目就是一个遗留系统。在一次休息时,我们在比赛找最古老的源码文件,最后找到了一个10年前写下的文件。尽管在我们的代码里有单元测试、针对具体业务功能的测试,项目的代码已经超过20万行,项目中仍然有相当多的代码超出了我们所理解的业务范围。毕竟在这些年头里,有相当多的功能已经不存在了。后来,我们选用微服务重构了这个系统。对于中型的遗留系统来说,这算是一剂良药。

让我们先从某某网站使用新架构重新设计说起。当我们决定使用新架构重新设计系统,原因可能是多种多样的,如果我们排除一些无法抗拒的因素,如政治,那么剩下的原因可能就只有两个:

  1. 系统已经变得难以维护。这里的原因仍然有很多:大量的代码已经没有人知道其业务逻辑,变得难以修改;代码间耦合度过高,重构系统的难度过于复杂;项目所使用的技术栈已经过时,已经被市场所淘汰;团队的技术栈在成员变动的过程中,团队中的大部分成员的技术栈已经和当前的项目不匹配了。

  2. 系统的技术栈已经难以符合业务的需求。绝大多数情况下,我们在最初的开始创建项目的时候,所选择的技术栈都是符合当时业务需求的技术栈、可以快速验证其业务价值的技术栈。而随着业务的扩张,现有的技术栈很快将难以满足当前业务的需求,或出现性能优化上的限制。

在多数情况下,我们都会将这种系统称之为遗留系统。在这时团队里的气氛,便是“能不动这些代码就尽量不去动它”。我们已经很难将项目的问题归根到人的因素上,多数的时候都是受业务扩张的影响。

作为一个专业的程序员,我们的本能就是将程序写好。而我们往往没有这样的机会:

业务人员对项目经理说:“我们的竞争对手已经在本周上线了这个功能”。

项目经理对开发人员说:“这个功能下星期就要上线

是的,我们的功能不得不马上上线。这时候,我们往往要在代码质量和交付速度上作出一些妥协。妥协多了,系统也就变烂了。

开发人员:“这个代码我不太敢修改,要是出了什么大bug怎么办?”。慢慢地人们就开始讨论起重构系统的事宜,并开始着手设计新的架构—使之可以满足当前的业务需求、可预测时间内的业务与技术需求。

技术选型与验证

在我们讨论新的架构的过程中,不同的人可能会有不同的技术偏好,也会因存在一些政治因素导致不同技术方案的产生。如团队中的一些人可能出于稳定缘故而使用Java,而一些人可能出于对新技术的需求使用Scala,而团队中大部分会可能因为都会使用JavaScript而选择使用JavaScript。如下图所示,我们的考虑应该不仅仅取决于这一系列的技术因素:

需要注意的是:在做技术选型的时候尽,要尽最大可能的以团队为核心。在我们最后决定之前,我们要提出不同语言、框架下的技术模型,并且进行验证。随后我们就需要快速搭建出一个原型,并针对这个原型进行假想式开发,然后验证原型本身是经得起考验的。

在这一阶段,我通常喜欢在GitHub上搜索一些名字中带有boilerplate的项目,即模块文件。而当一个框架很流行的时候,我就会去相应的awesome-xx寻找,如awesome-react就可以寻找到react相关的项目集。然后,我们Clone这样的一个项目,开始依照现有的系统创建简单的Demo。随后,我们就可以依据我们的业务试图在这上面进行扩展。最后,再决定是否使用这门技术、是否使用这个框架。

通常来说,在选择一门新技术来设计系统时,需要承担的风险相当的大,而如果能成功的话,那么它也很可能会带来巨大的收益。从这里看,使用最新的技术和赌博无益。在一些成熟的公司里,会有专门的技术委员会负责对新技术进行审核,来决定是否可以在某个项目里使用新的技术。除了,考虑其为开发带来的便利性,他们更多的会考虑其成熟度、安全以及技术风险等等。

搭建构建系统

决定好了架构、选择完技术栈后,我们就得着手于创建项目的构建系统,设计项目的部署流程。构建系统不仅仅包含了项目相关的构建流程,还从某种意义上反应了这个项目的工作流程。

在我们创建完hello, world程序后,我们要着手做的事情就是创建一个持续集成环境。这样的环境包含了一系列的工具、步骤及实践,从工具上来说,我们需要选择版本管理工具、代码托管环境、持续集成工具、打包工具、自动部署脚本等等一系列的流程,这些流程将会在“第四章 构建流及工作流”进行详细的讨论。

下图便是笔者之前经历过的一个项目的构建流程:

这是一个后台语言用的是 Java,前台语言用的是 JavaScript 的项目的构建流程。

迭代

在互联网行业里,能越快速地对市场需求做出反应,就越能有更好的发展。只要你细心观察就可以发现,大部分的互联网公司都在以一定的规律更新产品,或者一周,或者两周,又或者是一个月等等,这种不断地根据反馈来改进产品的过程称之为迭代。如下图是一个简化的迭代模型:

当一个迭代开始时,我们需要收集上一个迭代的反馈,又或者是新的需求,然后开始开发代码,最后再发布我们的产品。我们开发的产品在这个过程中,不断地增强功能。为此,我们还需要选择一个好的迭代周期。一个好的迭代周期,即应该有充足的时间,即可以修复上一个迭代的Bug,又能在下一个迭代开始之前交付重要的功能。当然,如果不幸交付的软件包里出现了重要的Bug,那么我们也能在第一时间使用旧版本的包,并在下个迭代交付。当然在这样的开发节奏里,一个星期显得太短,一个月又显得太长,两星期会是一个很不错的时间。

当一个团队在这方面做得不好时,那么他们可能在一次上线后,发现重要的bug,不得不在当晚又或者是第二天更新他们的产品。即使是有经验的团队,在开发的初期也会经常遇到这些问题,而这些问题可以依赖于在迭代中的回顾来改进这些流程问题。好的迭代实践都是依据团队自身的需求而发展而来的,这意味着有时候适合团队 A 的实践并不一定适合团队B。

随后,我们就会在这个 hello, world 的基础上不断地添加各种功能。

节选自:《全栈应用开发:精益实践》

亚马逊:《全栈应用开发:精益实践》 黄峰达【摘要 书评 试读】图书
京东:《全栈应用开发:精益实践》(黄峰达)【摘要 书评 试读】- 京东图书
当当:《全栈应用开发:精益实践》(黄峰达)【简介_书评_在线阅读】 - 当当图书


phodal
8k 声望2.8k 粉丝

待我代码编成,娶你为妻可好 @花仲马