软件工程:
在讲解agile之前,我们有必要先了解一下,什么是软件工程。
软件工程是一门研究用工程化方法构建和维护有效的、实用的和高质量的软件的学科。它涉及程序设计语言、数据库、软件开发工具、系统平台、标准、设计模式等方面。以上是百度百科的说法。由于一直以来都没有一个对软件工程的统一的定义,因此很多学者、机构、组织给出了自己认可的定义。
就我个人而言,我觉得软件工程就是将软件研发、生产、维护等一系列工作条理化、系统化、工程化管理的一种思想。
传统的软件工程:
传统的软件工程要求在开发过程中,应该根据不同时期的需要,将工程划分为前后有序的明确步骤,并在强有力的管理下依次完成。一般包含以下八个阶段:可行性研究与计划、需求分析、概要设计、详细设计、实现(包括单元测试)、组装测试(即集成测试)、确认测试、使用维护。并且在工程的进行过程中,需要撰写大量的文档,例如:可行性研究报告、项目开发计划、软件需求说明书、用户手册、操作手册、测试分析报告、项目开发总结报告等。
瀑布模型:
瀑布模型是一种典型的传统软件工程的开发思想,由W.Royce在1970年提出。瀑布模型的开发过程是有固定顺序的,并且每一阶段的的输入是由上一阶段的输出得来,因此也就意味着之前的工作没有完成,是不能够继续进行下一阶段开发的。
优点:稳定且需求明确;
缺点:耗时长、任务顺序固定、越往后越难纠错、不能应对需求变化。
在对瀑布模型的优缺点进行分析后,我们不难得出结论,这是一种成熟、稳重的思想,但缺乏速度和激情,在上一个阶段没完成之前,下一个阶段的人只能看着,啥事都做不了。
Agile模式:
敏捷软件开发思想的根基在于将大的项目划分为多个相互联系、可以独立运行并进行交付的小项目,并且在项目期间加强与客户的交流合作,实时反馈并根据反馈内容实时修改开发计划。
比起传统的软件工程,它更加强调面对面的沟通、频繁交付新的软件版本、更好地适应需求的变化以及重视人在软件开发中的作用。
我个人认为agile更像是一种价值观;一种思维模式。
敏捷开发的12条基本原则:
2001年,17位软件开发者齐聚在美国的犹他州的雪鸟(snowbird),讨论上述轻量级的软件开发方法,并写下了敏捷软件开发宣言。
通过对宣言的解读总结出了敏捷开发的12项基本原则:
1.Our highest priority is to satisfy the customer through early and continuous delivery of valuable software.
我们应该根据客户对功能的需求,首先为客户提供最有价值的功能。这也就是说,敏捷开发能够在开发的每一步看到并且运行已有的成果,而并不是像传统的软件工程那样,只有等到整个工程结束后才可以看到成果如何,通过频繁的迭代能够在早期与客户形成良好的合作,并得到反馈来及时调整自己的开发计划。
就好比用户现在继续一个代步工具,我们首先满足他的最迫切的需求,在通过不断地迭代,不断地完善需求,直至最后完全满足客户需求。
2.Welcome changing requirements, even late in development. Agile processes harness change for the customer's competitive advantage.
敏捷开发的参与者不怕需求的变化,相反地,他们认为有需求变化是好事,因为这能够充分发挥敏捷开发的优势,毕竟传统的软件工程是不支持频繁改变的需求的,因此这既是挑战,也是机遇。
3.Deliver working software frequently, from a couple of weeks to a couple of months, with a preference for the shorter timescale.
减小迭代的时间间隔,并将阶段性的成果频繁交付给客户,让客户在每一阶段都能够有软件可用,这样能够使得用户提前体验到已有的功能,增加客户对开发人员的信赖程度,并且便于客户根据现阶段能够看到的功能,对软件的未来提出新的期许。
4.Business people and developers must work together daily throughout the project.
业务人员和开发人员应该每天都在一起工作,正所谓隔行如隔山,开发人员懂得如何开发,却不懂得业务人员的使用习惯。这样,每当程序员实现一个功能之前,都去吸收一下业务人员的建议,这样能够使得最终设计出来的软件,受到更广泛的业务人员的欢迎概率大大增加。
5.Build projects around motivated individuals. Give them the environment and support they need, and trust them to get the job done.
比起传统的软件工程,敏捷开发更加注重以人为本,认为给开发人员提供一个适宜的环境,相信他们的工作并且在他们需要的时候提供强有力的支持,更能够鼓舞人心,在这种积极的环境中,能够想象到的最终结果一定是皆大欢喜的“提前N天结束,并超额完成任务”!
6.The most efficient and effective method of conveying information to and within a development team is face-to-face conversation.
面对面的交流比起其他的方式更有效率。敏捷开发的人员数量一般不会很多,因此比起通过文档交流,凑在一起唠个嗑会是更有效率的交流方式。
7.Working software is the primary measure of progress.
比起传统软件工程不好计量工作进度的特点,敏捷开发由于能够在不同的开发阶段实现新的功能,因此更容易计量,在进度能够量化的体系中,员工的效率更容易保持在一个较高的水平。
8.Agile processes promote sustainable development. The sponsors, developers, and users should be able to maintain a constant pace indefinitely.
开发者应该被允许在一个比较恒定的速度上开发。这个问题在国内的某些企业尤其严重,过多的加班使得员工的身体和精神随时处于崩溃的边缘,并且养成了“突击”的意识。实际上,为了提前做完工程而使员工一直超负荷工作是不明智的,因为这样会大大降低他们的工作兴趣,并且产生一些消极的抵抗心理。
9.Continuous attention to technical excellence and good design enhances agility.
这句话正好验证了中国的一句老话:活到老,学到老。作为一名开发人员,永远不能自大,因为没人敢说自己已经精通了所有的技能,或者能够解决所有的问题,一定要怀着一颗谦逊的心,多看书,看好书。
10.Simplicity--the art of maximizing the amount of work not done--is essential.
在构建某一阶段的工作模型的时候,不要过于复杂,实现最初期望实现的功能就好,因为客户的需求是可能随时改变的,一开始就构建一个完整的框架很可能会拖慢整体的进度。像是两个在火灾现场逃生的人,其中一个只以当前最迫切的逃生为目的,而另一个顾虑的比较多,想着逃生的同时,却还想着拿点财物出去方便今后的生活。相比较而言,前者更容易逃生,后者能逃出来固然是好的,如果逃不出来,那之前的所有“为了未来更好生活”的计划便真的是一点意义也没有了。
11.The best architectures, requirements, and designs emerge from self-organizing teams.
自组织团队是敏捷开发的标志性特征之一,自组织团队比起传统的软件开发团队来说相对自由,团队的凝聚不是靠管理者的管理,而是靠团队文化对每个成员潜移默化的影响。自组织团队的成员能够更加自由地发表自己的见解,当然这条原则也经常是敏捷开发反对者们攻击的对象,毕竟在他们看来,没有的管理层的团队更像是一盘散沙。
12.At regular intervals, the team reflects on how to become more effective, then tunes and adjusts its behavior accordingly.
反思是进步的前提工作,由于敏捷开发提高了软件开发中人的作用,因此软件项目在开发时,受成员的主观影响非常大,出现错误的地方也是千差万别。因此,团队成员应该习惯在一个阶段结束的时候,反思之前的工作,并为今后的开发提供更加合理的建议,以此来保持团队的敏捷性。
Scrum:
如果把Agile看作是价值观,那么Scrum就是方法论了。
Scrum通常用3355归纳:
3个角色:产品负责人(Product Owner)、流程管理员(Scrum Master)、开发团队(Scrum Team)
产品负责人(Product Owner):主要负责确定产品的功能和达到要求的标准,指定软件的发布日期和交付的内容,同时有权力接受或拒绝开发团队的工作成果。
流程管理员(Scrum Master):主要负责整个Scrum流程在项目中的顺利实施和进行,以及清除挡在客户和开发工作之间的沟通障碍,使得客户可以直接驱动开发。
开发团队(Scrum Team):主要负责软件产品在Scrum规定流程下进行开发工作,人数控制在5-10人左右,每个成员可能负责不同的技术方面,但要求每成员必须要有很强的自我管理能力,同时具有一定的表达能力;成员可以采用任何工作方式,只要能达到Sprint的目标。
3个产出:Product Backlog、Sprint Backlog、潜在可交付的产品增量
Product Backlog:PO首先将需求按照优先级进行排列,产生一个Product Backlog。作用类似于传统开发中项目经理确定需求文档。产品待办列表就是产品的“What”。PO通过“讲故事”的方式,让团队理解产品的目标,帮助整个团队对用户故事有充分和统一的理解。
Sprint Backlog:有了Product Backlog列表,我们需要通过Sprint Planning Meeting(Sprint计划会议) 挑选出用户故事(Story)作为每次迭代完成的目标。
潜在可交付的产品增量:要求每一个Sprint结束都产生用户可用的软件,也被称着“潜在可交付的产品增量”(Potential shippable product increment, PSPI)。能否每个Sprint生成满足质量定义的PSPI 是Scrum 执行效果的试金石。因此这里关键的是团队内有一致同意的DOD(完成的定义),基于其中的内容来判断是否迭代内所有东西都做完了。同样,随着时间推移,团队DOD内容会不断修改完善 。“潜在可交付”并不意味着构建出的东西必须实际交付,交付是产品负责人的业务决策,基于发布计划来确定。
5个活动:Sprint Planning;Daily Scrum Meeting;Sprint Review;Retrospective;Backlog Refinement
Sprint Planning(IPM):Sprint计划会议在Sprint一开始召开。PO和团队共同决定计划在这个Sprint完成哪些用户故事。
Daily Scrum Meeting(Standup):每日站会,一般在15分钟以内。团队成员相互交流任务的进展,计划以及遇到的困难。
Sprint Review(Showcase):Sprint评审会议发生在Sprint将要结束的时候。团队和客户一起评审本次Sprint的产出是否达到预期。
Retrospective:回顾会议发生在Sprint的最后,由Scrum Master负责召集团队召开。会中大家回顾和小结这个Sprint做的好的地方以及有哪些不足。保证团队能够持续改进,不断提高。
Backlog Refinement:Product Backlog的梳理,可以发生在整个Scrum周期的任何时间。
5个价值观:勇气、专注、承诺、尊重、公开
Scrum需遵守间箱原则:
产品待办梳理会:不多于一个Sprint的10%,如两周的Sprint,可能要花一天的时间
Sprint计划会分两个部分,在每个Sprint开始时召开:
Sprint站会:每天应小于15分钟
Sprint评审会:时间箱为对应Sprint中每一周对应一个小时
SPrint回顾会:时间箱为对应Sprint中的每一周为45分钟
测试驱动开发(TDD):
测试驱动开发不是指测试人员驱动开发人员搞开发,一开始我真这么认为了,实际上测试驱动开发指以测试用例为出发点,不写一行代码的情况下,编写单元测试,从而无法通过,然后开始编写代码使之通过测试。这样做的好处是直指目标,达到目标被视为最高优先级,TDD的执行离不开重构,因为这种开发方式完全漠视设计。所以设计在开始时一定很差,通过不断的重构达到最优的代码,绝不会过度设计,也不会做偏。网上多半会说实践后你会喜欢上它,它的大概流程如下图所示:
行为驱动开发(Behavior Driven Development)BDD:
行为驱动开发是一种敏捷软件开发的技术,主要是从用户的需求出发,强调系统行为。BDD最初是由Dan North在2003年命名,它包括验收测试和客户测试驱动等的极限编程的实践,作为对测试驱动开发的回应。
BDD的软件研发过程是这样的:
1、产品经理(业务人员)通过具体的用户故事使用场景来告诉软件需求分析人员他(她)想要什么样的软件产品。使用软件产品的使用场景来描述软件需求可以尽可能的避免相关人员错误理解软件需求或增加自己的主观想象的需求。
2、软件需求分析人员(BA)和研发团队(研发人员、测试人员)一起对产品经理(业务人员)的用户故事进行分析,并梳理出具体的软件产品使用场景举例,这些场景举例使用结构化的关键字自然语言进行描述,例如中文、英文等。
3、研发团队使用BDD工具把用户故事场景文件转化为可执行的自动化测试代码,研发人员运行自动化测试用例来验证开发出来的软件产品是否符合用户故事场景的验收要求。
4、测试人员可以根据自动化测试结果开展手工测试和探索性测试。
5、产品经理(业务人员)可以实时查看软件研发团队的自动化测试结果和BDD工具生成的测试报告,确保软件实现符合产品经理(业务人员)的软件期望。
极限编程XP:
XP是一个轻量级的、灵巧的软件开发方法;同时它也是一个非常严谨和周密的方法。它的基础和价值观是交流、朴素、反馈和勇气。即任何一个软件项目都可以从四个方面入手进行改善:加强交流;从简单做起;寻求反馈;勇于实事求是。XP是一种近螺旋式的开发方法,它将复杂的开发过程分解为一个个相对比较简单的小周期;通过积极的交流、反馈以及其它一系列的方法,开发人员和客户可以非常清楚开发进度、变化、待解决的问题和潜在的困难等,并根据实际情况及时地调整开发过程。
敏捷开发中XP与SCRUM的区别
区别之一: 迭代长度的不同
XP的一个Sprint的迭代长度大致为1~2周, 而Scrum的迭代长度一般为 2~ 4周.
区别之二: 在迭代中, 是否允许修改需求
XP在一个迭代中,如果一个User Story(用户素材, 也就是一个需求)还没有实现, 则可以考虑用另外的需求将其替换,替换的原则是需求实现的时间量是相等的。 而Scrum是不允许这样做的,一旦迭代开工会完毕, 任何需求都不允许添加进来,并有Scrum Master严格把关,不允许开发团队受到干扰
区别之三: 在迭代中,User Story是否严格按照优先级别来实现
XP是务必要遵守优先级别的。 但Scrum在这点做得很灵活, 可以不按照优先级别来做,Scrum这样处理的理由是:如果优先问题的解决者,由于其它事情耽搁,不能认领任务,那么整个进度就耽误了。 另外一个原因是,如果按优先级排序的User Story #6和#10,虽然#6优先级高,但是如果#6的实现要依赖于#10,则不得不优先做#10.
区别之四:软件的实施过程中,是否采用严格的工程方法,保证进度或者质量
Scrum没有对软件的整个实施过程开出工程实践的处方。要求开发者自觉保证,但XP对整个流程方法定义非常严格,规定需要采用TDD, 自动测试, 结对编程,简单设计,重构等约束团队的行为。因此,原作者认为,这点上,XP的做法值得认同的,但是却把敏捷带入了一个让人困惑的矛盾, 因为xp的理念,结合敏捷模式,表达给团队的信息是“你是一个完全自我管理的组织, 但你必须要实现TDD, 结对编程等。
不难发现, Scrum非常突出Self-Orgnization, XP注重强有力的工程实践约束。建议, 在管理模式上启用Scrum, 而在实践中,创造一个适合自己项目组的XP
CI/CD持续集成/持续部署
持续集成(Continuous integration)是一种软件开发实践,即团队开发成员经常集成它们的工作,通过每个成员每天至少集成一次,也就意味着每天可能会发生多次集成。每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽早地发现集成错误。
持续部署(continuous deployment)是通过自动化的构建、测试和部署循环来快速交付高质量的产品。某种程度上代表了一个开发团队工程化的程度,毕竟快速运转的互联网公司人力成本会高于机器,投资机器优化开发流程化相对也提高了人的效率,让 engineering productivity 最大化。
持续交付(英语:Continuous delivery,缩写为 CD),是一种软件工程手法,让软件产品的产出过程在一个短周期内完成,以保证软件可以稳定、持续的保持在随时可以释出的状况。它的目标在于让软件的建置、测试与释出变得更快以及更频繁。这种方式可以减少软件开发的成本与时间,减少风险。
与DevOps的关系:
持续交付与DevOps的含义很相似,所以经常被混淆。但是它们是不同的两个概念。DevOps的范围更广,它以文化变迁为中心,特别是软件交付过程所涉及的多个团队之间的合作(开发、运维、QA、管理部门等),并且将软件交付的过程自动化。另壹方面,持续交付是壹种自动化交付的手段,关注点在于将不同的过程集中起来,并且更快、更频繁地执行这些过程。因此,DevOps可以是持续交付的壹个产物,持续交付直接汇入DevOps;
与持续部署的关系:
有时候,持续交付也与持续部署混淆。持续部署意味着所有的变更都会被自动部署到生产环境中。持续交付意味着所有的变更都可以被部署到生产环境中,但是出于业务考虑,可以选择不部署。如果要实施持续部署,必须先实施持续交付。
可以看出,敏捷开发(Agile Development)、持续集成(Continuous Integration)、持续交付(Continuous Delivery)和开发运维一体化(DevOps),所覆盖的软件生命周期的阶段不同。
当然,还有在敏捷开发中会出现的一些场景或道具,也可以在这里分享一下:
任务看板:任务看版包含 未完成、正在做、已完成 的工作状态,假设你今天把一个未完成的工作已经完成,那么你要把小卡片从未完成区域贴到已完成区域。
计划纸牌:比如A程序员开发一个功能,需要5个小时,B程序员认为只需要半小时,那他们各自取相应的牌,藏在手中,最后摊牌,如果时间差距很大,那么A和B就可以讨论A为什么要5个小时...
小结:
敏捷方法有时候被误认为是无计划性和纪律性的方法,实际上更确切的说法是敏捷方法强调适应性而非预见性。 敏捷开发不是一套一成不变的标准化流程,而更多的是一种自适应,自我优化的流程理念,不一样的团队有不一样的流程,所以实施前一定要根据自己团队当前状态做调整。记住这一点:敏捷就是永远只做对产品和项目有用的事情 。