•  UML 2 中的阴和阳

    在 UML 2 中有二种基本的图范畴:结构图和行为图(structure diagrams and behavior diagrams)。每个 UML 图都属于这二个图范畴。结构图的目的是显示建模系统的静态结构。它们包括类,组件和(或)对象图。另一方面,行为图显示系统中的对象的动态行为,包括如对象的方法,协作和活动之类的内容。行为图的实例是活动图,用例图和序列图大体上的结构图

    大体上的结构图(Structure diag...
  •   在按照我的理解方式审查了软件开发的生命周期后,我得出一个结论:实际上满足工程设计标准的惟一软件文档,就是源代码清单。

    -- Jack Reeves
    简介
      2001年,为了解决许多公司的软件团队陷入不断增长的过程泥潭,一批业界专家一起概括出了一些可以让软件开发团队具有快速工作、响应变化能力的价值观和原则,他们称自己为敏捷联盟。敏捷开发过程的方法很多,主要有:SCRUM,Crystal,特征驱动软件开发(Feature Driven Development,简称FDD),自适应软件开发(Adaptive Software Development,简称ASD),以及最重要的极限编程(eXtreme Programming,简称XP)。极限编程(XP)是于1998年由Smalltalk社群中的大师级人物Kent Beck首先倡导的。

    极限编程

      设计和编程都是人的活动。忘记这一点,将会失去一切。
    -- Bjarne Stroustrup

      极限编程(XP)是敏捷方法中最著名的一个。它是由一系列简单却互相依赖的实践组成。这些实践结合在一起形成了一个胜于部分结合的整体。

    下面是极限编程的有效实践:
    1. 完整团队 XP项目的所有参与者(开发人员、客户、测试人员等)一起工作在一个开放的场所中,他们是同一个团队的成员。这个场所的墙壁上随意悬挂着大幅的、显著的图表以及其他一些显示他们进度的东西。
    2. 计划游戏计划是持续的、循序渐进的。每2周,开发人员就为下2周估算候选特性的成本,而客户则根据成本和商务价值来选择要实现的特性。
    3. 客户测试作为选择每个所期望的特性的一部分,客户可以根据脚本语言来定义出自动验收测试来表明该特性可以工作。
    4. 简单设计团队保持设计恰好和当前的系统功能相匹配。它通过了所有的测试,不包含任何重复,表达出了编写者想表达的所有东西,并且包含尽可能少的代码。
    5. 结对编程所有的产品软件都是由两个程序员、并排坐在一起在同一台机器上构建的。
    6. 测试驱动开发编写单元测试是一个验证行为,更是一个设计行为。同样,它更是一种编写文档的行为。编写单元测试避免了相当数量的反馈循环,尤其是功功能能验证方面的反馈循环。程序员以非常短的循环周期工作,他们先增加一个失败的测试,然后使之通过。
    7. 改进设计随时利用重构方法改进已经腐化的代码,保持代码尽可能的干净、具有表达力。
    8. 持续集成团队总是使系统完整地被集成。一个人拆入(Check in)后,其它所有人责任代码集成。
    9. 集体代码所有权任何结对的程序员都可以在任何时候改进任何代码。没有程序员对任何一个特定的模块或技术单独负责,每个人都可以参与任何其它方面的开发。
    10. 编码标准 系统中所有的代码看起来就好像是被单独一人编写的。
    11. 隐喻 将整个系统联系在一起的全局视图;它是系统的未来影像,是它使得所有单独模块的位置和外观变得明显直观。如果模块的外观与整个隐喻不符,那么你就知道该模块是错误的。
    12. 可持续的速度 团队只有持久才有获胜的希望。他们以能够长期维持的速度努力工作,他们保存精力,他们把项目看作是马拉松长跑,而不是全速短跑。 极限编程是一组简单、具体的实践,这些实践结合在形成了一个敏捷开发过程。极限编程是一种优良的、通用的软件开发方法,项目团队可以拿来直接采用,也可以增加一些实践,或者对其中的一些实践进行修改后再采用。
    敏捷开发
      人与人之间的交互是复杂的,并且其效果从来都是难以预期的,但却是工作中最重要的方面。
    -- Tom DeMacro和Timothy Lister

    敏捷软件开发宣言:
    • 个体和交互     胜过 过程和工具
    • 可以工作的软件 胜过 面面俱到的文档
    • 客户合作       胜过 合同谈判
    • 响应变化       胜过 遵循计划
    虽然右项也有价值,但是我们认为左项具有更大的价值。
    • 我们最优先要做的是通过尽早的、持续的交付有价值的软件来使客户满意。
    • 即使到了开发的后期,也欢迎改变需求。敏捷过程利用变化来为客户创造竞争优势。
    • 经常性地交付可以工作的软件,交付的间隔可以从几个星期到几个月,交付的时间间隔越短越好。
    • 在整个项目开发期间,业务人员和开发人员必须天天都在一起工作。
    • 围绕被激励起来的个体来构建项目。给他们提供所需的环境和支持,并且信任他们能够完成工作。
    • 在团队内部,最具有效果并富有效率的传递信息的方法,就是面对面的交谈。
    • 工作的软件是首要的进度度量标准。
    • 敏捷过程提倡可持续的开发速度。责任人、开发者和用户应该能够保持一个长期的、恒定的开发速度。
    • 不断地关注优秀的技能和好的设计会增强敏捷能力。
    • 简单是最根本的。
    • 最好的构架、需求和设计出于自组织团队。
    • 每隔一定时间,团队会在如何才能更有效地工作方面进行反省,然后相应地对自己的行为进行调整。
    当软件开发需求的变化而变化时,软件设计会出现坏味道,当软件中出现下面任何一种气味时,表明软件正在腐化。
    • 僵化性: 很难对系统进行改动,因为每个改动都会迫使许多对系统其他部分的其它改动。
    • 脆弱性: 对系统的改动会导致系统中和改动的地方在概念上无关的许多地方出现问题。
    • 牢固性: 很难解开系统的纠结,使之成为一些可在其他系统中重用的组件。
    • 粘滞性: 做正确的事情比做错误的事情要困难。
    • 不必要的复杂性: 设计中包含有不具任何直接好处的基础结构。
    • 不必要的重复性: 设计中包含有重复的结构,而该重复的结构本可以使用单一的抽象进行统一。
    • 晦涩性: 很难阅读、理解。没有很好地表现出意图。
    敏捷团队依靠变化来获取活力。团队几乎不进行预先设计,因此,不需要一个成熟的初始设计。他们更愿意保持设计尽可能的干净、简单,并使用许多单元测试和验收测试作为支援。这保持了设计的灵活性、易于理解性。团队利用这种灵活性,持续地改进设计,以便于每次迭代结束生成的系统都具有最适合于那次迭代中需求的设计。为了改变上面软件设计中的腐化味,敏捷开发采取了以下面向对象的设计原则来加以避免,这些原则如下:
    • 单一职责原则(SRP)
      就一个类而言,应该仅有一个引起它变化的原因。
    • 开放-封闭原则(OCP)
      软件实体应该是可以扩展的,但是不可修改。
    • Liskov替换原则(LSP)
      子类型必须能够替换掉它们的基类型。
    • 依赖倒置原则(DIP)
      抽象不应该依赖于细节。细节应该依赖于抽象。
    • 接口隔离原则(ISP)
      不应该强迫客户依赖于它们不用的方法。接口属于客户,不属于它所在的类层次结构。
    • 重用发布等价原则(REP)
      重用的粒度就是发布的粒度。
    • 共同封闭原则(CCP)
      包中的所有类对于同一类性质的变化应该是共同封闭的。一个变化若对一个包产生影响,则将对该包中的所有类产生影响,而对于其他的包不造成任何影响。
    • 共同重用原则(CRP)
      一个包中的所有类应该是共同重用的。如果重用了包中的一个类,那么就要重用包中的所有类。
    • 无环依赖原则(ADP)
      在包的依赖关系图中不允许存在环。
    • 稳定依赖原则(SDP)
      朝着稳定的方向进行依赖。
    • 稳定抽象原则(SAP)
      包的抽象程度应该和其稳定程度一致。
      上述中的包的概念是:包可以用作包容一组类的容器,通过把类组织成包,我们可以在更高层次的抽象上来理解设计,我们也可以通过包来管理软件的开发和发布。目的就是根据一些原则对应用程序中的类进行划分,然后把那些划分后的类分配到包中。

    下面举一个简单的设计问题方面的模式与原则应用的示例:

    问题:
      选择设计运行在简易台灯中的软件,台灯由一个开关和一盏灯组成。你可以询问开关开着还是关着,也可以让灯打开或关闭。

    解决方案一:
      下面图1是一种最简单的解决方案,Switch对象可以轮询真实开关的状态,并且可以发送相应的turnOn和turnOff消息给Light。


    解决方案二:
      上面这个设计违反了两个设计原则:依赖倒置原则(DIP)和开放封闭原则(OCP),DIP原则告诉我们要优先依赖于抽象类,而Switch依赖了具体类Light,对OCP的违反是在任何需要Switch的地方都要带上Light,这样就不能容易扩展Switch去管理除Light外的其他对象。为了解决这个方案,可以采用ABSTRACT SERVER模式,在Switch和Light之间引入一个接口,这样就使得Switch能够控制任何实现了这个接口的东西,这也就满足了DIP和OCP原则。如下面图2所示:



    解决方案三:
      上面图2所示解决方案,违返了单一职责原则(SRP),它把Switch和Light绑定在一起,而它们可能会因为不同的原因而改变。这种问题可以采用ADAPTER模式来解决,适配器从Switchable 派生并委托给Light,问题就被优美的解决了,现在,Switch就可以控制任何能够被打开或者关闭的对象。但是这也需要会出时间和空间上的代价来换取。如下面图3所示:



      敏捷设计是一个过程,不是一个事件。它是一个持续的应用原则、模式以及实践来改进软件的结构和可读性的过程。它致力于保持系统设计在任何时间都尽可能得简单、干净和富有表现力。

    参考文献
    1. 设计模式-可复用面向对象软件的基础 -- 李英军等译
    2. 重构-改善既有代码的设计 -- 侯捷等译
    3. 敏捷软件开发-原则、模式与实现 -- 邓辉译
    联系方式
    • 地址:陕西省西安市劳动路90号院(台板厂家属院)六单元
    • 邮编:710082
    • Email: jingzhou_xu@163.net
    • 未来工作室(Future Studio)
  • 从瀑布模型、极限编程到敏捷开发
    ---软件开发管理者思维的变化
    Jack zhai
    软件开发是一种对人类智慧的管理,对人大脑思维的“工厂化”管理。人是有感情的、有情绪的、变化的、相对独立的工作单元,这与冰冷的机器是不可比的,所以在中国的历史上,管理人是最难的工作;“学而优则仕”的观点就是让最聪明的人应该选出来做官,做官就是管理人的。软件开发不仅是代码编程,而是人员的有效组织,如何既发挥人的主观能动性,避免情绪变化对工作的影响,又可以让大家有效的交流,让多个大脑的思路统一,快速完成目标呢?多年来软件企业的管理者一直在不断地探索。
    另外有一个问题一直是软件开发管理人员的心病:软件是工具,开发的是客户业务的应用,但客户不了解软件,开发者不了解业务,如何有效沟通是软件质量的重大障碍。把开发者变成客户业务的专家是个没有办法的办法,让软件企业付出的代价也是昂贵的。
    瀑布模型、极限编程、敏捷开发是有代表性的开发模式,在对开发者、客户、最终的产品的关注上的变化,体现了软件开发管理者在管理模式上的变化。
    一、瀑布开发
    瀑布模型(Waterfall Model)Royce1970年提出的,他把大型软件开发分为:分析与编程,象工厂流水线一样把软件开发过程分成各种工序,并且每个工序可以根据软件产品的规模、参与人员的多少进一步细分成更细的工序。该模型非常符合软件工程学的分层设计思路,所以成为软件开发企业使用最多的开发模型。
    瀑布模型的特点:
    1、               强调文档,前一个阶段的输出就是下一个阶段的输入,文档是个阶段衔接的唯一信息。所以很多开发人员好象是在开发文档,而不是开发软件,因为要到开发的后期,才可以看到软件的“模样”。
    2、               没有迭代与反馈。瀑布模型对反馈没有涉及,所以对变化的客户需求非常不容易适应,瀑布就意味着没有回头路。
    3、               管理人员喜欢瀑布模型的原因是把文档理解为开发的速度,可以方便地界定不同阶段的里程碑。
    瀑布模型的用户很多,也有一些反对的意见:
    第一、瀑布模型不适合客户需求不断变化的软件开发,尤其是客户的业务管理的软件,业务随着市场变化,而软件初期的设计可能已经大大变化,而后期的需求更改成本是开始的10倍基数。在ERP盛行的软件市场里,一方面市场带动需求变化,另一方面初期客户对需求描述不清楚,都为瀑布模型的使用团队带来困难。
    第二、瀑布模型是一种软件文档的开发,把开发者变成流水线上的机器,大量重复性的工作让编程人员提不起兴趣,工作很枯燥,没有激情,编程成了一种没有创意的机械劳动,这让一向以高科技为标志的高级程序人员大为恼火。
    在这种背景下,极限编程(extreme Programming, XP)带来了新鲜的空气。
    二、极限编程
    极限编程诞生于一种加强开发者与用户的沟通需求,让客户全面参与软件的开发设计,保证变化的需求及时得到修正。要让客户能方便地与开发人员沟通,一定要用客户理解的语言,先测试再编码就是先给客户软件的外部轮廓,客户使用的功能展现,让客户感觉到未来软件的样子,先测试再编码与瀑布模型显然是背道而驰的。同时,极限编程注重用户反馈与让客户加入开发是一致的,让客户参与就是随时反馈软件是否符合客户的要求。有了反馈,开发子过程变短,迭代也就很自然出现了,快速迭代,小版本发布都让开发过程变成更多的自反馈过程,有些象更加细化的快速模型法。当然极限编程还加入了很多激励开发人员的“措施”,如结队编程、40小时工作等。
    极限编程是一种开发管理模式,它强调的重点是:
    1、              角色定位:极限编程把客户非常明确地加入到开发的团队中,并参与日常开发与沟通会议。客户是软件的最终使用者,使用是否合意一定以客户的意见为准。不仅让客户参与设计讨论,而且让客户负责编写拥护故事(User Story),也就是功能需求,包括软件要实现的功能以及完成功能的业务操作过程。用户在软件开发过程中的责任被提到与开发者同样的重要程度。
    2、              敏捷开发:敏捷开发追求合作与响应变化。迭代就是缩短版本的发布周期,缩短到周、日,完成一个小的功能模块,可以快速测试、并及时展现给客户,以便及时反馈。小版本加快了客户沟通反馈的频率,功能简单,在设计、文挡环节大大简化。极限编程中文挡不再重要的原因就是因为每个版本功能简单,不需要复杂的设计过程。极限编程追求设计简单,实现客户要求即可,无需为扩展考虑太多,因为客户的新需求随时可以添加。
    3、              追求价值:极限编程把软件开发变成自我与管理的挑战,追求沟通、简单、反馈、勇气,体现开发团队的人员价值,激发参与者的情绪,最大限度地调动开发者的积极性,情绪高涨,认真投入,开发的软件质量就大大提高。结对编程就是激发队员才智的一种方式。
        极限编程把软件开发过程重新定义为聆听、测试、编码、设计的迭代循环过程,确立了测试->编码->重构(设计)的软件开发管理思路。
    极限编程的12个实践是极限编程者总结的实践经典,是体现极限编程管理的原则,对极限编程具有指导性的意义,但并非一定要完全遵守12个实践,主要看它给软件过程管理带来的价值。
    1、              小版本。为了高度迭代,与客户展现开发的进展,小版本发布是一个可交流的好办法,客户可以针对性提出反馈。但小版本把模块缩得很小,会影响软件的整体思路连贯,所以小版本也需要总体合理的规划。
    2、              规划游戏。就是客户需求,以客户故事的形式,由客户负责编写。极限编程不讲求统一的客户需求收集,也不是由开发人员整理,而是采取让客户编写,开发人员进行分析,设定优先级别,并进行技术实现。当然游戏规则可进行多次,每次迭代完毕后再行修改。客户故事是开发人员与客户沟通的焦点,也是版本设计的依据,所以其管理一定是有效的、沟通顺畅的。
    3、              现场客户。极限编程要求客户参与开发工作,客户需求就是客户负责编写的,所以要求客户在开发现场一起工作,并为每次迭代提供反馈。
    4、              隐喻。隐喻是让项目参与人员都必须对一些抽象的概念理解一致,也就是我们常说的行业术语,因为业务本身的术语开发人员不熟悉,软件开发的术语客户不理解,因此开始要先明确双方使用的隐喻,避免歧异。
    5、              简单设计。极限编程体现跟踪客户的需求变化,既然需求是变化的,所以对于目前的需求就不必过多地考虑扩展性的开发,讲求简单设计,实现目前需求即可。简单设计的本身也为短期迭代提供了方便,若开发者考虑“通用”因素较多,增加了软件的复杂度,开发的迭代周期就会加长。简单设计包括四方面含义:1、通过测试。2、避免重复代码。3、明确表达每步编码的目的,代码可读性强。4、尽可能少的对象类和方法。由于采用简单设计,所以极限编程没有复杂的设计文档要求。
    6、              重构。重构是极限编程先测试后编码的必然需求,为了整体软件可以先进行测试,对于一些软件要开发的模块先简单模拟,让编译通过,到达测试的目的。然后再对模块具体“优化”,所以重构包括模块代码的优化与具体代码的开发。重构是使用了“物理学”的一个概念,是在不影响物体外部特性的前提下,重新优化其内部的机构。这里的外部特性就是保证测试的通过。
    7、              测试驱动开发。极限编程是以测试开始的,为了可以展示客户需求的实现,测试程序优先设计,测试是从客户实用的角度出发,客户实际使用的软件界面着想,测试是客户需求的直接表现,是客户对软件过程的理解。测试驱动开发,也就是客户的需求驱动软件的开发。
    8、              持续集成。集成的理解就是提交软件的展现,由于采用测试驱动开发、小版本的方式,所以不断集成(整体测试)是与客户沟通的依据,也是让客户提出反馈意见的参照。持续集成也是完成阶段开发任务的标志。
    9、              结对编程。这是极限编程最有争议的实践。就是两个程序员合用一台计算机编程,一个编码,一个检查,增加专人审计是为了提供软件编码的质量。两个人的角色经常变换,保持开发者的工作热情。这种编程方式对培养新人或开发难度较大的软件都有非常好的效果。
    10、           代码共有。在极限编程里没有严格文档管理,代码为开发团队共有,这样有利于开发人员的流动管理,因为所有的人都熟悉所有的编码。
    11、           编码标准。编码是开发团队里每个人的工作,又没有详细的文档,代码的可读性是很重要的,所以规定统一的标准和习惯是必要的,有些象编码人员的隐喻。
    12、           每周40小时工作。极限编程认为编程是愉快的工作,不轻易加班,今天的工作今天做,小版本的设计也为了单位时间可以完成的工作安排。
    三、敏捷开发
    极限编程的思想体现了适应客户需求的快速变化,激发开发者的热情,也是目前敏捷开发思维的重要支持者。
    2001年,17名编程大师分别代表极限编程、Scrum(“棒球”团队开发模式)、特征驱动开发、动态系统开发方法、自适应软件开发、水晶方法、实用编程等开发流派,发表“敏捷软件开发”宣言。敏捷软件开发是一个开发软件的管理新模式,用来替代以文件驱动开发的瀑布开发模式。敏捷方式也称轻量级开发方法。敏捷软件开发宣言内容:
    ²        个体和交互胜过过程和工具
    ²        可以工作的软件胜过面面具到的文档
    ²        可户合作胜过合同谈判
    ²        响应变化胜过遵循计划
    敏捷开发集成了新型开发模式的共同特点,它重点强调:
    1.         以人为本,注重编程中人的自我特长发挥。
    2.         强调软件开发的产品是软件,而不是文档。文档是为软件开发服务的,而不是开发的主体。
    3.         客户与开发者的关系是协作,不是合约。开发者不是客户业务的“专家”,要适应客户的需求,是要客户合作来阐述实际的需求细节,而不是为了开发软件,把开发人员变成客户业务的专家,这是传统开发模式或行业软件开发企业的最大面临问题。
    4.         设计周密是为了最终软件的质量,但不表明设计比实现更重要,要适应客户需求的不断变化,设计也要不断跟进,所以设计不能是“闭门造车”、“自我良好”,能不断根据环境的变化,修改自己的设计,指导开发的方向是敏捷开发的目标。
    敏捷开发避免了传统瀑布方式的弊端,主要是吸收了各种新型开发模式的“动态”特性,关注点从文档到开发者,管理方式也从工厂的流水线到团队的自我放松式的组织。总结敏捷开发与瀑布模式的不同,主要是下面几个“敏捷”的关注点:
    ²        迭代。软件的功能是客户的需求,界面的操作是客户的“感觉”,对迭代的强调是缩短了软件版本的周期
    ²        客户参与。以人为本,客户是软件的使用者,是业务理解的专家,没有客户的参与,开发者很难理解客户的真实需求
    ²        小版本。快速功能的展现,看似简单,但对于复杂的客户需求,合理地分割与总体上的统一,要很好地二者兼顾是不容易的。
       
    敏捷就是“快”,快才可以适应目前社会的快节奏;要快就要发挥个人的个性思维多一些,个性思维的增多,虽然通过结队编程、代码共有、团队替补等方式减少个人对软件的影响力,但也会造成软件开发继承性的下降,因此敏捷开发是一个新的思路,但不是软件开发的终极选择。对于长时间、人数众多的大型软件应用的开发,文档的管理与衔接作用还是不可替代的。如何把敏捷的开发思路与传统的“流水线工厂式”管理有机地结合,是软件开发组织者面临的新课题。
  • 一 什么是Scrum?

    Scrum (英式橄榄球争球队), 软件开发模型是敏捷开发的一种,在最近的一两年内逐渐流行起来。

    Scrum的基本假设是:

    开发软件就像开发新产品,无法一开始就能定义软件产品最终的规程,过程中需要研发、创意、尝试错误,所以没有一种固定的流程可以保证专案成功。Scrum 将软件开发团队比拟成橄榄球队,有明确的最高目标,熟悉开发流程中所需具备的最佳典范与技术,具有高度自主权,紧密地沟通合作,以高度弹性解决各种挑战,确保每天、每个阶段都朝向目标有明确的推进。

    Scrum 开发流程通常以 30 天(或者更短的一段时间)为一个阶段,由客户提供新产品的需求规格开始,开发团队与客户于每一个阶段开始时挑选该完成的规格部分,开发团队必须尽力于 30 天后交付成果,团队每天用 15 分钟开会检查每个成员的进度与计划,了解所遭遇的困难并设法排除。

    二 Scrum较传统开发模型的优点

    Scrum模型的一个显著特点就是响应变化,它能够尽快地响应变化。下面的图片使用传统的软件开发模型(瀑布模型、螺旋模型或迭代模型)。随着系统因素(内部和外部因素)的复杂度增加,项目成功的可能性就迅速降低。


    下图是Scrum模型和传统模型的对比:
          

    三 Scrum模型

    一)  有关Scrum的几个名词

    backlog: 可以预知的所有任务, 包括功能性的和非功能性的所有任务。

    sprint:一次跌代开发的时间周期,一般最多以30天为一个周期.在这段时间内,开发团队需要完成一个制定的backlog,并且最终成果是一个增量的,可以交付的产品。

    sprint backlog:一个sprint周期内所需要完成的任务。

    scrumMaster: 负责监督整个Scrum进程,修订计划的一个团队成员。

    time-box: 一个用于开会时间段。比如每个daily scrum meeting的time-box为15分钟。

    sprint planning meeting: 在启动每个sprint前召开。一般为一天时间(8小时)。该会议需要制定的任务是:产品Owner和团队成员将backlog分解成小的功能模块,  决定在即将进行的sprint里需要完成多少小功能模块,确定好这个Product Backlog的任务优先级。另外,该会议还需详细地讨论如何能够按照需求完成这些小功能模块。制定的这些模块的工作量以小时计算。

    Daily Scrum meeting:开发团队成员召开,一般为15分钟。每个开发成员需要向ScrumMaster汇报三个项目:今天完成了什么? 是否遇到了障碍? 即将要做什么?通过该会议,团队成员可以相互了解项目进度。

    Sprint review meeting:在每个Sprint结束后,这个Team将这个Sprint的工作成果演示给Product Owner和其他相关的人员。一般该会议为4小时。

    Sprint retrospective meeting:对刚结束的Sprint进行总结。会议的参与人员为团队开发的内部人员。一般该会议为3小时。



    二)实施Scrum的过程简单介绍

    1) 将整个产品的backlog分解成Sprint Backlog,这个Sprint Backlog是按照目前的人力物力条件可以完成的。
    2) 召开sprint planning meeting,划分,确定这个Sprint内需要完成的任务,标注任务的优先级并分配给每个成员。注意这里的任务是以小时计算的,并不是按人天计算。
    3) 进入sprint开发周期,在这个周期内,每天需要召开Daily Scrum meeting。
    4) 整个sprint周期结束,召开Sprint review meeting,将成果演示给Product Owner.
    5) 团队成员最后召开Sprint retrospective meeting,总结问题和经验。
    6) 这样周而复始,按照同样的步骤进行下一次Sprint.

    整个过程如下图所示:




    The diagrams in this article are all from web site: http://www.controlchaos.com/.  Thanks very much!

    参考:
    http://www.controlchaos.com/about/
    http://www.microsoft.com/Taiwan/msdn/columns/200311softdev.htm

  • 1)时间频度
      一个算法执行所耗费的时间,从理论上是不能算出来的,必须上机运行测试才能知道。但我们不可能也没有必要对每个算法都上机测试,只需知道哪个算法花费的时间多,哪个算法花费的时间少就可以了。并且一个算法花费的时间与算法中语句的执行次数成正比例,哪个算法中语句执行次数多,它花费时间就多。一个算法中的语句执行次数称为语句频度或时间频度。记为T(n)。
      (2)时间复杂度
      在刚才提到的时间频度中,n称为问题的规模,当n不断变化时,时间频度T(n)也会不断变化。但有时我们想知道它变化时呈现什么规律。为此,我们引入时间复杂度概念。
      一般情况下,算法中基本操作重复执行的次数是问题规模n的某个函数,用T(n)表示,若有某个辅助函数f(n),使得当n趋近于无穷大时,T(n)/f(n)的极限值为不等于零的常数,则称f(n)是T(n)的同数量级函数。记作T(n)=O(f(n)),称O(f(n)) 为算法的渐进时间复杂度,简称时间复杂度。
      在各种不同算法中,若算法中语句执行次数为一个常数,则时间复杂度为O(1),另外,在时间频度不相同时,时间复杂度有可能相同,如T(n)=n^2+3n+4与T(n)=4n^2+2n+1它们的频度不同,但时间复杂度相同,都为O(n^2)。
      按数量级递增排列,常见的时间复杂度有:
      常数阶O(1),对数阶O(log(2)n),线性阶O(n),
      线性对数阶O(nlog(2)n),平方阶O(n^2),立方阶O(n^3),...,
      k次方阶O(n^k),指数阶O(2^n)。随着问题规模n的不断增大,上述时间复杂度不断增大,算法的执行效率越低。
      (3)算法的时间复杂度
      若要比较不同的算法的时间效率,受限要确定一个度量标准,最直接的办法就是将计算法转化为程序,在计算机上运行,通过计算机内部的计时
      功能获得精确的时间,然后进行比较。但该方法受计算机的硬件、软件等因素的影响,会掩盖算法本身的优劣,所以一般采用事先分析估算的算法,
      即撇开计算机软硬件等因素,只考虑问题的规模(一般用用自然数n表示),认为一个特定的算法的时间复杂度,只采取于问题的规模,或者说它是
      问题的规模的函数。
      为了方便比较,通常的做法是,从算法选取一种对于所研究的问题(或算法模型)来说是基本运算的操作,以其重复执行的次数作为评价算法时间
      复杂度的标准。该基本操作多数情况下是由算法最深层环内的语句表示的,基本操作的执行次数实际上就是相应语句的执行次数。
      一般 T(n)=O(f(n))
      O(1)<O(log2n)<O(n)<O(n log2 n)<O(n^2)<O(n^3)<O(2^n)所以要选择时间复杂度量级低的算法。

    实例说明时间复杂度的计算:

    时间复杂度:算法中基本操作重复执行的次数是问题规模n的某个函数f(n),T(n)=O(f(n))。它表示随问题规模n的增大,算法执行时间的增长率和f(n)的增长率相同。
          语句的频度:是该语句重复执行的次数。

    1:交换ij的内容。
    temp=i; i=j; j=temp;
    以上三条语句的频度均为1,该程序的执行时间是与问题规模n无关的常数,因此算法的时间复杂度为常数阶,记作Tn=O1)。

    2:变量计数。
    (1x=0;y=0;
    (2)for(k=1;k<=n;k++)
    (3)  x++;
    (4)for(i=1;i<=n;i++)
    (5)  for(j=1;j<=n;j++)
    (6)     y++;
     
    以上语句中频度最大的语句是(6),其频度为f(n)= n2,所以该程序段的时间复杂度为T(n)=O(n2)

    3:求两个n阶方阵的乘积C=A×B,其算法如下:
    #define n 100
    void MatrixMultiply(int A[n][n],int B[n][n],int C[n][n])

    { int i,j,k
     for (i=1;i<=n;++i)         /* 次数 n+1 */
    for (j=1;j<=n;++j)          /* 次数 n*(n+1)*/
    { C[i][j]=0;                /* 次数  n2  */
            for (k=1;k<=n,k++)  /* 次数 n2(n+1) */
               C[i][j]=C[i][j]+A[i][k]*B[k][j];/* 次数 n3 */
    }
    }
    T(n)=2n3+3n2+2n+1
    limT(n)/ n3)=2 
    T(n)=O(n3)

    4
    1{++x;s=0;}
    2for (i=1;i<=n;++i) {++x;s+=x;}
    3for (j=1;j<=n;++j)
    4    for (k=1;k<=n;k++){++x;s+=x;}
    (5) i=1; while(i<=n) i=i*2;执行次数f(n)与n的关系是n=2^f(n)

    含基本操作“x1,即语句++x”的语句的频度分别为1,nn2和log2n

    常见的时间复杂度,按数量级递增排列依次为:常数阶O(1),对数阶0(Log2n),线性阶O(n),线性对数阶0(nLog2n),平方阶O(n2),立方阶0(n3),指数阶O(2n)通常认为,具有指数阶量级的算法是实际不可计算的,而量级低于平方阶的算法是高效的。