软件开发流程的演变其实就是软件开发模型的演变过程。

软件开发模型是在软件开发中逐渐被总结的程序员的很多经验或方法,这些经验或方法经过提炼汇总就变成了软件开发模型。例如,最开始普及的是瀑布模型,后来出现了敏捷开发模型,现在很流行的是DevOps模型。

下面,分别介绍一下这几种软件开发模型。

1.瀑布模型

瀑布的意思是从山壁上或河床突然降落的地方流下的水,远看好像挂着的布匹。通俗理解就是水从上向下流形成的一个水流动的形式。软件开发中的瀑布模型也是一样,开发步骤像水流一样从上往下一步一步进行。瀑布模型如图1-1所示。

..\22-0118二校改图回传\1-1.tif

图1-1

(1)需求分析

在系统开发之前,我们首先要做的就是需求分析。

需求分析中的需求文档的内容是产品人员从用户那里了解到的需要解决的问题。产品人员了解清楚用户想要解决的问题之后,再把了解的内容细化成为一个文档——需求文档。需求文档中清楚地列出了系统大致拥有的大功能模块,大功能模块中又包括哪些小功能模块,并且还列出了系统具有的界面和界面功能。有了这个需求文档,系统的UI界面、功能就都确定下来了。

(2)设计

完成需求分析之后就开始做系统设计。设计包括两个方面。

1)界面设计:UI设计师根据需求文档设计出前端界面的一个设计稿。

2)程序设计:程序开发人员设计系统的基本处理流程、模块的划分、接口的规范等。

(3)编码

在软件编码阶段,程序开发人员会根据设计好的方案,通过代码实现一个系统。

(4)实现

实现就是开发人员用代码实现了需求文档里提出的系统功能。

(5)测试

开发人员把系统实现之后,软件测试人员就可以介入了。这也是瀑布模型的流程:先有系统代码,再做软件测试。

(6)发布与维护

软件测试工作完成之后,发布系统上线运行,并继续对系统进行维护。

(7)瀑布模型的特点

在瀑布模型中,软件开发人员的各项活动严格按照线性方式进行,当前活动接受上一项活动的工作结果,并对当前活动的工作结果进行验证。

瀑布模型的优点很明显,软件开发的各个阶段比较清晰,强调早期计划及需求调查,比较适合需求稳定的产品开发。

但是,因为软件开发人员的活动是线性的,所以依照此模型开发的系统的早期错误可能要等到开发后期的阶段才能被发现,这增加了开发的风险。

为了解决瀑布模型的这个问题,后面又慢慢发展出来了别的开发模型。

2.敏捷开发模型

敏捷开发模型是一种从20世纪90年代开始逐渐引起广泛关注的一种新型软件开发方法。这种开发模型更适用于产品需求频繁变化和产品需要快速开发的场景。

常见的敏捷开发模型有XP和Scrum,下面分别介绍这两种开发模型。

(1)XP(Extreme Programming,极限编程)

XP是一种近似螺旋式的开发方法(模型)。它是把复杂的开发周期分解为一个个相对比较简单的小周期,在每一个小周期里面,项目开发人员和客户都可以非常清楚地了解进度、变化、待解决的问题和潜在的困难等,而且可以根据实际情况及时地调整开发过程,如图1-2所示。

..\22-0118一校改图\22-0118改图回传\1-2.tif

图1-2

在图1-2中可以看出,极限编程是从3个维度来组织开发流程的。

1)编程方法

首先是编程方法这个维度。这个维度对开发人员的开发方法做出了规定。

简单设计:XP要求开发人员用最简单的办法实现每个小需求。一些设计只要能满足客户在当下的需求就可以了,不需做更高深的设计,这些设计都可在后续的开发过程中不断地调整和优化。

结对编程:指代码由两个开发人员一起完成。一个人主要考虑编码细节,另外一个人主要关注整体结构,不断地对第一个人开发的代码进行评审。

测试驱动开发:测试驱动开发的基本思想就是在开发功能代码之前,先编写测试代码。测试代码编写好之后,再去编写可以通过测试代码验证的功能代码。这样就可以让测试来驱动整个开发过程。这样做,有助于开发人员编写简洁、可用和高质量的代码,代码会具有很高的灵活性和健壮性。

重构:XP强调简单的设计,但简单的设计既不是没有任何结构的流水,也不是缺乏重用性的程序设计。XP提倡重构代码,主要是努力减少程序和设计中重复出现的部分,增强程序和设计的可重用性。

2)小组实践

小组实践是从团队合作的维度来规定开发人员的工作方法。

代码集体所有:代码集体所有意味着每个人都对系统所有的代码负责。反过来又意味着每个人都可以更改代码的任意部分。

编码标准:既然大家都可修改代码,那开发小组中的所有人都需要遵循一个统一的编程标准,这样所有的代码看起来好像是一个人编写的。因为有了统一的编程标准,小组中的每个程序员更加容易读懂其他人编写的代码,这是实现代码集体所有的重要前提之一。

稳定高速的步伐:可以把项目看作是马拉松长跑,而不是全速短跑。这需要团队成员保持长期稳定的工作节奏。

持续集成:集成就是要把团队中开发人员的代码合并到一起。团队中的开发人员需要经常把他们开发的程序集成在一起,每次集成都通过自动化的构建方式(其中还包括了自动化测试)来验证,这样能尽快发现系统代码集成后出现的错误。

隐喻:为了帮助开发团队中的每个人清楚地理解要完成的客户需求、要开发的系统功能,团队往往需要用很多形象的比喻来描述系统或功能模块是怎样工作的。例如,对于一个搜索引擎,它的系统隐喻可能是:一大群蜘蛛,在网上四处寻找要捕捉的东西,然后把东西带回家。

3)交付和发布

交付是把产品交到客户手中;发布是把产品上线运行,让用户可以使用系统。总体来说,交付和发布都是把产品交给用户,并可以上线使用。整个交付的过程会涉及4个方面。

小规模发布:规模有多小呢?就是系统每个迭代用时1~3周。在每个迭代结束的时候,团队交付可运行的、经过测试的功能,这些功能可以立即被使用。

计划游戏:预测在交付日期前可以完成多少工作,确定现在和下一步该做些什么工作。不断地回答这两个问题,就是直接服务于系统开发的实施及调整。

完整的团队:每一个项目中的贡献者都是“团队”完整的一部分。这个队伍是围绕着一个需要每天和队伍共同工作的商业代表——“客户”,建立起来的。

现场客户:在XP中,“客户”并不是为系统付账的人,而是真正使用该系统的人。XP认为客户应该时刻在开发现场并提出问题。

从XP开发模型可以看出,开发人员和客户在系统开发中占据主导地位。测试人员的工作基本都是通过自动化测试的方式进行的。例如,编码过程中的测试驱动开发这个环节和持续集成中都包含了自动化测试。总体而言,这个开发模型对开发人员和测试人员的要求都是非常高的,团队里的人必须都具有非常高的技术水平,这样才能使这个模型运转成功。

(2)Scrum

在Scrum模型里面,最基本的概念是Sprint。Sprint其实就是一个冲刺,通俗一点来说就是一个迭代周期,如图1-3所示。

..\22-0118三校改图\1-3.tif

图1-3

整个项目开始之前,会先有一个产品Backlog(清单)。使用产品Backlog来管理产品的需求,它是整个项目的概要文档。Backlog是一个按照商业价值排序的产品需求列表(清单),列表条目的体现形式通常为用户故事,即描述用户渴望得到系统的功能。

使用Scrum模型的团队从产品Backlog中挑选最高优先级的需求进行开发,挑选的需求在Sprint计划会议上讨论。

在Sprint计划会议上经过讨论、分析和估算得到相应的任务列表,这个任务列表被称为Sprint Backlog。

Scrum中,整个开发过程由若干个短的迭代周期组成,一个短的迭代周期称为一个Sprint,每个Sprint的建议时间长度是2~4周。

在每个迭代周期中,使用Scrum模型的团队会举行每日站会。在每日站会上团队检验Sprint目标的进展,做出调整,从而优化次日的工作。

每个迭代周期结束时,使用Scrum模型的团队将递交潜在可交付的产品增量。

在每个迭代周期最后,团队需要召开一次Sprint评审会议,会上团队的人员向产品负责人和利益相关方展示已完成的功能。

Sprint评审会议结束之后,下一个Sprint计划会议之前,需要召开Sprint回顾会议。回顾会议的目的是:在Sprint过程中,回顾一下哪些地方执行得很好,哪些地方执行得不好,团队可以做哪些改进。

整个Scrum模型的工作流程中,每一个Sprint也是一个迭代周期,其实也是一个小的瀑布。每个迭代周期都会完成一个需求分析—设计—编码—测试—上线这样的流程。

3.DevOps开发模型

DevOps(Dev和Ops的组合词)涉及软件整个开发生命周期中的各个阶段。

DevOps是一个非常关注开发(Dev)人员、运维(Ops)人员,以及测试人员之间沟通合作的开发模型。DevOps是通过自动化方式完成软件测试交付流程的,以便让构建、测试、发布软件能够更加地快捷、频繁和可靠地进行。

它的出现满足了现在的项目需要更加快速地上线并且每天都能上线新功能的需求。若在项目中用敏捷开发模型,项目上线新功能最快也需要一周的时间,满足不了每天都可以上线新功能的需求。所以,为了能够更加快捷地上线新功能,开发、测试和运维工作必须紧密合作。DevOps更适合用在项目中需求频繁变化,开发、测试、运维都需要敏捷的场景,如图1-4所示。

..\22-0118六校改图回传\1-4.tif

图1-4

DevOps是有生命周期的,下面介绍一下DevOps生命周期中包含了哪些阶段。

(1)持续开发

这是DevOps生命周期中软件不断被开发的阶段。与瀑布模型不同的是,软件可交付成果被分配在多个任务节点,目的是在较短的时间内开发并交付系统功能。

DevOps生命周期中软件不断被开发的阶段包括计划阶段、编码阶段和构建阶段。

1)计划阶段:可以使用一些项目管理工具,如JIRA来管理整个项目。

2)编码阶段:可以使用Git或者SVN来维护不同版本的代码。

3)构建阶段:使用打包工具,如Maven,把代码打包到可执行文件中。

(2)持续测试

在这个阶段,程序员开发出来的软件会被持续地测试。

对于持续测试,可以使用一些自动化测试工具实施,如Selenium、Appium。Selenium是做Web自动化测试的工具,Appium是做App自动化测试的工具。自动化测试的工具还需要配合测试框架一起使用,如Java中的TestNG、JUnit,Python中的unittest、pytest。有了这些自动化测试的工具,就可以持续地对开发出来的软件进行测试了。

(3)持续集成(CI)

一旦新提交的代码测试通过,这些代码就会不断地与已有代码进行集成,这就是持续集成。

这个时候可以使用Jenkins,它是现在流行的持续集成工具。使用Jenkins,可以从Git 库中提取最新的代码,并生成一个构建任务,最终可以把程序代码部署到测试环境或生产服务器中。

还可以把Jenkins设置成:发现Git库里有新提交的代码,就自动触发新构建任务;我们也可以单击Jenkins的“构建”按钮手动触发一个新的构建任务。有了Jenkins这款利器,开发人员就可以非常方便地完成代码的持续集成工作。

(4)持续部署

持续集成完成之后,就可以直接把代码部署到实际环境中。在这个阶段,需要保证只有通过了持续测试的正确代码才能被部署到服务器上。

因为,如果系统上线了新功能,就会有更多用户使用新功能。这样的话,为了不让系统宕机,运维人员可能还需要扩展服务器来容纳更多用户。持续部署是通过配置管理工具快速、频繁地执行部署任务实现的。这让产品的新功能可以更快地和用户见面,打通了开发、测试到上线的一个快速通道。

在这个阶段,容器化工具Docker也发挥着重要作用。它可以帮助保持各种运行环境是一致的,如测试环境、生产环境等,因为运行环境的不同也可能会导致一些系统Bug的出现。

(5)持续监控

系统上线之后,就到了持续监控的阶段。这是DevOps生命周期中非常关键的阶段。通过线上的监控可以帮助我们提高软件的质量,监控软件的性能。

这里也需要运营团队的参与,他们也会监控用户在使用产品过程中出现的一些“错误行为”,用以系统的进一步优化。

在这个阶段,可以使用ELK Stack,这是一个收集线上数据,并分析、展示数据的平台,通过这个工具可以自动地收集用户使用系统的动作和产品的一些线上的badcase(坏案例)数据,通过分析这些数据,可以为产品将来的发展方向做出指导。