- 本文写作说明
本文是根据笔者在华为时实际参与的开发过程并结合相关资料写作完成的。由于华为采取的是敏捷开发流程,故本文命名为《敏捷开发相关说明》。本文试图说明一套开发流程并探讨一些开发理念,以供大家参考。
- 流程与敏捷开发流程
流程,是指和组织本身功能相关的一系列规范和运作方式的集合;流程本身具有顺序性和相关性;一定意义来讲,流程是保证组织战略实施,让企业拥有核心竞争力的重要保证。
软件开发,是一个系统工程。软件开发不仅仅是写代码,而是由需求确定、需求控制、产品设计、架构设计、技术选型、编码实施、产品测试、质量保证、运行维护等一系列流程组成的过程。没有相关流程的软件,也许能暂时支撑某一小方面的功能,但往往无法应对足够的压力,容易崩溃和不易维护。
传统的软件开发采用直线流程,即沿着“需求——产品设计——代码编写——功能测试——软件交付”这个流程来开发;但这种软件开发流程往往时间周期长,质量性能差,并可能和实际需求有一定差距。
敏捷开发流程,是针对传统开发流程这一系列问题,而提出的一套软件开发理念。敏捷开发是一种以人为核心、迭代、循序渐进的开发方法。在敏捷开发中,软件项目的构建被切分成多个子项目,各个子项目的成果都经过测试,具备集成和可运行的特征。换言之,就是把一个大项目分为多个相互联系,但也可独立运行的小项目,并分别完成,在此过程中软件一直处于可使用状态。
- 敏捷开发流程的目的与意义
敏捷开发的目的有几个:
- 敏捷开发方法是“适应性”(Adaptive)而非“预设性” (Predictive)。
这里说的预设性,可以通过一般性工程项目的做法理解,比如土木工程,在这类工程实践中,有比较稳定的需求,同时建设项目的要求也相对固定,所以此类项目通常非常强调施工前的设计规划。只要图纸设计得合理并考虑充分,施工队伍可以完全遵照图纸顺利建造,并且可以很方便地把图纸划分为许多更小的部分交给不同的施工人员分别完成。
然而,在软件开发的项目中,这些稳定的因素却很难寻求。软件的设计难处在于软件需求的不稳定,从而导致软件过程的不可预测。但是传统的控制项目模式都是试图对一个软件开发项目在很长的时间跨度内做出详细的计划,然后依计划进行开发。所以,这类方法在不可预测的环境下,很难适应变化,甚至是拒绝变化。
与之相反的敏捷方法则是欢迎变化,目的就是成为适应变化的过程,甚至能允许改变自身来适应变化。所以称之为适应性方法。
(2)敏捷开发方法是“面向人” (people oriented)而非“面向过程”(process oriented)。
在敏捷开发过程中,人是第一位的,过程是第二位的。所以就个人来说,应该可以从各种不同的过程中找到真正适合自己的过程。这与软件工程理论提倡的先过程后人正好相反。
在传统的软件开发工作中,项目团队分配工作的重点是明确角色的定义,以个人的能力去适应角色,而角色的定义就是为了保证过程的实施,即个人以资源的方式被分配给角色,同时,资源是可以替代的,而角色不可以替代。
然而,传统软件开发的这些方法在敏捷开发方式中被完全颠覆。敏捷开发试图使软件开发工作能够利用人的特点,充分发挥人的创造能力。
敏捷开发的目的是建立起一个项目团队全员参与到软件开发中,包括设定软件开发流程的管理人员,只有这样软件开发流程才有可接受性。同时敏捷开发要求研发人员独立自主在技术上进行决策,因为他们是最了解什么技术是需要和不需要的。再者,敏捷开发特别重视项目团队中的信息交流,有调查显示:项目失败的原因最终都可追溯到信息没有及时准确地传递到应该接受它的人。
敏捷开发的意义在于:
- 适应用户需求,并可以在迭代中不断增强软件功能;
- 提高人的主动性;
- 借助多种工具,提高团队工作效率。
- 敏捷开发的特点
- 编码规范:每个团队人员进入首先学的是编码规范,而不是上来就干活;
- 师徒制度:每个团队人员进入,无论水平多高,都有师傅来带,徒弟表现是师傅的绩效之一;
- 测试全程跟随制度:测试,全程参与研发,并保证产品质量,促进产品优化;
- 流程和团队胜于单打独斗:注重流程,注重团队,而并不仅仅依赖个人能力;
- 更注重交流而不是过分注重文档,并认为源代码就是最好的文档;
- 迭代进行:从需求讨论,需求确定,产品研发和实现,都是多轮迭代进行的。
- 敏捷开发的几个关键术语
1)Test-Driven Development,测试驱动开发。
它是敏捷开发的最重要的部分。在敏捷开发中,我们实现任何一个功能都是从测试开始,首先对业务需求进行分析,分解为一个一个的Story,记录在Story Card上。然后两个人同时坐在计算机前面,一个人依照Story,从业务需求的角度来编写测试代码,另一个人看着他并且进行思考,如果有不同的意见就会提出来进行讨论,直到达成共识,这样写出来的测试代码就真实反映了业务功能需求。接着由另一个人控制键盘,编写该测试代码的实现。如果没有测试代码,就不能编写功能的实现代码。先写测试代码,能够让开发人员明确目标,就是让测试通过。
2)Continuous Integration,持续集成。
在以往的软件开发过程中,集成是一件很痛苦的事情,通常很长时间才会做一次集成,这样的话,会引发很多问题,比如 build未通过或者单元测试失败。
敏捷开发中提倡持续集成,一天之内集成十几次甚至几十次,如此频繁的集成能尽量减少冲突,由于集成很频繁,每一次集成的改变也很少,即使集成失败也容易定位错误。
一次集成要做哪些事情呢?它至少包括:获得所有源代码、编译源代码、运行所有测试,包括单元测试、功能测试等;确认编译和测试是否通过,最后发送报告。
当然也会做一些其它的任务,比如说代码分析、测试覆盖率分析等等。
3)Refactoring,重构。
相信大家对它都很熟悉了,有很多很多的书用来介绍重构,最著名的是Martin的《重构》,Joshua的《从重构到模式》等。重构是在不改变系统外部行为下,对内部结构进行整理优化,使得代码尽量简单、优美、可扩展。在以往开发中,通常是在有需求过来,现在的系统架构不容易实现,从而对原有系统进行重构;或者在开发过程中有剩余时间了,对现在代码进行重构整理。但是在敏捷开发中,重构贯穿于整个开发流程,每一次开发者check in代码之前,都要对所写代码进行重构,让代码达到clean code that works。值得注意的是,在重构时,每一次改变要尽可能小,用单元测试来保证重构是否引起冲突,并且不只是对实现代码进行重构,如果测试代码中有重覆,也要对它进行重构。
4)Pair-Programming,结对编程。
在敏捷开发中,做任何事情都是结对的,包括分析、写测试、写实现代码或者重构。结对做事有很多好处,两个人在一起探讨很容易产生思想的火花,也不容易走上偏路。
5)Stand up,站立会议。
每天早上,项目组的所有成员都会站立进行一次会议,由于是站立的,所以时间不会很长,一般来说是15-20分钟。会议的内容并不是需求分析、任务分配等,而是每个人都回答三个问题:1. 你昨天做了什么?2. 你今天要做什么? 3. 你遇到了哪些困难?站立会议让团队进行交流,彼此相互熟悉工作内容,如果有人曾经遇到过和你类似的问题,那么在站立会议后,他就会和你进行讨论。
6)Frequent Releases,小版本发布。
在敏捷开发中,不会出现这种情况,拿到需求以后就闭门造车,直到最后才将产品交付给客户,而是尽量多的产品发布,一般以周、月为单位。这样,客户每隔一段时间就会拿到发布的产品进行试用,而我们可以从客户那得到更多的反馈来改进产品。正因为发布频繁,每一个版本新增的功能简单,不需要复杂的设计,这样文档和设计就在很大程度上简化了。又因为简单设计,没有复杂的架构,所以客户有新的需求或者需求进行变动,也能很快的适应。
7)Minimal Documentation,较少的文档。
其实敏捷开发中并不是没有文档,而是有大量的文档,即源代码和测试。
敏捷开发认为:源代码就是最好的文档。
同时,敏捷开发认为,让人参与测试,对程序进行学习。
8)Collaborative Focus,以合作为中心,表现为代码共享。
在敏捷开发中,代码是归团队所有而不是哪些模块的代码属于哪些人,每个人都有权利获得系统任何一部分的代码然后修改它,如果有人看到某些代码不爽的话,那他能够对这部分代码重构。这样每个人都能熟悉系统的代码,即使团队的人员变动,也没有风险。
9)Customer Engagement ,现场客户。
敏捷开发中,客户是与开发团队一起工作的,团队到客户现场进行开发或者邀请客户到团队公司里来开发。如果开发过程中有什么问题或者产品经过一个迭代后,能够以最快速度得到客户的反馈。
10)Automated Testing ,自动化测试。
为了减小人力或者重覆劳动,所有的测试包括单元测试、功能测试或集成测试等都是自动化的,这对QA人员提出了更高的要求。他们要熟悉开发语言、自动化测试工具,能够编写自动化测试脚本或者用工具录制。
11)Adaptive Planning,可调整计划。
敏捷开发中计划是可调整的,并不是像以往的开发过程中,需求分析->概要设计->详细设计->开发 ->测试->交付,每一个阶段都是有计划的进行,一个阶段结束便开始下一个阶段。而敏捷开发中只有一次一次的迭代,小版本的发布,根据客户反馈随时作出相应的调整和变化。
- Product Owner:产品负责人。
产品负责人清楚的知道产品的愿景,需要对产品待办列表的梳理,优化,优先级排序等负责。决定团队每个冲刺要完成哪些任务。对于团队非常重要,决定Why和What。一般可以对应为现有的产品经理和BA的角色。
- PM:项目经理
项目经理确保团队合理的运作,并帮助团队扫除实施中的障碍。
- Team:团队
团队可以认为是开发团队,但是一个跨职能的团队,能够交付一个端到端的真正对客户有价值的产品。
- 敏捷开发流程
敏捷开发最关键的一个词是迭代,迭代原来指重复的反馈活动,在敏捷开发中,迭代指从头至尾的完整活动,但每次从头到尾的活动都会有进一步的任务,一般来说,迭代持续2-4周。
- 需求确定与产品设计
在该阶段,大致分为3轮迭代,主要为根据需求确定概念并根据需求进行产品设计的过程。在该阶段,需求要进行确定,并区分需求的优先级,并保证其他需求可以在迭代中不断实现。在该阶段,设计的产品应该保证在研发阶段每一个迭代的产品中都可以用和测试。
在该阶段,居于主导地位的是产品负责人、系统架构师和各模块负责人。产品负责人负责全局,系统架构师负责技术架构,各模块负责人负责各模块的具体特性,几方通力合作,对需求进行确定,对产品进行设计。在该阶段,会输出《需求确定书》、《产品设计图》和《开发计划》。
- 产品研发
该阶段大致分为2个半迭代。由于在需求设计中,产品设计为在不同迭代阶段的即可用的阶段。
该阶段由项目经理主导。在日常工作中,项目经理需要召集站立会议,并推动项目进展。同时,项目经理应该按一定周期(如一周)给产品负责人汇报团队工作。
同时,每一个迭代之后,都要由测试部门进行严格的测试。同时,值得注意的是,研发阶段的第2轮迭代是各重要里程碑,决定了项目的成败。
- 测试与产品迭代升级
从严格意义来讲,在敏捷开发中,测试贯穿研发阶段当中。测试的负责人是测试经理,并同测试工程师一起保证测试质量。测试与产品的迭代升级紧密融合,互相促进。
- 永不止步的迭代
当产品做出来以后,产品还可以继续升级和改造。即使该产品不再研发和维护了,新的产品也会采用迭代的形式。从这个意义来说,迭代是永不止步的。
- 敏捷开发的辅助工具
- 版本控制工具:SVN,Clear Case,Git等版本控制工具;
- 进度控制工具:燃尽图等工具;
- 测试驱动工具:注重测定的驱动开发;
- 代码互检工具:对代码进行互检,如gerrit等工具;
- 质量控制工具:主要是代码规范检查工具,如python的flake8等,
- 产品生成工具:主要是自动构建工具,如Jennkins等。
- 附注说明
本文对研发敏捷做了一个总结,并认为应该做两个附注说明:
- 任何公司都可以进行敏捷开发,至少可以有敏捷理念;
- 注重团队,注重流程;
- 立足于人,以人为本。