敏捷开发 宣言 思想 认识误区

2023-10-31

 

  敏捷软件开发 Agile software Development

  敏捷开发是一种软件开发方法,基于迭代和增量开发,通过自组织,跨团队,沟通协作完成开发工作。

Image  敏捷宣言的诞生:
  2001年2月11日到13日,17位软件开发领域的领军人物聚集在美国犹他州的滑雪胜地雪鸟(Snowbird)雪场。经过两天的讨论,“敏捷”(Agile)这个词为全体聚会者所接受,用以概括一套全新的软件开发价值观。这套价值观,通过一份简明扼要的《敏捷宣言》,传递给世界,宣告了敏捷开发运动的开始。

  敏捷软件开发宣言

  我们一直在实践中探寻更好的软件开发方法,身体力行的同时也帮助他人。由此我们建立了如下价值观:

  个体和互动 高于 流程和工具

  工作的软件 高于 详尽的文档

  客户合作 高于 合同谈判

  响应变化 高于 遵循计划

  也就是说,尽管右项有其价值,我们更重视左项的价值。

  We are uncovering better ways of developing software by doing it and helping others do it. Through this work we have come to value:
  Individuals and interactions over processes and tools
  Working software over comprehensive documentation
  Customer collaboration over contract negotiation
  Responding to change over following a plan
  That is, while there is value in the items on the right, we value the items on the left more.

  敏捷开发的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 mouths, 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. 
  要善于激励项目人员,给他们以所需要的环境和支持,并相信他们能够完成任务。
  准则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. 
  团队要定期反省如何能够做到更有效,并相应地调整团队的行为。

  敏捷方法 Agile

  Scrum:http://zh.wikipedia.org/wiki/Scrum

  Scrum Role 角色

  Product Owner, Team, ScrumMaster, Chicken and the Pig

  产品经理,团队,ScrumMaster,鸡和猪,有一则小故事

  Scrum Meetings

  Sprint 计划会议 Sprint Planning Meeting

  需求澄清,确定那些用户故事需要在接下来的迭代里完成

  根据Product Owner制定的产品或项目计划在Sprint的开始时做准备工作。

  他要准备一个根据商业价值排好序的客户需求列表。这个列表就是Prodct Backlog[需求池],一个最终会交付给客户的产品特性列表,它们根据商业价值来排列优先级。

  商业价值"公式":As a <type of user> I want <some functionality> so that <some benefit>

Sprint Planning Meeting  每日站立会 Daliy Meeting

  在会议上每个团队成员回答三个问题(During the meeting, each team member answers three questions)

  1. 昨天你完成了那些工作?(What have you done since yesterday?)

  2. 今天天你打算做什么?(What are you planning to do today?)

  3. 完成你的目标是否存在障碍?(Do you have any problems that would prevent you from accomplishing your goal?)

  会议准时举行(The meeting starts precisely on time.)

  任何人都可以参加,,但只有团队内部人员发言(All are welcome, but normally only the core roles speak.)

  会议时长限制为15分钟(The meeting is timeboxed to 15 minutes.)

  会议时间地点应该固定(The meeting should happen at the same location and same time every day)

Image  评审会议(Sprint Review Meeting
  评审会议在每个迭代结束后举行,在会议上团队演示此次迭代中完成了那些工作,一般会有相关的DEMO演示。
  At the end of each sprint a sprint review meeting is held. During this meeting the Scrum team shows what they accomplished during the sprint. Typically this takes the form of a demo of the new features.

  这个会议演示的内容应该是启动会议上确定的那些内容

  During the sprint review the project is assessed against the sprint goal determined during the Sprint planning meeting

Image(3)  回顾会议(Sprint Retrospective Meeting)
  冲刺回顾会议一般限时为3个小时(The sprint retrospective meeting is timeboxed to 3 hours.)

  仅团队成员参加,产品经理和ScrumMaster,产品经理选择性参加(It is attended only by the team, the scrum master and the product owner. The product owner is optional.)。

  会议上团队中每个成员需要回答两个问题(Start the meeting by having all team members answer two questions):

  1. 此次冲刺中那些地方做得好?(What went well during the sprint?)

  2. 下个迭代中那些地方可以改进? (What could be improved in the next sprint?)

  scrum master记录每个成员的答案(The scrum master writes down the team’s answers in summary form)。

  团队为这些改进意见评定优先级(The team prioritizes in which order it wants to talk about the potential improvements)。

  scrum master在回顾会议中不允许给出答案,但要鼓励成员自己找到较好的办法(The scrum master is not in this meeting to provide answers, but to facilitate the team’s search for better ways for the scrum process to work for it)。

  这些改进工作可以添加至下个迭代中,作为一个非功能性工作,回顾会议最不担心的就是变化(Actionable items that can be added to the next sprint should be devised as high-priority non functional product backlog. Retrospectives that dont result in change are sterile and frustrating.)。

Image(4)  测试驱动开发(TDD/Test-Driven Development)

  测试驱动开发不是指测试人员驱动开发人员搞开发,一开始我真这么认为了,实际上测试驱动开发指以测试用例为出发点,不写一行代码的情况下,编写单元测试,从而无法通过,然后开始编写代码使之通过测试。这样做的好处是直指目标,达到目标被视为最高优先级,TDD的执行离不开重构,因为这种开发方式完全漠视设计。所以设计在开始时一定很差,通过不断的重构达到最优的代码,绝不会过度设计,也不会做偏。网上多半会说实践后你会喜欢上它,它的大概流程如下图所示:

Image(8)  极限编程XP

  XP是一个轻量级的、灵巧的软件开发方法;同时它也是一个非常严谨和周密的方法。它的基础和价值观是交流、朴素、反馈和勇气。即任何一个软件项目都可以从四个方面入手进行改善:加强交流;从简单做起;寻求反馈;勇于实事求是。XP是一种近螺旋式的开发方法,它将复杂的开发过程分解为一个个相对比较简单的小周期;通过积极的交流、反馈以及其它一系列的方法,开发人员和客户可以非常清楚开发进度、变化、待解决的问题和潜在的困难等,并根据实际情况及时地调整开发过程。

  结队编程Paring Program -即时反馈

  http://kb.cnblogs.com/page/91650/

  http://www.blogjava.net/moxie/archive/2006/09/14/69714.html

  流模式(Flow)——两个程序员共同从事一个有趣又有挑战性的问题。

  指导模式(Coaching)——老练的程序员在解决问题方面有经验和知识,可以与其他不能有效地独自解决问题的程序员分享。

Image(9)  看板Kanban - 工作可视化,专注于当下

  非常软的软广告:国产开源敏捷工具 - fKanban

  http://www.cnblogs.com/a311300/archive/2010/11/18/1880776.html

  ToDo, OnGoing, Done, Impediment

Image(5)

  敏捷估算扑克 - 合理的任务分解
  http://community.techexcel.com.cn/010DevSuite/070Agile_Scrum/010Posts/010Agile_Poker

  http://www.csaipm.com/cost/201005101141211188.htm

  敏捷方法中的估算应该是由团队成员共同进行,而不是由项目经理“闭门造车”式地得出。这样做的原因之一是因为开发团队是由不同经验的同事组成,对于同一个问题,经验不同的人往往会给出不一样的解决方案。如果可以将所有人的能力集中到一起,那么最后对问题的求解也就八九不离十了。

Image(6)  持续集成(Continuous Integration)- 团队协作的基础

  http://blog.csdn.net/tony1130/article/details/1876819

  http://www.hansky.com.cn/cn/dokuwiki/doku.php/corp/case/digitalchina

  什么是持续集成(Continuous Integration)?

  这个名词已经在软件开发领域持续了N年,一个比较简单的定义如下:

  持续集成(CI)是一种实践,可以让团队在持续发布的基础上收到反馈并进行改进,不必等到开发周期后期才寻找和修复缺陷。

Image(7)  单元测试Unit Test - 重构的保障

  http://www.hudong.com/wiki/%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95
  单元测试(模块测试)是开发者编写的一小段代码,用于检验被测代码的一个很小的、很明确的功能是否正确。通常而言,一个单元测试是用于判断某个特定条件(或者场景)下某个特定函数的行为。

  敏捷测试 Agile Test

  http://subject.csdn.net/agile-testing.htm
  所谓敏捷测试,就是指测试遵循敏捷宣言进行,把开发作为顾客看待。与敏捷宣言中的“个体和交互比过程和工具更有价值”一样强调人的作用。

  代码重构(Reconstruction)

  Duplicated Code(重复代码)

  Long Method(过长函数)

  Large Class(过大的类)

  Long Parameter List(过长参数列)

  Divergent Change(发散式变化)

  Shotgun Surgery(霰弹式修改)

  Feature Envy(依恋情结)

  Data Clumps(数据泥团)

  Primitive Obsession(基本类型偏执)

  Switch Statements(switch惊悚现身)

  Parallel InheritanceHierarchies(平行继承体系)

  Lazy Class(冗赘类)

  Speculative Generality(夸夸其谈未来性)

  Temporary Field(令人迷惑的暂时字段)

  Message Chains(过度耦合的消息链)

  Middle Man(中间人)

  Inappropriate Intimacy(狎昵关系)

  Alternative Classes with Different Interfaces(异曲同工的类)

  Incomplete Library Class(不完美的库类)

  Data Class(纯稚的数据类)

  Refused Bequest(被拒绝的遗赠)

  Comments(过多的注释)

  Extract Method(提炼函数)

  Inline Method(内联函数)

  Inline Temp(内联临时变量)

  Replace Temp with Query(以查询取代临时变量)

  Introduce Explaining Variable(引入解释性变量)

  Split Temporary Variable(分解临时变量)

  Remove Assignments to Parameters(移除对参数的赋值)

  Replace Method with Method Object(以函数对象取代函数)

  Substitute Algorithm(替换算法)

  Move Method(搬移函数)

  Move Field(搬移字段)

  Extract Class(提炼类)

  Inline Class(将类内联化)

  Hide Delegate(隐藏"委托关系")

  Remove Middle Man(移除中间人)

  Introduce Foreign Method(引入外加函数)

  Introduce Local Extension(引入本地扩展)

  Self Encapsulate Field(自封装字段)

  Replace Data Value with Object(以对象取代数据值)

  Change Value to Reference(将值对象改为引用对象)

  Change Reference to Value(将引用对象改为值对象)

  Replace Array with Object(以对象取代数组)

  Duplicate Observed Data(复制"被监视数据")

  Change Unidirectional Association to Bidirectional(将单向关联改为双向关联)

  Change Bidirectional Association to Unidirectional(将双向关联改为单向关联)

  Replace Magic Number with Symbolic Constant(以字面常量取代魔法数)

  Encapsulate Field(封装字段)

  Encapsulate Collection(封装集合)

  Replace Record with Data Class(以数据类取代记录)

  Replace Type Code with Class(以类取代类型码)

  Replace Type Code with Subclasses(以子类取代类型码)

  Replace Type Code with State/Strategy(以State/Strategy取代类型码)

  Replace Subclass with Fields(以字段取代子类)

  Decompose Conditional(分解条件表达式)

  Consolidate Conditional Expression(合并条件表达式)

  Consolidate Duplicate Conditional Fragments(合并重复的条件片段)

  Remove Control Flag(移除控制标记)

  Replace Nested Conditional with Guard Clauses(以卫语句取代嵌套条件表达式)

  Replace Conditional with Polymorphism(以多态取代条件表达式)

  Introduce Null Object(引入Null对象)

  Introduce Assertion(引入断言)

  Rename Method(函数改名)

  Add Parameter(添加参数)

  Remove Parameter(移除参数)

  Separate Query from Modifier(将查询函数和修改函数分离)

  Parameterize Method(令函数携带参数)

  Replace Parameter with Explicit Methods(以明确函数取代参数)

  Preserve Whole Object(保持对象完整)

  Replace Parameter with Methods(以函数取代参数)

  Introduce Parameter Object(引入参数对象)

  Remove Setting Method(移除设值函数)

  Hide Method(隐藏函数)

  Replace Constructor with Factory Method(以工厂函数取代构造函数)

  Encapsulate Downcast(封装向下转型)

  Replace Error Code with Exception(以异常取代错误码)

  Replace Exception with Test(以测试取代异常)

  Pull Up Field(字段上移)

  Pull Up Method(函数上移)

  Pull Up Constructor Body(构造函数本体上移)

  Push Down Method(函数下移)

  Push Down Field(字段下移)

  Extract Subclass(提炼子类)

  Extract Superclass(提炼超类)

  Extract Interface(提炼接口)

  Collapse Hierarchy(折叠继承体系)

  Form Tem Plate Method(塑造模板函数)

  Replace Inheritance with Delegation(以委托取代继承)

  Replace Delegation with Inheritance(以继承取代委托)

  Tease Apart Inheritance(梳理并分解继承体系)

  Convert Procedural Design to Objects(将过程化设计转化为对象设计)

  Separate Domain from Presentation(将领域和表述/显示分离)

  Extract Hierarchy(提炼继承体系)

  代码Review

  不想重复说了,同单元测试一样重要。

Image(10)  总结

  以上是个人经过理论学习,实践检验后总结的一篇文章,其中大部分观点、素材皆来自网络和公司敏捷活动中所得。我想要说的是,我是支持这些观点的,我认为这些方法论可以很好的指导日常开发工作,能够解决实际问题,That's All。

转自 http://kb.cnblogs.com/page/107587/

 

 

敏捷开发(Agile development)

敏捷开发概述

  敏捷开发是一种以人为核心、迭代、循序渐进的开发方法。在敏捷开发中,软件项目的构建被切分成多个子项目,各个子项目的成果都经过测试,具备集成和可运行的特征。换言之,就是把一个大项目分为多个相互联系,但也可独立运行的小项目,并分别完成,在此过程中软件一直处于可使用状态。

敏捷开发的路线

  Image:敏捷开发的路线图.jpg

  图:敏捷开发的路线图

  Test-Driven Development,测试驱动开发。

  它是敏捷开发的最重要的部分。在ThoughtWorks,我们实现任何一个功能都是从测试开始,首先对业务需求进行分析,分解为一个一个的Story,记录在Story Card上。然后两个人同时坐在电脑前面,一个人依照Story,从业务需求的角度来编写测试代码,另一个人看着他并且进行思考,如果有不同的意见就会提出来进行讨论,直到达成共识,这样写出来的测试代码就真实反映了业务功能需求。接着由另一个人控制键盘,编写该测试代码的实现。如果没有测试代码,就不能编写功能的实现代码。先写测试代码,能够让开发人员明确目标,就是让测试通过。

  Continuous Integration,持续集成。

  在以往的软件开发过程中,集成是一件很痛苦的事情,通常很长时间才会做一次集成,这样的话,会引发很多问题,比如 build未通过或者单元测试失败。敏捷开发中提倡持续集成,一天之内集成十几次甚至几十次,如此频繁的集成能尽量减少冲突,由于集成很频繁,每一次集成的改变也很少,即使集成失败也容易定位错误。一次集成要做哪些事情呢?它至少包括:获得所有源代码、编译源代码、运行所有测试,包括单元测试、功能测试等;确认编译和测试是否通过,最后发送报告。当然也会做一些其它的任务,比如说代码分析、测试覆盖率分析等等。在我们公司里,开发人员的桌上有一个火山灯用来标志集成的状态,如果是黄灯,表示正在集成;如果是绿灯,表示上一次集成通过,开发人员在这时候获得的代码是可用而可靠的;如果显示为红灯,就要小心了,上一次集成未通过,需要尽快定位失败原因从而让灯变绿。在持续集成上,我们公司使用的是自己开发的产品CruiseControl。

  Refactoring,重构。

  相信大家对它都很熟悉了,有很多很多的书用来介绍重构,最著名的是Martin的《重构》,Joshua的《从重构到模式》等。重构是在不改变系统外部行为下,对内部结构进行整理优化,使得代码尽量简单、优美、可扩展。在以往开发中,通常是在有需求过来,现在的系统架构不容易实现,从而对原有系统进行重构;或者在开发过程中有剩余时间了,对现在代码进行重构整理。但是在敏捷开发中,重构贯穿于整个开发流程,每一次开发者check in代码之前,都要对所写代码进行重构,让代码达到clean code that works。值得注意的是,在重构时,每一次改变要尽可能小,用单元测试来保证重构是否引起冲突,并且不只是对实现代码进行重构,如果测试代码中有重复,也要对它进行重构。

  Pair-Programming,结对编程。

  在敏捷开发中,做任何事情都是Pair的,包括分析、写测试、写实现代码或者重构。Pair做事有很多好处,两个人在一起探讨很容易产生思想的火花,也不容易走上偏路。在我们公司,还有很多事都是Pair来做,比如Pair学习,Pair翻译,Pair做PPT,关于这个话题,钱钱同学有一篇很有名的文章对它进行介绍,名为Pair Programming (结对编程)。

  Stand up,站立会议。

  每天早上,项目组的所有成员都会站立进行一次会议,由于是站立的,所以时间不会很长,一般来说是15-20分钟。会议的内容并不是需求分析、任务分配等,而是每个人都回答三个问题:1. 你昨天做了什么?2. 你今天要做什么? 3. 你遇到了哪些困难?站立会议让团队进行交流,彼此相互熟悉工作内容,如果有人曾经遇到过和你类似的问题,那么在站立会议后,他就会和你进行讨论。

  Frequent Releases,小版本发布。

  在敏捷开发中,不会出现这种情况,拿到需求以后就闭门造车,直到最后才将产品交付给客户,而是尽量多的产品发布,一般以周、月为单位。这样,客户每隔一段时间就会拿到发布的产品进行试用,而我们可以从客户那得到更多的反馈来改进产品。正因为发布频繁,每一个版本新增的功能简单,不需要复杂的设计,这样文档和设计就在很大程度上简化了。又因为简单设计,没有复杂的架构,所以客户有新的需求或者需求进行变动,也能很快的适应。

  Minimal Documentation,较少的文档。

  其实敏捷开发中并不是没有文档,而是有大量的文档,即测试。这些测试代码真实的反应了客户的需求以及系统API 的用法,如果有新人加入团队,最快的熟悉项目的方法就是给他看测试代码,而比一边看着文档一边进行debug要高效。如果用书面文档或者注释,某天代码变化了,需要对这些文档进行更新。一旦忘记更新文档,就会出现代码和文档不匹配的情况,这更加会让人迷惑。而在敏捷中并不会出现,因为只有测试变化了,代码才会变化,测试是真实反应代码的。这时有人会问:代码不写注释行吗?一般来说好的代码不是需要大量的注释吗?其实简单可读的代码才是好的代码,既然简单可读了,别人一看就能够看懂,这时候根本不需要对代码进行任何注释。若你觉得这段代码不加注释的话别人可能看不懂,就表示设计还不够简单,需要对它进行重构。

  Collaborative Focus,以合作为中心,表现为代码共享。

  在敏捷开发中,代码是归团队所有而不是哪些模块的代码属于哪些人,每个人都有权利获得系统任何一部分的代码然后修改它,如果有人看到某些代码不爽的话,那他能够对这部分代码重构而不需要征求代码作者的同意,很可能也不知道是谁写的这部分代码。这样每个人都能熟悉系统的代码,即使团队的人员变动,也没有风险。

  Customer Engagement ,现场客户。

  敏捷开发中,客户是与开发团队一起工作的,团队到客户现场进行开发或者邀请客户到团队公司里来开发。如果开发过程中有什么问题或者产品经过一个迭代后,能够以最快速度得到客户的反馈。

  Automated Testing ,自动化测试。

  为了减小人力或者重复劳动,所有的测试包括单元测试、功能测试或集成测试等都是自动化的,这对QA人员提出了更高的要求。他们要熟悉开发语言、自动化测试工具,能够编写自动化测试脚本或者用工具录制。我们公司在自动化测试上做了大量的工作,包括Selenium开源项目。

  Adaptive Planning,可调整计划。

  敏捷开发中计划是可调整的,并不是像以往的开发过程中,需求分析->概要设计->详细设计->开发 ->测试->交付,每一个阶段都是有计划的进行,一个阶段结束便开始下一个阶段。而敏捷开发中只有一次一次的迭代,小版本的发布,根据客户反馈随时作出相应的调整和变化。

  敏捷开发过程与传统的开发过程有很大不同,在这过程中,团队是有激情有活力的,能够适应更大的变化,做出更高质量的软件。

敏捷开发的特点

  敏捷方法主要有两个特点,这也是其区别于其他方法,尤其是重型方法的最主要特征:

  (1)敏捷开发方法是“适应性”(Adaptive)而非“预设性” (Predictive)。

  这里说的预设性,可以通过一般性工程项目的做法理解,比如土木工程,在这类工程实践中,有比较稳定的需求,同时建设项目的要求也相对固定,所以此类项目通常非常强调施工前的设计规划。只要图纸设计得合理并考虑充分,施工队伍可以完全遵照图纸顺利建造,并且可以很方便地把图纸划分为许多更小的部分交给不同的施工人员分别完成。

  然而,在软件开发的项目中,这些稳定的因素却很难寻求。软件的设计难处在于软件需求的不稳定,从而导致软件过程的不可预测。但是传统的控制项目模式都是试图对一个软件开发项目在很长的时间跨度内做出详细的计划,然后依计划进行开发。所以,这类方法在不可预测的环境下,很难适应变化,甚至是拒绝变化。

  与之相反的敏捷方法则是欢迎变化,目的就是成为适应变化的过程,甚至能允许改变自身来适应变化。所以称之为适应性方法。    (2)敏捷开发方法是“面向人” (people oriented)而非“面向过程”(process oriented)。

  Matin Flower认为:“在敏捷开发过程中,人是第一位的,过程是第二位的。所以就个人来说,应该可以从各种不同的过程中找到真正适合自己的过程。”这与软件工程理论提倡的先过程后人正好相反。 (续致信网上一页内容)

  在传统的软件开发工作中,项目团队分配工作的重点是明确角色的定义,以个人的能力去适应角色,而角色的定义就是为了保证过程的实施,即个人以资源的方式被分配给角色,同时,资源是可以替代的,而角色不可以替代。

  然而,传统软件开发的这些方法在敏捷开发方式中被完全颠覆。敏捷开发试图使软件开发工作能够利用人的特点,充分发挥人的创造能力。

  敏捷开发的目的是建立起一个项目团队全员参与到软件开发中,包括设定软件开发流程的管理人员,只有这样软件开发流程才有可接受性。同时敏捷开发要求研发人员独立自主在技术上进行决策,因为他们是最了解什么技术是需要和不需要的。再者,敏捷开发特别重视项目团队中的信息交流,有调查显示:“项目失败的原因最终都可追溯到信息没有及时准确地传递到应该接受它的人。”

敏捷开发的价值观

  实际上敏捷开发运动在数年前就开始了,但它正式开始的标志是2001年2月的“敏捷宣言”(Agile Manifesto),这项宣言是由17位当时称之为“轻量级方法学家”所编写签署的,他们的价值观是:个人与交互重于开发过程与工具;可用的软件重于复杂的文档;寻求客户的合作重于对合同的谈判;对变化的响应重于始终遵循固定的计划。

  个人与交互重于开发过程与工具的原因:一个由优秀的人员组成但使用普通的工具,要比使用优秀的工具但由普通人组成、紊乱的小组做得更好。多年来人们花了很多时间试图建立一种过程,以便把人当作机器上的一个可以替代的齿轮,但结果却并不成功。敏捷过程是承认每个人都有特定的能力(以及缺点)对之加以利用,而不是把所有的人当成一样来看待。更重要的是,在这样的理念下,几个项目做下来,每个人的能力都从中得以提高。这种人的能力的提高,对公司是无价之宝。而不至于把人当成齿轮,随着时间的推移,人的能力慢慢被消耗掉,最后变成留之无用、弃之可惜的尴尬人物。

  可用的软件重于复杂的文档的原因:可用的软件可以帮助开发人员在每次迭代结束的时候,获得一个稳定的、逐渐增强的版本。从而允许项目尽早开始,并且更为频繁的收集对产品和开发过程的反馈。随着每次迭代完成软件的增长,以保证开发小组始终是处理最有价值的功能,而且这些功能可以满足用户的期待。

  寻求客户的合作重于对合同的谈判的原因:敏捷开发小组希望与项目有关的所有团体都在朝共同方向努力,合同谈判有时会在一开始就使小组和客户出于争执中。敏捷开发追求的是要么大家一起赢,要么大家一起输。换句话说,就是希望开发小组和客户在面对项目的时候,以一种合作的态度共同向目标前进。当然,合同是必需的,但是如何起草条款,往往影响到不同的团体是进行合作式的还是对抗式的努力。

  对变化的响应重于始终遵循固定的计划的原因:敏捷开发认为对变化进行响应的价值重于始终遵循固定的计划。他们最终的焦点是向用户交付尽可能多的价值。除了最简单的项目以外,用户不可能知道他们所需要的所有功能的每个细节。不可避免地在过程中会产生新的想法,也许今天看起来是必需的功能,明天就会觉得不那么重要了。随着小组获得更多的知识和经验,他们的进展速度会比开始的时候期望值慢或者快。对敏捷开发来说,一个计划是从某个角度对未来的看法,而具有多个不同的角度看问题是有可能的。

项目的敏捷开发方法

  敏捷方法很多,包括 Scrum、极限编程、功能驱动开发以及统一过程(RUP)等多种法,这些方法本质实际上是一样的,敏捷开发小组主要的工作方式可以归纳为:作为一个整体工作; 按短迭代周期工作; 每次迭代交付一些成果; 关注业务优先级; 检查与调整。下图是典型的敏捷过程总图,下面介绍其有关的特点。

  Image:敏捷过程总图.gif

  1、敏捷小组作为一个整体工作

  项目取得成功的关键在于,所有项目参与者都把自己看成朝向一个共同目标前进的团队的一员。“扔过去不管”的心理不是属于敏捷开发。设计师和架构师不会把程序设计“扔”给编码人员;编码人员也不会把只经过部分测试的代码“扔”给测试人员,一个成功的敏捷开发小组应该具有“我们一起参与其中的思想”, “帮助他人完成目标”这个理念是敏捷开发的根本管理文化。当然,尽管强调一个整体,小组中应该有一定的角色分配,各种敏捷开发方法角色的起名方案可能不同,但愿则基本上是一样的。第一个角色是产品所有者,他的主要职责包括:确认小组成员都在追求一个共同的目标前景;确定功能的优先等级,以便总是处理最有价值的功能;作出可以使项目的投入产生良好回报的决定。产品所有者通常是公司的市场部门或者产品管理部门的人员,在开发内部使用的软件的时候,产品所有者可能是用户、用户的上级、分析师,也可能是为项目提供资金的人。

  2、敏捷小组按短迭代周期工作

在敏捷项目中,总体上并没有什么上游阶段、下游阶段,你可以根据需要定义开发过程在初始阶段可以有一个简短的分析、建模、设计,但只要项目真正开始,每次迭代都会做同样的工作(分析、设计、编码、测试。等等)。迭代是受时间框限制的,也就是说即使放弃一些功能,也必须结束迭代。时间框一般很短,大部分是 2~4周,在 Scrum中采用的是 30个日历天,也就是 4 周。迭代的时间长度一般是固定的,但也有报告说,有的小组在迭代开始的时候选择合适的时间长度。

  3、敏捷小组每次迭代交付一些成果

  比选择特定迭代长度更重要的,是开发小组在一次迭代中要把一个以上的不太精确的需求声明,经过分析、设计、编码、测试,变成可交付的软件(称之为功能增量)。当然并不需要把每次迭代的结果交付给用户,但目标是可以交付,这就意味着每次迭代都会增加一些小功能,但增加的每个功能都要达到发布质量。每次迭代结束的时候让产品达到可交付状态十分重要,但这并不意味着要完成发布的全部工作,因为迭代的结果并不是真正发布产品。假定一个小组需要在发布产品之前对软硬件进行为期两个月的“平均无故障时间”(MTBF)测试,他们不可能缩短这两个月的时间,但这个小组仍然是按照  4 周迭代,除了MTBF测试,其它都达到了发布状态。

  4、敏捷小组关注业务优先级

  敏捷开发小组从两个方面显示出他们对业务优先级的关注。首先,他们按照产品所有者制定的顺序交付功能,而产品所有者一般会按照组织在项目上的投资回报最大化的方式来确定优先级,并且把它组织到产品发布中去。要达到这个目的,需要综合考虑开发小组的能力,以及所需功能的优先级来建立发布计划。在编写功能的时候,需要使工能的依赖性最小化。如果开发一个功能必须依赖其它 3 个功能,那产品所有者这就很难确定功能优先级。功能完全没有依赖是不太可能的,但把功能依赖性控制在最低程度还是相当可行的。

  5、敏捷小组检查与调整

  任何项目开始的时候所建立的计划,仅仅是一个当前的猜测。有很多事情可以让这样的计划失效:项目成员的增减,某种技术比预期的更好或更差,用户改变了想法,竞争者迫使我们做出不同的反应,等等。对此,敏捷小组不是害怕这种变化,而是把这种变化看成使最终软件更好地反映实际需要的一个机会。每次新迭代开始,敏捷小组都会结合上一次迭代中获得新知识做出相应调整。如果认为一些因素可能会影响计划的准确性,也可能更改计划。比如发现某项工作比预计的更耗费时间,可能就会调整进展速度。也许,用户看到交付的产品后改变了想法,这就产生反馈,比如他发现他更希望有另一项功能,或者某个功能并不像先前看得那么重。通过先期发布增加更多的用户希望的功能,或者减少某些低价值功能,就可以增加产品的价值。迭代开发是在变与不变中寻求平衡,在迭代开始的时候寻求变,而在迭代开发期间不能改变,以期集中精力完成已经确定的工作。由于一次迭代的时间并不长,所以就使稳定性和易变性得到很好的平衡。在两次迭代期间改变优先级甚至功能本身,对于项目投资最大化是有益处的。从这个观点来看,迭代周期的长度选择就比较重要了,因为两次迭代之间是提供变更的机会,周期太长,变更机会就可能失去;周期太短,会发生频繁变更,而且分析、设计、编码、测试这些工作都不容易做到位。综合考虑,对于一个复杂项目,迭代周期选择4周还是有道理的。

  MIT Sloan Management Review(麻省理工学院项目管理评论)所刊载的一篇为时两年对成功软件项目的研究报告,报告指出了软件项目获得成功的共同因素,排在首位的是迭代开发,而不是瀑布过程。其它的因素是:

  1、至少每天把新代码合并到整个系统,并且通过测试,对设计变更做出快速反应。

  2、开发团队具备运作多个产品的工作经验。

  3、很早就致力于构建和提供内聚的架构。

  从这个报告中所透露出的信息告诉我们,认真研究敏捷过程对软件项目的成功是非常有意义的,它的意义在于:

  1)给开发小组的自组织提供了机会

  经典项目管理就好比一个具备中央调度服务的航空管理系统,这个系统是自治的,而且是封闭的,但现实中更庞大的系统,似乎并不属于中央调度控制系统,但也同样也是有效的。假如我们开车到某个地方,我们可以任意选择所需要的路线,我们甚至不需要准确计算停车,只要我们遵守交通法规,驾驶员可以临时根据路况改变某个转弯点,在驾驶游戏规则的框架内,依照自身最大利益做出决策。成千上万的驾驶者,并不需要中央控制和调度服务,人们仅仅在简单的交通法规的框架内,就可以完成综合起来看是更庞大的目标,很多事情从管理的角度只要抓住关键点,并不需要多么复杂的规则,往往会更有效。随着系统复杂度的提高,中央控制和调度系统面临崩溃。仔细研究交通系统的特点,我们会发现这样的系统中独立的个体在一组适当的规则下运行,并不需要设计每个个体临时变更的方案,而每个个体只需要知道目标和大致的状况,他们完全可以利用自己的聪明才智来决定自己的行为。

  2)缩短了反馈通道

  敏捷过程有效运作的另一个原因是,它极大的缩短了用户与开发者、预测目标与实施状况、投资与回报之间的反馈回路。在面对不断变化的市场、业务过程以及不断发展的技术状态的时候,便需要有一种方法在比较短的时间内发展完善。事实上,所有的过程改进都不同程度的使用着戴明循环,以研究问题、测试解决方案、评估结果,进而根据已知的事实来进行改进,这就称之为基于事实的决策模式,我们都知道,这比前端预测的决策方式更加有效。

  3)易于集思广益

  敏捷过程能有效应用的另一个原因在于,它可以就一个问题集思广益。我们的经验告诉我们当一个问题发生的时候,总有某些人员知道问题所在,但他的观点却遭到忽视。例如航天飞机在起飞阶段发生爆炸,事后分析出了各种原因,但这种调查也提供给我们一个惊人的事实,就是部分工程师早就意识到这些潜在问题,却无法说服他人重视这个担忧。对这些事实的深入思考,促使我们研究我们应该采取何种管理系统,使前线工作人员的经验、观点及担忧得到充分的重视呢?

对敏捷开发的误解

  误解一:敏捷对人的要求很高

  很多人在尝试实施敏捷时说:敏捷对人的要求太高了,我们没有这样的条件,我们没有这样的人,因此我们没法敏捷。可是,敏捷对人的要求真的那么高么?软件归根到底还是一种创造性活动,开发人员的技术水平和个人能力对软件的质量还是起着决定性的作用,各种过程与方法只是帮助开发人员、测试人员等角色能够更好的合作,从而产生更高的生产力。不管用什么方法,开发人员的水平永远都是一个主要的因素。

  从另一个角度来看:过程和方法究竟能帮开发人员多大忙?对于技术水平较低的开发人员,敏捷方法和传统方法对他的帮助是差不多的,因此看不到显着的效果,甚至有些时候还有反效果;而随着开发人员技术水平的提高,敏捷方法能够解开对人的束缚,鼓励创新,效果也会越来越显着。

  敏捷对人的要求并不高,而且会帮助你培养各种所需的能力,当然前提是你处在真正敏捷的环境中。

  误解二:敏捷没有文档,也不做设计

  这个误解从XP开始就没有停止过,XP鼓励“在非到必要且意义重大时不写文档”。这里面提到的“必要且意义重大”是一个判断标准,并不是所有的文档都不写。例如,用户手册是不是“必要且意义重大”?这取决于客户的要求,如果客户不需要,那就不用写,如果客户需要,就一定要写;再如,架构设计文档要不要写?复杂要写,不复杂不用写。通常架构设计只需要比较简单的文档,对于有些项目,一幅简单的UML图就够了。因此,写不写,怎么写,都要根据这个文档到底有多大意义,产出和投入的比例,以及项目的具体情况决定。实际操作时可以让项目组所有人员表决决定,尽量避免由某一个人(比如lead)来决定。

  至于设计,XP奉行的是持续设计,并不是不设计。这实际上是将设计工作分摊到了每天的日常工作中,不断的设计、改善(重构),使得设计一直保持灵活可靠。至于编码前的预先设计,Kent Beck等人确实实行着不做任何预先设计的开发方式,但是对于我们这些“非大师”级开发人员,必要的预先设计还是需要的,只是不要太多,不要太细,要有将来会彻底颠覆的准备。

  误解三:敏捷好,其他方法不好

  有些人一提到敏捷就大呼好,只要是敏捷的实践就什么都好,而提到CMMI等方法就大呼不好,不管是什么只要沾上边就哪里都不好,似乎敏捷和其他方法是完全对立的。牛顿说过,我是站在了巨人的肩膀上。敏捷同样也吸取了其他方法论的优点,也是站在了巨人的肩膀上,敏捷依然保持了很多历史悠久的实践和原则,只是表现方式不同罢了。

  从另一个方面来看,方法本没有好环,好与坏取决于是否适合解决你的问题。每一种方法都有他最善于解决的问题和最佳的发挥环境,在需求稳定、软件复杂度相对不高的时代,瀑布模型也可以工作的很好,而敏捷恰好适用于变化快风险高的项目 - 这恰恰是现在很多项目的共性。

  因此选择一个方法或过程,并不是根据它是否敏捷,而应根据它是否适合。而要了解一个东西是否适合,还是要尝试之后才知道,任何没有经过实践检验的东西都不可信。

  误解四:敏捷就是XP(极限编程),就是Scrum

  XP 和Scrum只是众多敏捷方法中的两种,还有很多其他的敏捷方法。龙生九子各个不同,敏捷的这些方法看起来差别也是很大的,可是他们之所以被称为敏捷方法,就是因为他们背后的理念和原则都是相同的,这个原则就是《敏捷宣言》。学习敏捷不仅仅要学习实践,还要理解实践后的原则,不仅要理解怎么做,还要理解为什么这么做,以及什么时候不要这么做。

  即使将XP或Scrum完全的应用的你的项目中,也未见得就能成功,适合别人的东西未必就适合你。敏捷的这些实践和方法给了我们一个起点,但绝对不是终点,最适合你的方式还要由你自己在实际工作中探索和寻找。

  误解五:敏捷很好,因此我要制定标准,所有项目都要遵循着个标准

  没有哪两个项目是一样的,客户是不一样的,人员是不一样的,需求是不一样的,甚至没有什么可能是一样的。不一样的环境和问题,用同样的方法解决,是不可能解决的好的。方法是为人服务的,应该为项目团队找到最适合他们的方法,而不是先确定方法,再让团队适应这个方法。因此也不存在适合所有项目的统一的方法。任何企图统一所有项目过程的方法都是不正确的。

  同时,对于同一个团队,随着项目的进行,对需求理解的深入,对技术理解的深入,一开始适合项目的过程和方法也会渐渐的不适合。这时候也需要团队对过程进行及时的调整,保证项目的质量和效率。敏捷是动态的,而非静止不变的,因为这个世界本身就是变化的,在变化的世界使用不变的方法,是不现实的。银弹从来就没有过,在有限的将来也不会存在。

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

敏捷开发 宣言 思想 认识误区 的相关文章

随机推荐

  • docker K8s部署

    docker K8s部署 docker build t www aaa cn pro admin 20230202 1703 docker images docker login www aaa cn U username P passwo
  • 码云出现错误git@gitee.com: Permission denied (publickey). fatal: Could not read from remote repository. P

    第一步 重新生成ssh ssh keygen t rsa C 这里需要填写邮箱 我填写的是我的绑定主邮箱 我想其他邮箱也是可以的 只不过我没有测试 第二步 查看你生成的公钥 cat ssh id rsa pub 然后我们就可以看到我们的公钥
  • Glide:4.8.0基础使用

    参考 https blog csdn net mars314 article details 80653795 首先 添加依赖 implementation com github bumptech glide glide 4 8 0 ann
  • 微信小程序授权登陆页面

    1 在进入小程序的时候要判断是否有授权 如果没有授权 则要先授权之后 才能登陆到小程序的首页 刚开始 我把login页当作了小程序的首页 这样导致如果已经授权过 这个页面也会一闪而过 用户体验不好 捋了一下思路之后认为 应该把授权的判断放在
  • 华为OD机试 C++【 数据最节约的备份方法】

    描述 你有一堆文件需要备份 但你只有一些500MB的光盘 你的任务是弄清楚 为了备份所有文件 你最少需要多少张光盘 核心要点 每个文件的大小都是整数MB 而且不会超过500MB 文件不能被拆分来备份 给我数据 文件的大小 如 100 500
  • java基础练习题

    1变量 运算符和类型转换 1 1手动输入一个学生的成绩 对这个成绩进行一次加分 加当前成绩的20 输出加分后成绩 Scanner scan new Scanner System in System out println 请输入一个数字 i
  • [Codeforces] combinatorics (R1600) Part.5

    Codeforces combinatorics R1600 Part 5 题单 https codeforces com problemset tags combinatorics 1201 1600 1096B Substring Re
  • 【问答23】Linux移植:如何制作rootfs?

    粉丝问题 如何制作rootfs 安排 想直奔主题的 直接跳到第四章 一 分析 1 文件系统简介 理论上说一个嵌入式设备如果内核能够运行起来 且不需要运行用户进程的话 是不需要文件系统的 文件系统简单的说就是一种目录结构 由于 linux操作
  • python os.mkdir与os.makedirs递归创建目录

    os mkdir创建单层目录 usr bin python coding UTF 8 import os sys 创建的目录 path tmp home monthly daily hourly os mkdir path 0755 os
  • [ESP32C3填坑] AT指令不应答

    烧录固件 固件连接 发布的固件 ESP32 C3 ESP AT 用户指南 latest 文档 espressif com 然后选择 v2 4 2 0 ESP32 C3 MINI 1 AT V2 4 2 0 zip这个版本 再下载烧录软件 工
  • 外观模式(Facade)

    设计模式之外观模式 外观模式的作用 为复杂的系统提供高层的接口 程序这个东西总是会变的越来越大 随着时间的推移 程序中的类会越来越多 而且它们之间相互关联 这会导致程序结构也变得越来越复杂 随之也会使得我们在使用这些类之前 必须弄清楚它们之
  • 中文乱码的原因及解决方法

    1 我们常用的编码表 ASCLL 美国标准信息交换码 gt 用一个字节的7位可以表示 ISO8859 1 拉丁码表 欧洲码表 gt 用一个字节的8位来表示 GB2312 中国的中文编码表 GBK 中国的中文编码表的升级 gt 一个汉字用两个
  • TensorFlow实战练习2

    TensorFlow实现自编码器 自编码器可以使用自身的高阶特征编码自己 自编码器其实是一种神经网络 它的输入和输出是一致的 它借助稀疏编码的思想 目标是使用稀疏的一些高阶特征重新组合来重构自己 它的特点非常明显 第一 期望输入 输出一致
  • VS2019无法登陆解决办法

    文章目录 前言 1 vs登陆 2 解决 总结 前言 今天想看看c代码 打开vs2017 哦豁 登不进去 打开vs2019 哦豁 还是不行 1 vs登陆 到这里就登不进去了 2 解决 vs2019找到账户选项 将嵌入式Web浏览器改为系统We
  • Spring事务嵌套:业务场景事务2异常时需要事务2回滚事务1提交

    目录 1 改变事务2的传播方式REQUIRES NEW 2 异步调用 业务场景 业务提交审核 生成审核账单等数据 事务方法1 审核通过 业务看到账单如果没有问题就去手动审核通过 事务方法2 后期增加了一个自动审核的功能 如果账单中等等一些信
  • 【华为OD机试真题 JAVA】转骰子

    JS版 华为OD机试真题 JS 转骰子 标题 转骰子 时间限制 1秒 内存限制 262144K 语言限制 不限 骰子是一个立方体 每个面一个数字 初始为左1 右2 前3 观察者方向 后4 上5 下6 用123456表示这个状态 放置到平面上
  • 【新手教程】手把手教你搭建腾讯云服务器,图文详细教程

    目 录 本篇字数 1271 背景 服务器搭建 环境搭建 安装JDK Tomcat MySQL驱动 域名绑定 背景 暑假期间 愁着无聊但也不能荒废学业吧 毕竟以后想靠技术混口饭吃 为了实施自己的计划 特地挑了一个便宜的云服务器来用作自己的后台
  • 华为OD机试 - 计算最接近的数(Java)

    题目描述 给定一个数组X和正整数K 请找出使表达式 X i X i 1 X i K 1 结果最接近于数组中位数的下标 i 如果有多个 i 满足条件 请返回最大的 i 其中 数组中位数 长度为N的数组 按照元素的值大小升序排列后 下标为 N
  • SQL 从字符串中提取数字

    一基础使用 声明一个nvarchar类型的变量并赋值declare Name nvarchar 50 set Name 我正在123学 习22 SQL中11 的一些函数 patindex函数返回所查内容在字符串中第一次出现的内容print
  • 敏捷开发 宣言 思想 认识误区

    敏捷软件开发 Agile software Development 敏捷开发是一种软件开发方法 基于迭代和增量开发 通过自组织 跨团队 沟通协作完成开发工作 敏捷宣言的诞生 2001年2月11日到13日 17位软件开发领域的领军人物聚集在美