敏捷开发技巧_项目经理在敏捷开发中的作用敏捷开发 - CSDN
  • 敏捷开发技巧

    2009-08-10 10:18:17
    1、移除重复代码  其根本方法是把大于1次使用的代码分离成共有方法。  重构的目标应该是在不降低代码效率的基础上提高代码的复用性和质量。重构应该考虑效率、结构、代价之间的平衡。 2、把注释化为代码 ...

    1、移除重复代码

         其根本方法是把大于1次使用的代码分离成共有方法。
         重构的目标应该是在不降低代码效率的基础上提高代码的复用性和质量。重构应该考虑效率、结构、代价之间的平衡。

    2、把注释化为代码

         看到代码就能见文知义,消除无谓注释。一般注释用于说明该处的想法、算法、优劣、记录等,能用代码说明的尽量不要用注释。
         当我们要加注释的时候,我们应该再三的想想:
         注释能不能转化在代码里面,让代码跟注释一样的清晰?
         大多数情况下是能!
         每一个注释都是一个改进代码的好机会!
         包含太多注释的代码,绝对不是高质量的代码!

    3、除去代码异味

         理想情况下,我们希望一个类、方法或其他代码设计完成以后,就不用再做修改了。它们应该稳定到不用修改就能重用。

         判断代码的稳定性,我们可能会这样:先假设一些具体的情况或者需求改变了,然后来看一看,要满足这些新的需求,代码是否需要被修改?

         有个简单的方法,如果我们发现已经第三次修改这些代码了,那我们就认定这些代码是不稳定的。这方法比较“懒惰”,而且“被动”,虽然这种方法还算有效。

         还有一个简单的方法,而且“主动”。如果这段代码是不稳定的或者有一些潜在问题,那么代码往往会包含一些明显的痕迹。这些痕迹就是“代码异味”。

         普遍的代码异味:

        类别代码和switch表达式是比较普遍的代码异味。此外,还有其他的代码异味也很普遍。
        下面是大概的异味列表:
        代码重复
        太多的注释
        类别代码(type code)
        switch或者一大串if-then-else-if
        想给一个变量,方法或者类名取个好名字时,也怎么也取不好   
        用类似XXXUtil, XXXManager, XXXController 和其他的一些命名
        在变量,方法或类名中使用这些单词“And”,“Or”等等  
        一些实例中的变量有时有用,有时没用
        一个方法的代码太多,或者说方法太长
        一个类的代码太多,或者说类太长
        一个方法有太多参数
        两个类都引用了彼此(依赖于彼此)

    要移动一些类别代码和switch表达式,有两种方法:                           
        1.用基于同一父类的不同子类来代替不同的类别。                                       
        2.用一个类的不同对象来代替不同的类别。
        当不同的类别具有比较多不同的行为时,用第一种方法。当这些类别的行为非常相似,或者只是差别在一些值上面的时候,用第二个方法。

    4、保持代码简洁

        判断一个类是否需要修整,一个比较主观的方法是:看看我们会不会觉得这个类“太长了”,“太复杂了”,或者包含的概念“太多了”?如果会这样觉得的话,我们就认定这个类需要修整。

        另外一个比较简单(虽然懒惰、被动)而且客观的方法是:当发现我们已经在第二次或者第三次扩充这个类的时候,我们认定这个类药修整了。

    5、慎用继承

        Java中传递调用的中间介叫“代理(delegation)”。其实就是和继承并列的组合。

        如果一个父类描述的东西不是所有的子类共有的,那这个父类的设计肯定不是一个好的设计。

        当我们想要让一个类继承自另一个类时,我们一定要再三的检查:子类会不会继承了一些它不需要的功能(属性或者方法)?如果是的话,我们就得认真再想想:它 们之间有没有真正的继承关系?如果没有的话,就用代理。如果有的话,将这些不用的功能从基类转移到另外一个合适的地方去。

    6、处理不合适的引用(依赖)

        互相依赖也是一种代码异味,我们就认定这样的代码,是“不合适的依赖”。

    要判断一个代码是不是包含了“不合适的依赖”,共有四个方法:

       1.看代码:有没有互相依赖?

       2.认真想想:它真正需要的是什么?

       3.推测一下:它在以后的系统中可以重用吗?

       4.到要重用的时候就知道了:现在我要重用这个类,能不能重用?

    方法1跟4是最简单的方法,推荐初学者可以这样来判断。有更多的设计经验了,再用方法2跟3会好一些。

    7、将数据库访问、UI和域逻辑分离

         域逻辑,原文是叫Domain logic,“Domain logic is also called "domain model" or
           "business logic".”,即“域逻辑又称为域模型或者业务逻辑”。

         这三个不同类别的代码混在一起,会造成下面的问题:
         1.代码很复杂。
         2.代码很难重用。如果是在一个web系统中,就更难重用了。
         3.代码很难测试。每次要测这样的一段代码,我们都要建一个数据库,还要通过一个用户操作界面来测试。
         4.如果数据库表结构更改了,很多地方都要跟着更改。
         5.它导致我们一直在考虑一些低层的太细节的概念,比如数据库字段,表的记录之类的,而不是类,对象,方法和属性这一类的概念。或者说白了一点,一直在考虑怎么往数据库里面装数据,而没有了面向对象的概念,没有了建立业务模型的思维。

        因此,我们应该将这三种类别的代码分离开(UI,数据库访问,域逻辑)。

        一般而言,比较完美的方案是UI层和数据库访问层依赖于域逻辑层,那么域逻辑就能得到最大程度的复用,而这就是我们设计结构的目标(特别是大项目)。

        很多东西都属于UI层,不仅仅窗口、按钮这些,报表,Servlet,Jsp,文本控制台等等也算。搞J2EE开发的要注意,请不要在 Servlet,Jsp里面放置任何的域逻辑或者数据库访问的代码;也不要在域逻辑中调用UI的代码,如System.out.print.   

    8、以用户例事管理项目

        用户例事 User Case or User Story

        在一个系统面前,每个用户要完成同样的目标,都要做这个系统设定的例行的事,这件事情不是一个例子,所以不叫事例,这也不是故事,也不能算一段历程,而是一个例行的事。

        一个用户例事只是以客户能明白的方式,描述了一个系统的外在行为,它完全忽略了系统的内部动作。千万不要提及任何有关数据库、记录、字段之类的对客户一点意义都没有的东西。

        一开始我们可以用例事点来评估发布时间。

        为了做到更准的估计,我们希望客户给我们一段时间做些实际的开发,来测量一下我们在这段时间里面可以做多少用户例事,这段时间就叫“迭代周期”。通过迭代周期,我们可以进一步评估发布时间。

        如果不能如期完成,一种方法是我们和客户达成协议推迟发布周期,我们先选择客户认为比较重要的例事点来实现,而把相对次要的放在下一个发布周期去;另一种 方法,可以增加开发人员来满足发布期限,但是这里要注意,团队人数加倍不等于开发周期的减半,如果团队超过10个人,增加更多的人可能反而会延缓项目的进 度,项目开发周期越长,团队内的成员对整个项目的代码熟悉度越少,加上不确定的人员流动,这个项目会越来越复杂。

    9、用CRC卡协助设计

        CRC(Class,Responsibility,Collaboration),在卡里写上类名,它的职责,以及它的协作关系。

        之所以用CRC卡,因为

        1)卡片上的空间小,可以防止我们给这个类太多的职责。如果职责过多的话(比如大于4个),尝试以更抽象的方式去考虑一下,将职责划分。

        2)CRC卡主要是用在探索或者讨论类的设计阶段。如果我们觉得这个设计不好,既不用修改文档,也不用修改类图,只要把卡片丢了就行。此外,一旦设计完成,我们就可以把所有的卡丢了,它们不是用来做文档的。

        3)如果我们觉得现在的卡片不合适,之前设计的比较好,我们只要简单的把之前的卡片拿出来组合就行了。

        CRC卡主要是用来快速的组织设计。不应该花很长时间做CRC卡,也不要指望按照CRC卡的设计就一切ok。在编码的时候,肯定还会不断地调整设计。将设计和编码结合起来,我们才能做出好而有效的设计。

        一句话,CRC卡是用来帮忙清理设计的思路,它不是UML图,也不是精确的类结构图。只要我们在处理这些卡的时候不断讨论,我们设计的思路将会变得非常清楚。

    10、验收测试

         验收测试,也叫功能测试,只是测试系统的外部行为,忽略系统里面有哪些类,哪些模块。

         由于手动测试用例要花很多的时间和精力,我们希望这些测试用例可以在不需要人为干预的情况下自动运行。这样的测试,叫“自动验收测试”。

         测试代码是需要调用“正式”代码的,而“正式”代码绝对不能调用测试代码。

         测试代码应该在实现用户例事之前写。测试用力使我们软件需求的一个重要组成部分(现场客户是另一个重要部分)。作为需求的一部分,测试用例可以知道我们实 现用户例事。而现场客户的优点是,最新的信息,更有效的沟通;而测试用例的优点则是更准确,自动化的测试则可以很频繁地运行。

        测试文件不一定是个文本文件,可以是excel,也可以是html或者其他各式的文件,只要我们可以解析出来就可以了。最关键的一点是客户能够明白和操作这些测试文件。

        用测试用例防止系统走下坡路。每次我们跟客户一起建立了一个测试文件,我们都把它放在一个名为“测试队列”的文件夹里。开始的时候所有的测试文件都放在这 边。每运行通过一个测试文件,我们就将这个测试放到另外一个叫“通过”的文件夹里。之后不管是重构,还是增加新的功能,或者修改代码以后,都要将“通过” 这个文件夹里的所有测试文件跑一边。如果有测试文件通不过,证明代码有错,我们马上修改代码,让它通过。而不是将通不过的测试文件放回“测试队列”的文件 夹里。也就是说,除非是测试文件本身出了问题,否则,绝对不能把测试文件从“通过”放回到“测试队列”中去。当最终“测试队列”里面的文件都移到“通过” 队列后,系统完成了。

    11、对UI进行验收测试

         UI测试的原则是:分开测试每个UI组件。

    12、单元测试

         验收测试测试的是系统的外部行为,单元测试是测试系统的内部结构,它只测一个单元(类、甚至一个方法)。验收测试属于客户的,我们没有权利决定验收测试的 内容,我们顶多只是帮忙客户根据用户例事写出验收测试。单元测试属于我们,我们只是根据我们对这个单元的期望写出单元测试。

    13、测试驱动编程

        代码写得越复杂,我们就越担心;写得越多,我们也越担心。这时候,测试先行的方法就值得考虑了。

        测一点,写一点的好处:如果我们弄出一个bug,它会马上被发现,然后很容易定位到出错源。

        我们要在实现代码之前,保证我们的测试通不过。如果测试通过了,没有像预期中的失败了,说明我们的测试有问题。

        我们要测试代码是不是如我们预期的调用了某一个方法,我们要判断2点:1。它确实调用了我们希望它调用的方法。2。它调用时传递过去当参数的对象,应该是我们预期的对象。

        TDD(Test Driven Development)的优点:

        1,为了更容易写单元测试,我们会广泛地使用接口。这个会让单元测试代码很容易读写,因为测试代码里面没有多余的数据。

        2,因为广泛的使用接口,我们的类之间就不会耦合,因此重用性更好。

        3,写单元测试的时候,很容易就可以为一个行为写一个测试用例,让它通过,然后为另一种行为写另一个测试用例。也就是说,整个任务会被划分成很多小的任务,独立完成。

        要做什么,不要做什么:

        1,不要再测试里包含多余的数据,为此,你会用更多地使用接口和匿名类。

        2,如果你需要写一堆代码来建立测试上下文(比如数据库连接),那你绝对不要忍受这种痛苦。如果它确实发生了,那就用接口吧。

        3, 不要在两个测试里面测试了同样的东西。

        4,在写出通不过的测试之前,绝对不要写代码,除非代码非常简单。

        5,不要(至少尽量避免)一次性将所有的测试弄坏。

        6,不要一次性写太多东西,或者做一些要花费几个小时的事情。尽量将这些东西划分为更小的行为,使用TODD列表。

        7,每写完一个测试用例,在几分钟内通过它,并不是放在一边。

        6,每做一个或者一些小改动后,就要运行所有测试用例。

        9,先挑出你比较有兴趣的,或者可以从中尝到东西的任务,而不是先挑那些烦人的任务。

        10,测试调用顺序的时候,一定要使用调用日记。

        11,任何时候,脑中都要有个完整的概念。

    14、结对编程

        如果我们不懂对方在说什么,最好的办法就是让他举个例子。这是沟通(也是结对编程中)最重要的方法。

        有经验的开发人员,有时候还是可以从年青的开发人员上学到一些东西。

        交流设计的最好方法是边看代码边解释。如果还没有代码,就用图表。

        在结对编程里,一起设计是主要活动之一。除此,一起测试、一起查错也是另两个主要活动。

        在结对编程里,有着不同的知识/技能的人可以把他们的技能共享来解决一个困难的问题。经常可以交流知识和好的实践经验。开发人员会比较开心,做事也比较有信心。

        如果我们不能明白另一个人的设计意图,那最好的方法就是,写代码。让比较不明白的那个人来写。

        即使一个人在某一方面很擅长,另一个人还是有空间做一些有意义的贡献的。有经验不代表每次都能更快找到错误。每个人都可能擅长找某一方面的问题,而不擅长于其他方面的。幸运的是,两个人的“盲区”通常不会重叠。

        一起写代码也是结对编程的主要活动。

        因为结对编程两人的精力都会很集中,精神容易紧张,所以经常的休息开发效率才会更高。

        在这次结对编程以后,两个人对代码和业务都更熟悉了。如果他们中有人要去休假或者离开公司的话,另一个也可以维护。也就是说,结对编程可以减少职工离职对公司的损失。

        经常地换搭档是好事(特别是在一个新任务的开始阶段)。现在其中一个可以继续把他懂的东西教给第三个人,同时也能从第三个人身上学到另外一些。

        结对编程的好处:

        1,联合两人的知识去对付一个难题。

        2,知识互相传递。

        3,更有效的差错跟纠错。

        4,程序员都很开心。

        5,减少员工离职的损失。

        结对编程需要的一些技能:

        1,用代码解释已有的设计结构。

        2,用例子来解释。

        3,用图表来解释设计思路。

        4,如果你无法把你的设计思路表达清楚,把代码写出来。

        5,让比较迷惑的搭档来写代码,这样他就可以较好地融入你的概念。

        6,经常地休息。

        7,经常地更换搭档。

        研究表明,在一个大学的环境里,让两个人做一件事情,花费的时间比两个人分工所需的时间多15%。也就是说,我们没必要加倍。所以一方面来讲,结对编程有 很大的好处,但同时也要多花费15%的开发时间。但研究还表明,结对编程开发出来的软件,bug的数量比分工开发出来的少不止15%。单人修复bug所花 的时间,是结对的人所花时间的15-60倍。很明显,结对编程远远抵消了那多费的15%的开发时间。

        结对编程不是万灵的。因为它需要两个人不断地沟通,一起做决定,如果不能沟通或者做不了决定的话,结对编程就行不通了。下面是常见的问题,会造成结对编程无法正常工作:

        1,不情愿的配合。

        2,拒绝别人的意见,甚至攻击对方。

        3,小心翼翼有意见不敢提。

        4,怕别人觉得自己笨不敢问问题。

       注:

    开闭原则(Open Closed Principle):如果我们需要增加新的功能,我们只需要增加新的代码,而不是改变原有的。移除switch和类别代码是达到开闭原则的普遍方法.

    单一职责原则(The Single Responsibility Principle):每个类都应该只为一个理由而修改。当一个类包含许多其他功能时,很明显违反了单一职责原则。

    里斯科夫替换原则(LSP)(Subtype must be substitutable for their base types): 子类应该能够代替父类的功能。或者直接点说,我们应该做到,将所有使用父类的地方改成使用子类后,对结果一点影响都没有。或者更直白一点吧,请尽量不要用 重载,重载是个很坏很坏的主意!

    依赖反转原则(Dependency Inversion Principle ):抽象不应该依赖于具体,高层的比较抽象的类不应该依赖于低层的比较具体的类。当这种问题出现的时候,我们应该抽取出更抽象的一个概念,然后让这两个类依赖于这个抽取出来的概念。

    《重构——改善既有代码的设计》
    下面粗略地概括一下对重构的理解,也整理一下之前不是很清楚的概念。

    1、《重构》有一个很好的动机,也可以说是价值观,就是程序第一是写给人看的,而不是写给机器看的。
    根据这一价值观,其他多种利益纷至沓来,比如当程序有了良好的可读性和可理解性,程序中隐藏的Bug便很容易浮出水面,开发进度也更加顺畅,并且对于系统将来的结构变更和扩展,程序也更加具有灵活性。

    2、《重构》与《设计模式》的关系,在《设计模式》和《重构》中都有提出“设计模式为重构提供了目标”,在之前对这句话的理解总是朦朦胧胧,觉得有道理但又不是很深刻,现在觉得有两个词非常的关键:目标和目的。

    设计模式为重构提供了目标,但不是目的。

    设计模式是经过证实的在一定场景下解决一般设计问题的解决方案的核心,通过设计模式我们很好得解决了某种问题,并且便于我们思考和交流,降低沟通之间的理解误差,此外同样重要的,设计模式增强了可复用性,便于将来扩展和维护。

    而重构是对程序内部结构的一种调整,其目的是在不改变“软件之可察行为”的前提下,提高其可理解性,降低其修改成本(《重构》的名词性定义)。

    所以如果我们把软件开发比作在大海中航行,设计模式就是遍布在大海中的航标,他可以引导我们驶向目的地——高可读性、可理解性、可扩展性、可维护 性。所以设计模式是重构的目标(航标)而不是目的,设计模式可以帮助我们更好更快的抵达目的地(准确地说是无止境的),而避免触礁或偏离航向

    3、重构和优化,在之前的开发中,优化的意识要比现在(看完《重构》之后)强的多,如果遇到在一个循环中可以做多个事情的时候,决定把每件事情分开 放到单独的循环中是要鼓起很大的勇气的,而现在便可以轻松的决定,因为清晰的代码在需要性能优化时有更宽的道路可以选择,并且往往这种决定不会造成真正的 性能影响。

    《实时UML与Rational Rose RealTime建模案例剖析 》

    将实时系统、实时统一建模语言、实时系统的统一开发过程和Rational Rose RealTime建模环境有机地结合起来,以案例为基础,系统地介绍了实时系统的设计与实现。全书分为3部分,第1部分为基础篇,主要介绍实时系统的基本 概念、实时统一建模语言、实时对象约束语言和Rational Rose RealTime建模环境。第2部分为建模篇,结合实时统一建模语言和Rational Rose RealTime建模工具,介绍了实时系统的需求分析、系统设计和实现与部署。第3部分为案例篇,分析了4个典型的实时系统案例:纸牌游戏、咖啡机控制系 统、ATM自动取款机控制系统和电梯控制系统的设计与实现。案例是针对不同层次的实时系统开发人员进行设计的,同时也涵盖了实时系统设计的主要特性。

    展开全文
  • 敏捷开发的几大技巧:1、移动重复代码;2、将注解转换为代码:将注释转换为代码,让代码足够清楚到可以表示注释,如将一部分代码重构成方法,用方法名来表达注释的意思。3:除去代码异味: 第一种异味:代码用了类别代码...
    敏捷开发的几大技巧:
    1、移动重复代码;
    2、将注解转换为代码:将注释转换为代码,让代码足够清楚到可以表示注释,如将一部分代码重构成方法,用方法名来

    表达注释的意思。
    3:除去代码异味:
       第一种异味:代码用了类别代码(type code)如final int TYPERECTANGLE = 1;
       第二种异味:Shape 这个类有很多属性有时候是不用的;
       第三种异味:我们想给p1,p2 取个好一点的变量名都做不到,因为不同的情况下,它们有不同的含义:
       第四种异味:drawShapes这个方法里面,有个switch表达式。当我们用到switch(或者一大串的if-then-else-

    if)时,小心了。switch表达式经常是跟类别代码(type code)同时出现的。
        消除代码异味方法:
        针对第一种,大多数情况下,要想去掉一个类别代码,我们会为每一种类别建立一个子类.再使用就要用

    instanceof来判断对象。
        要移动一些类别代码和switch表达式,有两种方法:
        a.用基于同一父类的不同子类来代替不同的类别。
        b.用一个类的不同对象来代替不同的类别。
        
    4.保持代码简洁
    要判断一个类是否需要修整,一个比较主观的方法是:当在读一个类的代码时,看看我们会不会觉得这个类
    “太长了”,“太复杂了”,或者讲的概念“太多了”?如果会这样觉得的话,我们就认定,这个类需要修整.
    单一职责原则(The Single Responsibility Principle)认为:每个类都应该只为一个理由而修改.
    5.慎用继承:
    当我们想要让一个类继承自另一个类时,我们一定要再三的检查:子类会不会继承了一些它不需要的功能(属性或

    者方法)?如果是的话,我们就得认真再想想:它们之间有没有真正的继承关系?如果没有的话,就用代理。如果

    有的话,将这些不用的功能从基类转移到另外一个合适的地方去。
    如果一个父类描述的东西不是所有的子类共有的,那这个父类的设计肯定不是一个好的设计。

    里斯科夫替换原则(LSP)表述:Subtype must be substitutable for their base types. 子类应该能够代替父类的
    功能。或者直接点说,我们应该做到,将所有使用父类的地方改成使用子类后,对结果一点影响都没有。或者更
    直白一点吧,请尽量不要用重载,重载(类中可以相同的方法名不同的参数)是个很坏很坏的主意。

    6处理不合适的依赖
      怎么判断是“不合适的依赖”
      方法1:
    一个简单的方法就是:我们先看一下这段代码里面有没有一些互相循环的引用。比如,ZipMainFrame引用了
    ZipEngine这个类,而ZipEngine又引用了ZipMainFrame。我们管这样的类叫“互相依赖”。互相依赖也是一种代
    码异味,我们就认定这样的代码,是“不合适的依赖”。
      方法2:
    另一个方法比较主观:在检查代码的时候,我们问自己:对于它已经引用的这些类,是它真正需要引用的吗?
      方法3:
    第3 种方法也很主观:在设计类的时候,我们先预测一个以后可能会重用这个类的系统。然后再判断,在那
    样的系统中,这个类能不能被重用?如果你自己都觉得以后的系统不能重用这个类的话,你就断定,这个类包含
    “不合适的依赖”了。
       方法4
    第4 个方法比较简单而且客观了。当我们想在一个新系统中重用这个类,却发现重用不了时,我们就判断,
    这个类包含了“不合适的依赖”。
    解决方法:除掉其中的依赖类,利用接口来处理。
    依赖反转原则(Dependency Inversion Principle )表述:抽象不应该依赖于具体,高层的比较抽象的类不应该
    依赖于低层的比较具体的类。当这种问题出现的时候,我们应该抽取出更抽象的一个概念,然后让这两个类依赖
    于这个抽取出来的概念
    7、 将数据库访问,UI和域逻辑分离
      先抽取出数据库访问层,然后将领域逻辑将表示层也分离。
    8、以用户例事管理项目  (也就通常我们所说的用例)
       一件用户通过系统完成他一个有价值的目标(买一罐饮料)的事。这样的过程就叫“用户案例(user case)”或

    者“用户例事(user story)”。也就是说,上面我们的客户所说的话,就是在描述一个用户例事(user story)。
    9、 用CRC卡协助设计
        写上了类名,它的职责,以及它的协作关系,我们管这样的卡片叫“CRC卡”。CRC就是Class,Responsibility

    和Collaboration的简称
    10、 验收测试
    11、 对UI进行验收测试
    12、 单元测试
    13、 测试驱动编程
    14、 结对编程
          结对编程的好处:
        联合两人的知识去对付一个难题。
        知识互相传递。
        更有效的查错跟纠错。
        程序员都很开心。
        减少员工离职的损失。
         结对编程需要的一些技能:
        用代码解释已有的设计结构。
        用例子来解释。
        用图表来解释设计思路。
        如果你无法把你的设计思路表达清楚,把代码写出来。
        让比较迷惑的搭档来写代码,这样他就可以较好的融入你的概念。
        经常的休息。
        经常的更换搭档

    展开全文
  • 本文描述了敏捷开发技巧:如何以用户故事管理项目. [bitsCN_com] 什么是用户故事(user story) 假定这个项目的客户是个饮料自动售货机的制造商。他们要求我们为他们的售货机开发一款软件。我们可以
    
    	导读: 
      摘要:
      一件用户通过系统完成他一个有价值的目标(买一罐饮料)的事。这样的过程就叫“用户案例(user case)”或者“用户故事(user story)”。本文描述了敏捷开发的技巧:如何以用户故事管理项目. [bitsCN_com]
      什么是用户故事(user story)
      假定这个项目的客户是个饮料自动售货机的制造商。他们要求我们为他们的售货机开发一款软件。我们可以找他们的市场经理了解这个软件的需求。
      因此,我们的客户就是他们的市场经理。谈需求的时候,有一回他这样说:“用户往售货机每塞一个硬币,售货机都要显示当前该客户已经投了多少钱。当用户投的钱够买某一款饮料时,代表这款饮料的按钮的灯就会亮。如果那个用户按了这个按钮,售货机就放一罐饮料到出口,然后找零钱给他。”
      上面的话描述的是一件事情,一件用户通过系统完成他一个有价值的目标(买一罐饮料)的事。这样的过程就叫“用户案例(user case)”或者“用户故事(user story)”。也就是说,上面我们的客户所说的话,就是在描述一个用户故事(user story)。
      (我解释一下为什么用故事这个词,没兴趣也可以忽略。在一个系统面前,每个用户要完成同样的目标,都要做这个系统设定的例行的事,这件事情不是一个例子,所以不叫事例,这也不是故事,也不能算一段历程,而是一个例行的事。)
      如果我们想要记下这段用户故事,我们可能会用这样的格式:
      中国_网管联盟bitsCN.com
      名称:卖饮料
      事件:
      1. 用户投入一些钱。
      2. 售货机显示用户已经投了多少钱。
      3. 如果投入的钱足够买某种饮料,这种饮料对应的按钮的灯就会亮。
      4. 用户按了某个亮了的按钮。
      5. 售货机卖出一罐饮料给他。
      6. 售货机找零钱给他。
      注意到,一个用户故事里面的事件可以这样描述:
      1. 用户做XX。
      2. 系统做YY。
      3. 用户做ZZ。
      4. 系统做TT。
      5. ...
      用户故事只是描述系统的外在行为
      一个用户故事只是以客户能够明白的方式,描述了一个系统的外在行为,它完全忽略了系统的内部动作。比如,下面有下划线的那些文字,就属于不应该出现在用户故事中的系统内部动作:
      1. 用户投入一些钱。
      [bitsCN.Com]
      2. 售货机将塞进来的钱存在钱箱里,然后发送一条命令给屏幕,屏幕显示目前已经投入的金额。
      3. 售货机查询数据库里面所有饮料的价格,判定钱足够买哪些饮料,对于钱足够买的那些饮料,对应的按钮的灯就会亮起来。
      4. 用户按下一个亮起来的按钮。
      5. 售货机卖出一罐饮料给用户,然后将数据库里面该饮料的存货数量减1。
      6. 售货机找零钱给用户。
      不管是口头描述的,还是书面形式,这样的内容是描述用户故事时一个很常见的错误。特别的,千万不要提及任何有关数据库,记录,字段之类的对客户一点意义都没有的东西。
      评估发布时间
      用户故事是用来干嘛的?假定客户希望在50天内递交这个系统。我们做得了吗?为了解答这个问题,我们就要在项目开始的阶段,试着找出所有的用户故事,然后评估一下,每一项历程需要多长的开发时间。可是,怎么评估呢?
      比如,我们现在收集了下面这些用户故事:
      卖饮料:如上面所说的。 DL@bitsCN_com网管软件下载
      取消购买:在投入了一些钱后,用户可以取消购买。
      输入管理密码:授权的人可以输入管理密码,然后增加存货,设定价格,拿走里面的钱等等。
      补充饮料:授权的人可以在输入管理密码后增加存货。
      取出钱箱里的钱:授权的人在输入管理密码后,可以取出钱箱里的钱箱里面的钱。
      安全警报:有些事情经常发生的话,系统会自动打开安全警报。
      打印月销售报表:授权的人可以打印出月销售报表。
      然后找出里面最简单的用户故事(这里的“简单”,意思是说实现周期最短)。我们不一定非常精准的判断哪个最简单。只要挑出你觉得最简单的就行了。比如,我们觉得“输入管理密码”是最简单的用户故事。然后我们判断说,这个用户故事算1个“故事点(story point)”。
      
      用户故事 故事点
      卖饮料 [bitsCN.Com]
      取消购买
      输入管理密码 1
      补充饮料
      取出钱箱里的钱
      安全警报
      打印月销售报表
      不过一般我们不会列出清单,而是做出一堆卡片贴在墙上,每张卡片记录一个用户故事,然后将故事点写在卡片上面:
      11J3150344F21N6.jpg
      
      这样的一张卡片就叫“故事卡(story card)”。

    本文转自
    http://www.bitscn.com/java/base/200709/110072.html
    展开全文
  • 1,提要 软件开发是一个系统工程,包括最初的可行性分析、再到设计、开发、测试、维护等整个生命周期。在这个过程中某些阶段的失误或说是变化,都可能增加...传统瀑布模式和新型的敏捷开发就是其中最常用的方法,后

    1,提要
    软件开发是一个系统工程,包括最初的可行性分析、再到设计、开发、测试、维护等整个生命周期。在这个过程中某些阶段的失误或说是变化,都可能增加整个软件项目的风险。
    如何在保证效率的基础上还能安计划、保证质量的完成软件项目?于是产生了软件开发的一些方法,这个方法不是指具体有编码阶段的各种设计模式和技巧,而是在整个软件开发策略层面的方法。
    传统瀑布模式和新型的敏捷开发就是其中最常用的方法,后面着重讨论敏捷开发的优缺点和敏捷开发的基础知识。
    2,常用的开发模式
    (1)传统的瀑布式开发,也就是从需求到设计,从设计到编码,从编码到测试,从测试到交付大概这样的流程,要求每一个开发阶段都要做到最好。特别是前期阶段,设计的越完美,提交后的成本损失就越少。下面就是典型的瀑布模型。


    认识敏捷开发
    (3)原型模型,原型化模型第一步就是创建一个快速原型,能够满足项目干系人与未来的用户可以与原型进行交互,再通过与相关干系人进行充分的讨论和分析,最终弄清楚当前系统的需求,进行了充分的了解之后,在原型的基础上开发出用户满意的产品。
    (3)螺旋模型,将瀑布模型和快速原型模型结合,并特别强调项目风险。通常分为四个阶段组成:制定计划、风险分析、实施工程和客户评估。一般第一个原型只是双方交流的参考,随着后面的版本完善,最终达到目标。比较适合大型项目。
    (2)新型的敏捷开发,即迭代式开发,不要求非常完美的需求分析、设计、文档,而是在最短时间内完成一个框架,然后不断迭代,不断测试,直至交付。
    但它并不是不需要文档,不需要从需求、设计、开发、测试这样一个过程,在每个迭代过程中仍然需要做这样的事情。
    但是敏捷开发更加注重人的因素,不像瀑布式开发那样,由专门的需求人员采集用户需求,由设计师完成设计文档。敏捷开发每个人都是需要了解项目的需求,并不断的进行小会议,不断的测试修改,直到提交。
    敏捷开发则是以测试驱动开发,而瀑布式开发是以文档驱动开发。
    下图是Scrum(敏捷开发的一种)敏捷开发模式


    认识敏捷开发
    3,传统开发模式和敏捷开发的优缺点
    主要对比比较常用的瀑布模型和敏捷开发。
    (1)瀑布式开发:
    a.讲求阶段明确,严格把软件项目的开发分隔成各个开发阶段:需求分析,要件定义,基本设计,详细设计,编码,单体测试,结合测试,系统测试等。使用里程碑的方式,严格定义了各开发阶段的输入和输出。如果达不到要求的输出,下一阶段的工作就不展开。 软件生命周期前期造成的Bug的影响比后期的大的多。
    b.特别强调文档,在开发的后期才会看到软件的模样。在这种情况下,文档的重要性仿佛已经超过了代码的重要性。
    c.流水式的开发,瀑布模型把开发人员定义为流水线上的工人。由于各阶段的开发人员只能接触到自己工作范围内的东西,所以对客户需求的理解程度高低不等。对于客户需求变更,编码人员会比设计人员更容易产生很强的抵触情绪。当然好的方面就是按一定规范开发,如果有人员流失,短时间内可以补上去,除了核心的东西有文档参考外,开发过程本身就是在一定框架内的。
    d.进度一目了解,瀑布模型产生的管理文档(计划书,进度表)等,能让不太了解该项目的人也能看懂项目的进度情况(只有能看懂百分比就行),很适合向领导汇报用。所以管理人员比较喜欢瀑布模型,但是开发人员不喜欢,因为它束缚了开发人员的创造性。
    (2)敏捷开发
    a.唯快不破,敏捷即是快之意,不仅思维快节奏,而且行为也是快节奏,因上受到当今快节奏社会的喜爱。
    b.以人为本,和瀑布开发对应的文档为主来说,在敏捷开发中更强调人,在细节开发上个人可以发挥主观性,使用自己善长的技术和模式开发,而非机器式的开发,容易激发团队成员兴趣和创造力。除了项目参与者,人的因素中更考虑到与客户的沟通。每个成员都需要从沟通中,会议交流中,不断实现迭代。
    c.结果第一,不强调文档,突破束缚,软件的最终结果才是重点,文档等都是为软件开发本身服务的,完成了一个优秀的、质量可靠的软件才是敏捷开发的重中之重。
    d.迭代开发,迭代是敏捷开发的核心,不断迭代测试的过程,实际上就是精益求精的过程,正和现在这个社会的工匠精神相吻合。
    e.整合不易,快速迭代,就需要分割整体业务,对于复杂的客户需求,如何兼顾分割与整体,并不容易,这个需要在项目设计之初考虑到。
    4,敏捷开发管理方法
    敏捷开发的管理方法有很多种,比较广泛应用的有XP、Scrum等。既然都是敏捷开发,他们都有共同点,强调高速响应变更、以人为主重视团队成员自身发展,倾向采用迭代式的软件开发生命周期模型。
    敏捷开发中,XP和Scrum的区别:
    a.迭代周期不同,XP的每个Sprint(冲阶)的长度大概为1~2周,而Scrum为2~4周。
    b.迭代周期内专一性不同,XP在一个迭代中,如一个User Story(用户素材,也就是一个用户需求)还未实现,可以考虑另外需求替换,原则是时间当量相等。而Scrum不允许这样,一旦迭代开发会毕,任何需求不允添加进入,并有Master严格把关,使团队不受干扰。
    c.User Story优先级机制不同,XP必须遵守优先级(当然需要先确实优先级),Scrum更灵活,可以不遵循优先级。比如依赖关系中,虽然 US-A高于US-B,但由于要完成A需依赖B,则需要先开发B。
    d.实施中是否采用工程方法问题两者做法不同,Scrum这点上没有工程实践处方,体现的是以人为本,自我创造;而XP必须严格按TDD,自动测试,结对编程,简单设计,重构等约束团队,似乎看起来XP的方式束缚了团队,但需要看这个约束的程度,过细则会让人感觉与“以人为本,自我创新”思想不符,但优点就是一定程度上的规范更有利于保证软件质量。
    一个让人困惑的矛盾, 因为xp的理念,结合敏捷模式,表达给团队的信息是“你是一个完全自我管理的组织, 但你必须要实现TDD, 结对编程, ...等等”
    通过区别,看出: Scrum非常突出Self-Orgnization, XP注重强有力的工程实践约束
    5,总结
    通过了解传统瀑布开发模式和新型敏捷开发模式的差异,理解敏捷开发的在现在快节奏时代有更好的适用性:唯快不破,以人为本。

    展开全文
  • 关键任务系统和敏捷开发 关键任务系统对人类安全有重大影响。 这些系统的故障成本可能非常高,不仅造成财务损失,有时还导致人身伤亡。 将敏捷方法应用到其严格而复杂的开发中,可以帮助防止失败,提高质量,提供...
  • ”一位资深自由职业者的10点建议》收到不少读者的反馈,许多开发团队都在做敏捷,不得不进入「异地敏捷开发」模式,也遇到了一些问题。今天这篇,就聊聊异地敏捷开发团队,如何提升效率。 异地敏捷开发,又...
  • 敏捷开发和详细设计

    2013-03-28 10:23:57
    的软件周期来进行,随着敏捷开发方法和敏捷开发工具和技巧的发展,软件过程中的 一些步骤被新的开发颠覆甚至忽略。 模块耦合度低的项目,开发人员往往在概要设计、项目结构建立之后,就拿着需求文档在做各自的子...
  • 敏捷开发是个啥

    2019-04-01 10:18:32
    今天来篇正经的,从软件工程的角度来聊一聊敏捷开发模式,文章分两部分: 第一部分通过举例和对标其他行业聊聊软件开发模型的发展演进。 第二部分聊聊敏捷的核心思想。 敏捷开发是互联网界比较流行的软件开发模式...
  • 敏捷开发的艺术pdf

    2019-07-27 19:49:10
    本书为那些正在考虑应用敏捷开发来构建有价值软件的人们提供了实用的指导。现在已经有大量的书籍描述敏捷开发是什么或者为什么它能帮助软件项目成功,但很少有哪一本书能把针对开发者、管理者、测试者和客户的信息...
  • 关于敏捷开发

    2018-01-18 09:11:59
    敏捷开发被越来越多的创业者奉为最适合初创公司的开发方法,可是在实际运用中,敏捷开发给我带来的是一个又一个的坑,如果没有对这种开发方法更深层的掌控,可能会打乱你的产品工作,得不偿失。 经过一段时间的沉淀...
  • 敏捷开发的必要技巧完整版》 有个超级清晰的PDF版,好用,搜罗之。
  • 简单的说下敏捷开发的一些知识: 敏捷开发以用户的需求进化为核心,采用迭代、循序渐进的方法进行软件开发。在敏捷开发中,软件项目在构建初期被切分成多个子项目,各个子项目的成果都经过测试,具备可视、可集成...
  • .NET进入了生态化的新纪元,开发思路和开发理念都需要革新,是选择也是机遇,.NET程序员的好日子终于要来啦!
  • 摘要: 文章背景,来自于群内周五晚上的一次头脑风暴式的思维... 在敏捷开发中,软件项目在构建初期被切分成多个子项目,各个子项目的成果都经过测试,具备可视、可集成和可运行使用的特征。 换言之,就是把一个...
  • hursing所在的公司推行敏捷开发有两年多了,其中最让人直接感受到的就是scrum晨会。从生搬硬套到过程创新,令大家由抵触变成积极响应,这个过程真的很花费心思。 09年12月,hursing开始在自己的团队推行晨会。当时...
  • 阿里妹导读:敏捷开发不仅靠流程和技巧,更需要企业文化的支撑。今天借“敏捷开发”的话题,与大家探讨一个更深层的问题:工程师如何在控制性和创造性中找到平衡点?生产的严谨和创造的不严谨性怎么解决?本文的作者...
  • Scrum敏捷开发流程主要包扩三个角色、四个会议和个三物件。 三个角色 Scrum团队中包括三个角色,他们分别是产品负责人、开发团队和 项目的直接管理者(Scrum Master)。 Scrum 团队是自组织、跨职能的完整...
  • 敏捷开发是一种以人为核心、迭代、循序渐进的开发方法。在敏捷开发中,软件项目的构建被切分成多个子项目,各个子项目的成果都经过测试,具备集成和可运行的特征。换言之,就是把一个大项目分为多个相互联系,但也可...
  • 敏捷开发也是顺应市场的对价值的诉求和日益复杂的业务而产生的方法论,敏捷开发是追求高质量软件的方法论和过程。 本文将和大家一起探讨软件质量的含义,以及敏捷开发中如何进行高质量软件的
  • 笔者正在学习《软件工程-实践者的研究方法...敏捷可以应用于任何一个软件过程(沟通、策划、建模、构建和部署),过程的设计应该使项目团队适应于任务,并且使任务流水线化,在了解敏捷开发方法的流动性的前提下进行...
1 2 3 4 5 ... 20
收藏数 14,570
精华内容 5,828
关键字:

敏捷开发技巧