zoukankan      html  css  js  c++  java
  • 敏捷软件工程(agile software development) VS传统软件工程(traditional software development)

    敏捷软件工程(agile software development) VS传统软件工程(traditional software development)
         Agile principle
        The Agile Manifesto is based on twelve principles(敏捷开发12原则)
        1. Customer satisfaction by early and continuous delivery of valuable software
        2. Welcome changing requirements, even in late development
        3. Working software is delivered frequently (weeks rather than months)
        4. Close, daily cooperation between business people and developers
        5. Projects are built around motivated individuals, who should be trusted
        6. Face-to-face conversation is the best form of communication (co-location)
        7. Working software is the principal measure of progress
        8. Sustainable development, able to maintain a constant pace
        9. Continuous attention to technical excellence and good design
        10. Simplicity—the art of maximizing the amount of work not done—is essential
        11. Best architectures, requirements, and designs emerge from self-organizing teams
        12. Regularly, the team reflects on how to become more effective, and adjusts accordingly
      Manifesto for Agile Software Development
        1.dividuals and interactions over processes and tools
        2.rking software over comprehensive documentation
        3.stomer collaboration over contract negotiation
        4.sponding to change over following a plan

    目录:

    <1>敏捷软件工程(agile software development)的理解

    <2>传统软件工程(traditional software development)的理解

    <3>敏捷软件工程的优势(advantages)和劣势(disadvantages)

    <4>传统软件工程的优势(advatnages)和劣势(disadvantages)

    <5>敏捷软件工程和传统软件工程的对比

    <6>敏捷软件工程的现状和传统软件工程的现状

    <7>参考文献与引用插图

    注意:

    (1)引号中均为引用文献,

    (2)中括号会注明叙述的理论的来源文献

    <1>敏捷软件工程(agile software development)的理解 

            一提到敏捷开发,很多人就想到了极限编程(Extreme Programming 简称XP)或者scrum等开发流程,实际上,敏捷(agile)开发不是指某一种具体的开发方式,开发框架或者开发流程,而是一种价值观,一种软件的开发思想。

           敏捷开发的定义:"敏捷开发(Agile Development)是一种以人为核心、迭代、循序渐进的开发方法"。敏捷软件开发介绍了一套原则通过团队内的协同努力和同时跨越多个职能,来解决需求和发展解决方案,。它提倡适应性规划,进化发展,提前交付产品,并不断改进,它鼓励快速,灵活应对变化【1】。敏捷开发最突出的两个特点,一个是以人为本(以程序员为本),另外一个就是动态的开发方式。这两个特点能够将整个团队的积极性调动起来。如果我们纯粹从程序员的角度出发,那么敏捷开发无疑是最棒的。在敏捷开发的指导思想和原则下,有很多具体的开发方式:(A)极限开发(Extreme Programming)方式(B)Scrum方式(C)精益软件开发(Lean Software Development)方式(D)特征驱动开发(Feature Driver Development)方式等众多方式。

         但无论是哪种方式都有共同的特点。(1)迭代式开发:开发过程不再像传统的软件工程那样将整个开发过程视为一个整体,而是将开发过程分成很多个迭代周期,最短甚至可以不到一周就可以完成一个迭代周期,长一些也不过几周。(2)增量交付,持续集成,用户反馈推动产品开发:不是在最后才提交整个工程,而是多次提交,这样会避免出现最终产品和客户的预期相差太大,最终使得客户不断要求团队修正,使得整个项目停滞不前,无法完成最终交付。敏捷开发则将整个工程分成很多状态逐步提交逐步提交,这里用一个流程来描述。其中每个阶段的产品都是能够运行的产品,在每个阶段都可以进行适当的调整,并不断添加功能最终达到客户预期。可以看到这样的话,开发团队在整个开发流程中,都有客户参与,当产品脱离客户预期的时候也可以实时进行修改,换句话说是客户参与到了整个项目的开发之中。流程图如下

     

     

                                                                                                             【图1】

            到底客户参与度在敏捷开发有多重要?最好的情况是客户和开发人员在同一个房间中工作,次一点的情况是客户和开发人员的工作距离在100米以内,距离越大则客户越难融入到真正的开发之中,如果客户始终和开发团队只能保持电话和视频联系,那么客户很难融入到整个项目中【2】。
    (3) 开发团队自我管理。拥有一个积极的、自我管理的、具备自由交流风格的开发团队,是每个敏捷项目必不可少的条件。"人是敏捷开发的核心。敏捷开发总是以人为中心建立开发的过程和机制,而非把过程和机制强加给人"。也就是说,传统软件工程是给你一份文档,你照着文档进行项目开发就可以了,这里开发团队更多的是作为一种执行机器,这就要求开发团队能够正确及时的完成文档中规定的每一个细节,一旦有一个细节出错,就很可能最终导致整个项目无法按时提交。
    为了更加详细的介绍敏捷开发,我在这里介绍最流行的XP(Extreme Programming)模式,XP是由一系列相互依赖的实践所组成。相比于其他的敏捷软件开发模式,XP注重强有力的工程实践约束,(在这点上属于敏捷开发中偏向传统软件开发的一个模式)

    XP有以下十个比较简单理解的特征【3】
    (1)客户作为团队成员(Whole Team)
    内容:客户作为开发团队中的一员从而指引整个项目的前进。
    (2)用户素材(User Stories)
    内容:软件开发必须要知道项目需求,但具体知道到什么程度是一个很重要的问题。开发人员并不需要知道非常具体的细节,只需要知道存在这样的细节,这里举一个例子,当我们在开发网站时,网页A具有一个功能,在XP开发中,我们只需要知道这个网页需要某一种形式体现出这个功能,而不需要知道到底是哪一种具体的形式,在离实现需求很远的时候我们就关注特定的需求,往往会导致我们做很多的无用功,换句话说我们通过和客户的反复交流,需要知道的是存在那些细节,以及这些细节的分类,也就是说我们需要知道需求的框架和一些注意事项,不必将注意力放在某一个非常具体的细节上。将若干需求分成很多个优先级,然后优先实现等级高的需求,XP必须按照优先级来实现需求。
    用户素材是关于当前需求谈话的“助记符”,是一个计划工具。在这里,客户提交需求,开发团队根据用户所提的需求,计算实现代价和优先级,最后生成用户素材,然后交给客户,然后客户根据用户素材来安排实现需求的时间。
    (3)短迭代周期(ShortCycles)
    内容:每两周交付一次可以工作的软件,XP团队会创建一个计划来规划随后6次迭代的内容,一次发布需要3个月,发布计划是一组由客户根据开发人员所给出的预算,选择的,排好优先级的用户素材所组成。

    (4)验收测试(Acceptance Tests)
    内容:验收测试用来验证系统按照客户指定的行为运转。
    (5)结对编程(Pair Programming)
    内容:两名程序员共同使用一台电脑进行开发,一名程序员输入代码,另外一名程序员同时检查代码的正确性以及提出优化的地方。由于两名程序一直在共同工作使得他们对程序的理解差不多,因此可以轮流掌握电脑进行开发,最终的代码属于他们两人工作的共同产物。
    (6)测试驱动的开发方法(Test-Driven Development TDD)
    内容:以java代码为例,我们是使用Junit进行单元测试,对需求编写测试用例,如果测试失败,则说明该需求的主要部分还未完成,然后编写代码直至测试样例通过。用图来表示这一特点。

                                                                     【图2】
    (7)集体所有权(collective ownership)
    内容:结对编程中的每一对修改或删除任何一个程序模块的权限(当然必须确保更改后的正确性),没有任何一个模块是只有一个程序员单独负责的,也就是说每个程序员都了解其他的模块,而不是仅局限在一下部分。
    (8)可持续的开发速度(Sustainable Pace )
    内容:这里要强调一点,虽然整个工程被拆分为多次迭代,但只并不意味着,将整个项目有马拉松长跑变为加速短跑,团队为了保持精力和开发热情,不能图一时之快而加班完成项目,XP的规则是不允许团队加班工作【4】。好吧,这一点确实以人为本了。
    (9)计划游戏(The Planning Game)
    内容:用来划分业务人员和开发人员之间的职责。
    (10)简单设计(Sample Design)
    内容:考虑最简单的实现方案,只为眼前的工程服务,消灭重复代码。
    还有两个比较特殊的特征:
    分别是
    (11)重构(refactoring)
    重构定义:重构是一种不改变代码外在行为的前提下,对代码提出修改,改进程序的内部结构,最终使得整个程序的架构更加合理【5】。或许在最初设计的时候,我们有一个很好的代码框架,但随着代码的维护和许多功能的添加,代码的结构会逐渐退化混乱。往往在以下几个方面进行重构:
    1.重命名:对类,接口,方法,属性等重命名,以使得更易理解
    这里举一个,我在程序设计中碰到的一个问题:
    我在开始时将代码写成

    class 类名{
    double a1[400 + 1];
    double z2[40];
    double a2[40 + 1];
    double z3[10];
    double a3[10];
    double Y[10];
    double weight1[400 + 1][40];
    double weight2[40 + 1][10];
    double deltaWeight1[400 + 1][40];
    double deltaWeight2[40 + 1][10];
    double error;//消耗函数结果值
    double errorRate;//训练集的错误率
    .......................................................
    }
    //这里的400代表输入参数,40代表隐含参数,20代表输出参数,改的地方太多了,就决定重构一下。

    后来我的参数个数发生变化后,以为涉及到的地方太多,就将代码重构了一下,变为了

    #define inputLayerNum 400
    #define hiddenLayerNum 40
    #define outputLayerNum 
    class 类名{
    double a1[inputLayerNum + 1];
    double z2[hiddenLayerNum];
    double a2[hiddenLayerNum + 1];
    double z3[outputLayerNum];
    double a3[outputLayerNum];
    double Y[outputLayerNum];
    double weight1[inputLayerNum + 1][hiddenLayerNum];
    double weight2[hiddenLayerNum + 1][outputLayerNum];
    double deltaWeight1[inputLayerNum + 1][hiddenLayerNum];
    double deltaWeight2[hiddenLayerNum + 1][outputLayerNum];
    double error;//消耗函数结果值
    double errorRate;//训练集的错误率
    .... ......................................
    }

    优化后的代码可读性提高了,而且如果要修改参数的话,只需要修改宏就可以了。
    2.抽取代码:将方法内的一段代码抽取为另一个方法,以使得该段代码可以被其他方法调用,这是重构中很重要很常用的,此举可以极大的精炼代码,减少方法的代码行数。即使只有被重用的代码只有1,2行也最好封装成一个方法。
    比如在方法中

    void initialize(){
        error = 100;
        srand((unsigned)time(0));
        /////////
        for (int i = 0; i < inputLayerNum; ++i){
          for (int j = 0; j < hiddenLayerNum; ++j){
            deltaWeight1[i][j] = 0;
          }
        }
        for (int i = 0; i < hiddenLayerNum; ++i){
          for (int j = 0; j < outputLayerNum; ++j){
            deltaWeight2[i][j] = 0;
          }
        }
        //初始化权值
        for (int i = 0; i <= inputLayerNum; ++i){
          for (int j = 0; j < hiddenLayerNum; ++j){
            weight1[i][j] = fabs(double(rand()) / double(RAND_MAX));;
          }
        }
        for (int i = 0; i <= hiddenLayerNum; ++i){
          for (int j = 0; j < outputLayerNum; ++j){
            weight2[i][j] = fabs(double(rand()) / double(RAND_MAX));
          }
        }
        //初始化输入层,隐含层,输出层
        for (int i = 0; i <= inputLayerNum; ++i){
          if (i < inputLayerNum){
            a1[i] = fabs(double(rand()) / double(RAND_MAX));
          }
          else{
            a1[i] = 1;
          }
        }
        for (int i = 0; i <= hiddenLayerNum; ++i){
          if (i < inputLayerNum){
            a2[i] = fabs(double(rand()) / double(RAND_MAX));
          }
          else{
            a2[i] = 1;
          }
        }
        for (int i = 0; i <= outputLayerNum; ++i){
          a3[i] = fabs(double(rand()) / double(RAND_MAX));
        }

    }

    fabs(double(rand()) / double(RAND_MAX))求随机数的表达式重复出现,重构后,将这段代码提取出来,变为

    double getRand(){
        return fabs(double(rand()) / double(RAND_MAX));
    }
    void initialize(){
        error = 100;
        srand((unsigned)time(0));
        /////////
        for (int i = 0; i < inputLayerNum; ++i){
          for (int j = 0; j < hiddenLayerNum; ++j){
            deltaWeight1[i][j] = 0;
          }  
        }
        for (int i = 0; i < hiddenLayerNum; ++i){
          for (int j = 0; j < outputLayerNum; ++j){
            deltaWeight2[i][j] = 0;
          }
        }
        //初始化权值
        for (int i = 0; i <= inputLayerNum; ++i){
           for (int j = 0; j < hiddenLayerNum; ++j){
            weight1[i][j] = getRand();;
          }
        }
        for (int i = 0; i <= hiddenLayerNum; ++i){
          for (int j = 0; j < outputLayerNum; ++j){
            weight2[i][j] = getRand();
          }
        }
        //初始化输入层,隐含层,输出层
        for (int i = 0; i <= inputLayerNum; ++i){
          if (i < inputLayerNum){
            a1[i] = getRand();
          }
          else{
            a1[i] = 1;
          }
        }
        for (int i = 0; i <= hiddenLayerNum; ++i){
          if (i < inputLayerNum){
            a2[i] = getRand();
          }
          else{
            a2[i] = 1;
          }
        }
        for (int i = 0; i <= outputLayerNum; ++i){
          a3[i] = getRand();
        }
    }

    //这段代码很明显可读性提高了,并且getRand函数也可以在其他方法中调用了

    3.封装字段:将类的某个字段转换成属性,可以更加合理的控制字段的访问
    4.抽取接口:将类的某些属性,方法抽取组成个接口,该类自动实现该接口,这样可以更好整理软的程序的框架结构。
    5.提升方法内的局部变量为方法的参数:这主要是在写代码的过程中会使用到。这样可以提升这段代码的重用能力。
    比如:

    void initial(){
        int classifier=10;
        for (int i = 0; i < classiferNum; ++i){
          weight[i] = 1;//权值初始时都设为1
          C[i] = new NNLayer();
        }
    }
    /////以上这个方法只能处理,classifier是10的情况,
    /////修改成如下代码后,就可以处理任意数量的classifier了。
    void initial(int classifier){
        for (int i = 0; i < classiferNum; ++i){
          weight[i] = 1;//权值初始时都设为1
          C[i] = new NNLayer();
        }
    }

    (12)隐喻(metaphore)
    隐喻是将整个系统联系在一起的全局视图,它是系统的未来景观,也就是综合各个模块的视图,如果最终的隐喻和模块的外观不符,开发者就会知道该模块出了问题。隐喻是XP中很特殊的一个方面,这里举一个我们大家都知道的例子:比如当我们设计多线程的时候,往往会构建生产者-消费者模型。一个生产者在生产产品,这些产品将提供给若干个消费者去消费,为了使生产者和消费者能并发执行,在两者之间设置一个具有多个缓冲区的缓冲池,缓冲区可以用盘子来比喻,生产者将它生产的产品放入一个盘子中,消费者可以从缓冲区中取走产品进行消费,生产者和消费者之间必须保持同步,即不允许消费者到一个空的缓冲区中取产品,也不允许生产者向一个已经放入产品的缓冲区中再次投放产品。在这里,生产者-消费者模型就是对该多线程程序的隐喻,如果你发现你的程序中没有对应消费者的程序或者没有对应生产者或者没有对应盘子的程序,很容易发现你的程序一定是有问题的,通过隐喻我们可以很容易查找各个模块的功能是否实现了。在设计时很明显需要以下三个模块

    Java实现应该如下:
    public class Producer implements Runnable {}//生产者模块
    public class Consumer implements Runnable{}//消费者模块
    public class SynchronizedStack {}//盘子

    <2>传统软件工程(traditional software development)的理解
           传统软件工程,以软件架构(software architecture)为核心,采用结构化的设计和分析方法将软件生命周期划分为制定计划、需求分析、软件设计、程序编写、软件测试和运行维护等六个基本活动。各个阶段的通过文档相互流通。前期就要设计好整个软件大厦的框架来指导和支撑后面各个方面的开发和维护工作,后面再根据前期设计的蓝图来逐步实现。由架构师完成软件架构设计,开发人员再根据软件大厦的蓝图进行软件开发。可以发现传统软件工程一个很大的目的是为了将混乱的个人的软件开发转换为整体的有效的团队开发,所以传统的软件工程是以文档为导向的,有了文档,团队就按照文档照着实现就可以了。
    "惯用过程模型为软件工程增加大量有用的结构化设计,并为软件团队提供了有效的路线图"【6】。
    这里介绍最著名的瀑布模型(waterfall model),它提出了一个系统的,顺序的软件开发方法。用图来表示这种开发模型。一般情况下将其分为计划、需求分析、设计、编码,单元测试、测试、运行维护等几个阶段。

                                                                                                     【图3】

    <3>敏捷软件工程的优势(advantages)和劣势(disadvantages)
      优势 :(1) 风险可控,操作灵活.
                   (2) 能够尽快看到项目完成的效率和结果,防止一个项目停滞不前。
          (3) 即使到了开发的后期,也欢迎改变需求。
                   (4) 最终产品的客户满意度高。
                   (5)轻装前进。如果一个开发团队太过于注重一份非常完善的文档。或许在初始时,文档的撰写还算简单,但当开发阶段到达后期时,很可能团队的大部分时间都花在了撰写文档,而不是写源代码。相当简单的敏捷工作流程图如下

                                                           【图4】
                  (6)快速反馈。从开始采取行动,到获得行动的反馈,二者之间的时间至关紧要。敏捷开发团队能够快速获得客户的反馈,修正项目方向。
    劣势:     (1)对人员素质和稳定性的要求更高,因为敏捷开发以人为本,所以对人员素质和稳定性的要求又更高。项目组中需要有一定数目的老手来引导整个项目,如果项目中频繁有人离职或者大部分都是新手那么效率可能不如传统的软件工程开发。
                 (2)当然在设计的完善性上,敏捷开发具有一定的漏洞。
                 (3)矛盾的客户需求:有很多项目,都有很多的客户。但是每个客户都有自己的一套想法。XP团队因为让客户参与到了团队开发之中,因此XP团队需要整合不同客户的意见,最后达到满意的效果,这很明显是超出了开发团队的职权。
                (4)对于很大的项目来说,敏捷软件开发模式暂时还处在探索之中。不过暂时也有一些方法来处理这个问题。敏捷开发小组通常不超过7-10个人。敏捷开发建议不要超过建立100人的大组,而是建立很多的小组来替代这个大组(比如10个10人的小组)。分布图如下:


                                             【图5】
    <4>传统软件工程的优势(advatnages)和劣势(disadvantages)
    优势 :       (1)为项目提供了按阶段划分的检查点,将整个项目划分为了有序的整体。
                     (2)当前一阶段完成后,团队只需要去关注后续阶段,这样可以减轻团队的开发压力。
                     (3)开发的各个阶段比较清晰

    这里举一个例子,比如在文档中明确了功能,那么就可以抽象出接口加以实现,这会使得程序的结构更加清晰:using System;namespace exampleusing System;

    namespace example
    {
    //接口, internal interface commonFunction { void actionA(String message);
    void actionB(String message);
    } //具体实现类A class A : commonFunction { public void actionA(String message) { Console.WriteLine(message); } public void SayMsg(String message) { Console.ReadLine(message); } } //具体实现类B class B : commonFunction { public void actionA(String message) { Console.WriteLine(message); } public void actionB(String message) { Console.ReadLine(message); } } }

                     (4) 强调早期计划及需求调查
                     (5) 适合需求稳定的产品开发
    劣势:        (1)需求无法准确表达。客户很难在一开始的时候,就能够完全想明白所有的需求,或者难以描述这些需求,传统软件工程(例如瀑布模型)则要求客户明确要求,形成文档,因此当一个项目有很多不确定性的时候了,瀑布模型很难适应。
                    (2)客户等待周期长,在传统软件开发中,往往只有到软件开发的后期,客户才能第一次看到可以工作的软件。
                    (3) 风险往往迟至后期才显露,失去及早纠正的机会
    <5>敏捷软件工程和传统软件工程的对比
                   (1)客户的参与度:传统的开发方法基本上都是基于一个反复推敲的合同,合同中对于功能设计以及权利义务定义原则上都进行了仔细的定义。问题是很多客户在初期根本没有一个很明确的软件目标只知道一个大概方向,中途也可能临时改变想法,只能给出软件开发的大致方向,客户对于大部分细节也都没有明确的要求。客户为了保护自己的利益,会尽可能多的添加功能到这个项目书中。而开发团队考虑的是如何在自己的成本控制内得到尽可能多的盈利。在传统软件工程中,当客户第一眼看到项目效果的时候,已经是很长时间之后了,一个突出的问题是,项目的展示效果很可能和客户想象的不一样。而在敏捷软件开发中,客户贯穿了整个开发的周期,了解了所有的变动以及缘由,并且能够及时的看到项目效果,并能够按照自己的想法来控制最终的展示效果,客户的满意度会达到最高。
                (2)客户的满意度:传统软件工程通常会在产品起点与最终结果之间规划出一条直线,然后沿着直线不断往前走。也就是当文档完成后,团队会全力完成文档中的内容。然而当项目到达终点时,用户通常会发现那已经不是他们想去的地方。而敏捷方法则采用小步快跑,每走完一步再调整并为下一步确定方向,直到真正的终点。因此往往敏捷开发的客户满意度要高
                (3)团队规模,目前来看敏捷开发更适合小团队,传统的软件开发比较适合大团队。
                (4)效率方面,敏捷开发将在软件工程中各种复杂的东西去掉,追求效率和简单。因此往往在敏捷开发团队中人人都是多面手。而有时在传统软件工程团队中,大量的精力被消耗在了各种需求评审、用例评审,文山会海之中,往往效率会低一些。软件开发的主要目标是以有效的方式,制造出满足project stakeholder需要的软件,而不是制造无关的文档,无关的用于管理的artifact,甚至无关的模型。任何一项活动(activity ),如果不符合这项原则,不能有助于目标实现的,都应该受到审核,甚至取消。

               (5)产品成型方面,传统软件开发只有项目接近尾声的时候,用户才可能得到可执行的程序,而敏捷开发中用户在每一次迭代中都可以得到可执行的程序。
               (6)测试上的区别,敏捷开发(这里以XP为例),敏捷开发是要在编码开始之前建立单元测试是XP方法的关键因素。所建立的单元测试应当使用一个可以自动实施的框架(因此易于执行并可重复)。【7】
               (7)在工作方式上,传统软件工程,工作方式:团队中每一个人只关注自己的本职工作,不提倡个人的独特发挥,整个团队要求按照文档进行逐步开发。而敏捷开发更加注重个人能力的开发,并且关注业务优先级,经常进行检查与调整【8】。
               (8)计划上的区别。传统软件工程在和用户交流后会形成一个很完备的软件开发文档,并在开发中不断形成开发文档。而敏捷开发会不断的进行发布(这点在前文敏捷开发的特点已讲到过)。用图来表示规划的过程。

     

                                                               【图6】
               (9)适应于不同的项目,敏捷开发更加适合于工期短见效快,对于一些大型项目和产品,敏捷开发并不一定能起到好的效果。比如说开发操作系统的话,传统软件工程就能很好的完成任务了。但这也并不是绝对的,敏捷开发平台已成功应用于中国科学院资源规划系统,国家自然科学基金委这样的特大信息化项目,并取得了良好效果【9】。
              (10)“稳定”和“变化”:传统软件开发而言强调 “稳”,在一开始就花大量的工作做设计、做需求分析、做模块构建等工作,确保能实现客户需求,需要在开发之前就拿出一套非常完整的设计文档来。开发阶段则是以文档的为导向,逐步实现文档中描述的功能,直到最终向客户交付产品,这样一套流程下来,不止对于开发者要稳(按照计划不出纰漏的执行),对客户也有稳的要求,如果是一个不断变更需求的开发任务,那么传统的软件开发团队每一次更改程序都需要付出大量的时间精力,成本更是会不断增加。此外,传统的软件开发是没有迭代过程和反馈过程的,就像瀑布一样“一去不复返”,文档是联接不同阶段的唯一接口。敏捷软件开发强调“变”,这一点在敏捷开发宣言中也有所体现,通过接受变化后的快速应对和短时间,高频率的迭代交付确保产品能打到客户的预期。用一个很好的比喻来形容,传统软件工程是提前将起点到终点的跑道建好了,然后直接向前跑去,而敏捷开发,则是边跑边看方向。

                (11)敏捷软件在开发过程中整合和响应矛盾的客户需求带来的额外开发难度与随时响应客户需求带来的好处(from 1#  Mr.Write suggestion)

                  是欢迎随时响应需求还是拒绝响应请求往往还是需要根据具体的情形来判断。在实际的软件开发中如果非常拘泥于一种模式不进行任何的变通,使得敏捷开发沦为一句口号或者面子工程,那么并不能体现出敏捷开发的优势。如果客户懂技术,并且非常愿意融入进团队那么使用敏捷开发会有一定的优势(敏捷软件在开发过程中整合和响应矛盾的客户需求带来的额外开发难度,要小于随时响应客户需求带来的好处),如果客户没有太多时间并且总是对工程提一些非建设性意见(在实际软件开发中是很常见的),那么随时响应客户需求恐怕是非常痛苦的了。无论是敏捷开发还是传统软件开发都只为软件开发提供方向,在实际的工程中绝对不能古板僵化的套用,而应该结合实际情况进行软件的开发,最终才能使项目成功完成。

                (12)传统软件项目管理工具和敏捷软件开发项目管理工具的比较

                 往往进行传统软件开发的管理工具更具有严密性和时间规划性(例如project2013),而敏捷软件开发工具更简单和高效。

                 这里以teambition这款敏捷开发项目管理工具为例,只需要拖动窗口就可以进行项目的进度修改,可以看到这款软件对于需要经常、快速、高质量地发布软件的研发团队是非常适用的。

                                                                                   【图7】

    <7>敏捷软件工程的现状和传统软件工程的现状。
                敏捷软件工程近年来逐步兴起,许多传统的软件工程开发者团队,也在向敏捷开发模式转型,其中既有成功的案例,也有失败的案例。同时传统软件工程也因为自身独特的优势仍然活跃在软件开发的各个领域。在应用方面,这两者目前都广泛存在于软件开发行业中,随着互联网的兴起,社会节奏越来越快,敏捷开发也似乎更被人们所青睐,敏捷开发拥有了很多坚定的支持者,学习敏捷开发也似乎成了一种潮流,互联网相比传统软件行业来说更注重“更快的切中客户需求”,这与敏捷开发所强调的根据反馈快速迭代是完全相符的。敏捷开发本身也在不断的出现新的模式,比如Scrum、比如极限编程,比如精益、比如特征驱动开发、比如水晶方法等。也有大量的公司在开发中使用了敏捷开发,例如华为,思艾特,IBM,百度等。

     

    <8>参考文献
    【1】维基百科: "Agile software development describes a set of principles for software development under which requirements and solutions evolve through the collaborative effort of self-organizing cross-functional teams.[1] It advocates adaptive planning, evolutionary development, early delivery, and continuous improvement, and it encourages rapid and flexible response to change."
    【2】 作者:Robert C. Martin 书名: 《Agile Software Development: Principles Patterns and Practices》
    原文如下:"The best case is for the customer to work in the same room as the developers ,Next best is if the customer works within 100 meter of the developers. The larger the distance,the more difficult it is for customer to be a true team member."
    【3】《Agile Software Development: Principles, Patterns and Practices》的第二章的The Practices of Extreme Programming
    【4】《Agile Software Development: Principles, Patterns and Practices》中的"The XP rule is that a team is not allowed to work overtime"。
    【5】作者:Martin Fowler 书名《Refactoring: Improving the Design of Existing Code》,引用原文为:"Refactoring is the process of changing a software system in such a way that it does not alter the external behavior of the code yet impore it its internal structure。
    【6】作者:Roger S.Pressman 书名《软件工程-实践者的研究方法》 郑人杰,马素霞等译。
    【7】作者:Roger S.Pressman 书名《软件工程-实践者的研究方法》 郑人杰,马素霞等译。
    【8】作者:Mike Cohn 书名《Agile Estimating and Planning》,引用自chapter3,“Focus on bussiness priorities,Inspect And adapt”
    【9】(中国科学院计算机网络信息中心 北京100190 ) 《敏捷开发平台的设计》 李新 参考来源:
    其余参考资料:
    【10】作者:Ken Schwaber,《Agile Project Management with Scrum》
    【11】作者:Ken Schwaber,和Mike Beedle 《Agile Software Development with Scrum》
    【12】作者:Alistair Cockburn 《Crystal Clear: A Human-Powered Methodology for Small Teams》
    【13】作者:Venkat Subramaniam, Andy Hunt 《Practices of an Agile Developer: Working in the Real World》
    图像来源:
    【图1】:自行绘制
    【图2】:自行绘制
    【图3】:自行绘制

    【图4】:引用自《敏捷开发平台的设计》 李新

    【图5】:引用自《大团队敏捷开发解决方案》

    【图6】:引用自《Agile Estimating and Planning》Roger S.Pressman

     

  • 相关阅读:
    java页面请求跑批处理sql的有关问题
    Linux下一个检查跑批是否成功的Shell
    redhat Linux5 安装vsftp .
    LINUX FTP简单配置
    java代理机制
    详细解析Java中抽象类和接口的区别
    抽象类和接口的区别
    SVN与Git比较
    浅谈存储过程和触发器
    存储过程,触发器,函数 学习总结
  • 原文地址:https://www.cnblogs.com/codeDog123/p/5954443.html
Copyright © 2011-2022 走看看