项目管理——Head First 软件开发

Doc 下载: https://download.csdn.net/download/qccz123456/10567658

 

时间:2018年3月22日星期四

作者:清村常争

 

一、伟大的软件开发——让客户满意

         除开宏大的想法外,大多数项目都有两个焦点:要花多少钱?要花多长时间?

         大霹雳式(Big Bang)开发法:集中时间一口气开发完成。通常以一团糟结束,因为没有得到客户心目中的结果。软件开发工作不是玩猜猜看游戏,你必须让客户融入进来,确保你的开发工作在正确的轨道上,明白需求的细节。

伟大的软件开发会交付(1)What is needed客户需求, (2)On Time何时完成, (3)On Budget合同额。

通过开发循环达到目标:你决定每次有重大进展时,你都会与你客户进行确认,并重新确认你下一步要做什么,并且,在没有获得客户的反馈前,你不会做任何重大的决定。如果没有开发循环就会偏离客户的需求。只要你有一段可运行的代码时,就可以和客户进行讨论,尽快产生一个可运行的程序,即使很拙劣,建议的开发循环的时间是20个工作日或一二周。

每个开发循环都是一个微型项目,每个开发循环都会产生有品质的软件:从需求、设计、编码、测试等步骤,到具体每个步骤中完成的各个子阶段,都是一个开发循环。

构建每个开发循环中的每项功能,需要添加一个时间估计值、一个功能优先级。若需求变更,根据新提出的、及剩下的优先级和时间重新安排计划,但在截止日期之前。若具有高优先级功能被提出,最好的选择是将新需求加入到下一个开发循环,并延长软件交付期。但增加开发人员或增加现有开发人员工作时间常常将消耗预算,极少产生所期望的结果。

开发循环步骤:①评估新的功能;②要你的客户对新功能做优先排序;③重新修订你的开发循环计划;④检查项目的截止时间。

开发技术:开发循环有助于你保持在正确的开发轨道上,当需求发生变更时,更新规划和均衡开发循环。每个开发循环都产生有效的软件,并且能从客户那里收集到反馈意见。

        开发原则:交付客户需求的软件;按时地交付软件;符合预算地交付软件。

 

 

二、收集需求——知道客户想要什么

        了解客户需求,并得到使用情节

        (1)倾听客户需求,罗列需求的标题及其细节描述;

        (2)分析理解需求后,提出自身所能想到的问题,并与客户讨论;

        (3)第一次会议后,和团队一起进行头脑风暴,听取他人想法;如果让大家共聚一堂时,没有什么效果,可以与他们分别地进行头脑风暴,然后再集中起来,把众人想法写在白板上,再进行头脑风暴,有时候,可以先散会,思考思考,再开第二次会议。

        (4)采用角色扮演和观察等方法了解客户真正需求;扮演软件、从不同场合进步观察。

        (5)采用客户的语言来撰写需求,简短,易理解,并与客户讨论,最终得到清晰的、以客户为中心的使用情节。

        为每个使用情节添加时间估计值,单位是天数,需要多长时间完成开发,包括设计、编码、测试、交付。

        步骤:①把每个使用情节放在桌子中间;②给每人发13张牌,每张牌上有一个时间估计;③每个人都为使用情节选一个估计值,将与估计值对应的牌翻过来放在桌上;④每人在同一时间把牌翻过来;⑤发扑克牌的人记录下由每个估计值形成的分布;⑥得到一个合理的时间估计值。

        过程中可能存在的问题:① 分布太散可能存在理解错误。②当你不能排除所有假设时,时间估计期间的目标是通过客户澄清假设、排除尽可能多的假设,任何残存的假设都是风险。③珍惜客户时间,客户只需要看到听到你的问题,还有建立起来的使用情节。④试着一次收集好所有假设,然后立刻与客户全部进行澄清,安排一个排除假设的会议,一旦有答案了就进行最后一轮计划扑克牌游戏。⑤当使用情节(每个具体的子任务)的估计值打破了15天的规律(一般不应该超过7天),你可以根据下述做法,择一而行:把使用情节分解为若干个更容易估计的使用情节;与客户进行交流。

        得到合理的时间估计值,重复进行以下步骤:(1)与客户交流(2)进行计划扑克牌游戏(3)澄清假设(4)达成一致。直到大家都相信某个估计值,并且你并不怀疑所做的假设时,就可以在使用情节卡片上记录这个估计值。

        总计总的时间估计值,得到总的交付时间。当时间太长,第三章进行项目计划,得到解决。

        开发技术:共筑愿望,观察和角色扮演使用情节;以计划扑克牌游戏得到估计值。

        开发原则:客户知道他们想要什么,但有时候,你需要帮助他们确定下来;需求总是面向客户;与客户一起,反复地发掘和提炼需求。

 

三、项目计划——为成功而筹划

        将所有的使用情节摊在桌面上,与客户一起确定优先级顺序排序

        在系统的功能和客户的渴望中取得平衡:帮助客户理解在预定的时间内哪些功能可以得到完成,不容置疑,不是所有功能都要在Milestone 1.0版中完成,有些功能的实现可能要推迟到Milestone 2.0或3.0……中去实现。

        与你的客户一起,再对Milestone 1.0版中的使用情节重新按优先顺序排序:(1)缩减更多的功能;(2)尽早交付Milestone 1.0版本;(3)关注基本功能。

        如果你真不能按时完成所需要的软件,并且当你删掉某些使用情节时,客户又不愿意给钱,你可能就要放弃这个项目,至少客户还认为你是诚实的。

        每个新团队成员都需要时间跟上开发项目的步伐,他们需要去理解软件、技术上的决定,以及每件事之间是如何关联的,而当他们做这件事情时,他们是不可能达到100%的生产力的。

        小的开发团队中的人数最多5人,之后人数变多会导致效率变低。

        计算团队开发时间与客户期望时间是否合理,有两种方法:增加人员、减少工作量。采用“人天”为单位,每人每天完成的工作量。

        对使用情节进行优先级排序,并安排入每一个开发循环。每一个开发循环结束后,演示给客户看并从客户那里得到反馈意见。

        开发循环的基本原则:(1)保持开发循环的时间简短(2)保持开发循环均衡,每次开发循环应该是在处理需求变更、增加新功能、发现软件漏洞和了解开发人员的真实工作情况之间取得平衡。采用工作日,而非公历日,还需考虑假期、生病、文字工作等。

        先以0.7的时间效率值计算工作完成的天数,然后将除0.7后的工作量的工作天数(人天)与乘以0.7后团队实际开发时间(人天)进行比较(一个公历月实际上只有14个实际工作日,并且两人天单位指的是在同一单位下将工作量与团队进行比较,工作量当初以一人为单位计算总天数,团队以多人为单位计算总天数),将没有时间完成的任务放入下一个开发循环,最后与客户沟通,实际的开发时间和任务情况。

        如有需要,与客户进一步沟通:(1)为Milestone 1.0再增加一个开发循环(2)解释没有容纳下的工作并没有被丢弃,只是时间上有推迟(3)明明白白地告诉客户,数字是怎么得来的。

        原则:对于达成你所许诺的工作要有信心,你应该谨慎承诺并成功交付而不是过度承诺后导致失败。

        最终,制作大白板:使用情节、已完成、下一个、工作量完成情况趋势图等。工作量完成情况趋势图用来判断是否能按时完成一个Milestone,横坐标是剩余的工作天数(天),纵坐标是剩余的工作量(人天),若实际曲线位于理想直线上方则落后计划。

        注意点:需要平衡工作与生活,越快乐的团队越有生产力;开发人员每天只有三个小时有惊人的生产力。

        开发技术:开发循环理想的时间是不要超过一个月。那就是在每一个开发循环中,你有20个工作日。把时间效率值应用于你的开发计划之中,是你对客户的开发承诺感到更有信心。用一个大的、挂在墙上的白板,计划和监控你的目前的开发循环工作。选择哪些使用情节在Milestone 1.0中去完成,以及哪些情节要安排在哪个开发循环中,都要征求客户意见。

        开发原则:保持开发循环简短并且可管理,最终由客户决定使用情节放进Milestone 1.0,哪些不放进去谨慎承诺,成功交付对客户,诚信至上。

 

 

 

 

四、使用情节和任务——开始你实际的工作

        将使用情节分解为若干任务,并估计任务的时间值,理想估计值应在0.5到5天之间。

        把任务写在白板上,同时增加“正在进行中”和“已完成”的任务状态。

        为每个任务分配工作人员,并将工作人员正在做的工作任务放入“正在进行中”,要做到每个人都有事做,工作任务时间合理。

        设立每天早上的项目进度会议:跟踪任务,更新任务状态,通告昨天情况和今天任务,提出议题,时间5到15分钟。

        每周更新工作量完成趋势图和总已完成量,以判断工作进度是否合理。

        计划外的任务仍然是一项任务,必须要跟踪,和其他任务一样一起处理,与客户沟通,让客户确定计划之外事的优先顺序,并用红颜色标记。

        过程中你的工作量完成趋势图将偏向错误的方向,你一定要知道你工作到哪了,并且一定要让客户也知道你的工作到哪了。

 

 

 

五、足够好的设计——以良好的设计完成工作

        良好的设计有助于你更有生产力,并且使你的软件系统更灵活。       

        重构代码:当代码逻辑杂乱,不利于进一步开发时,需重构代码。方法有:

        (1)单一责任原则(Single Responsibility Principe, SRP):一个对象的方法是该对象它自己能完成的行为或动作,且该行为或动作是该对象的单一责任,而非有多个责任。单一责任指的是责任发生变化时,准确知道代码修改处,并不会引起其他代码一连串修改。

        (2)不自我重复原则(Don`t Repeat Yourself, DRY):不同类之中有相同的方法,就应该重新抽象出新的类,避免重复。譬如FirstDate、SecondDate、ThirdDate抽象为Date。

        项目时间估计中还应有demo的代码或会见对项目有影响力的人。完美的代码虽伟大,但如期交付价更大,注重功能性。

        当每件事得到完成时,开发循环就结束,大白板一次捕捉一个开发循环。

 

 

 

 

 

 

六、版本控制——防御性开发

        对客户而言,已发布的软件的漏洞比实施新的功能具有更高的优先级。漏洞的修复对发布的软件有影响,并且要在正在进行中的软件版本中实施修复。有效的漏洞修复取决于定位出特定的版本,并且在不影响现有开发的情况下,对这些版本进行修改。

        版本中主干是正在进行开发工作的地方,代表软件最新版本。标记附在特定修改项上的名称,方便今后检索。有时需要同样修改分支与主干。分支是代码的副本,用于特定功能开发。

        开发技术:使用版本控制工具以跟踪软件修改并分发给团队的成员。使用标记去跟踪项目的主要里程碑(开发循环的结束、软件的发布、漏洞的修复等)。使用分支去维护代码的独立副本,但只有绝对必要时才做分支(此处指的是需要release出去的分支,但开发人员可以创建多个分支对应多个功能,之后合并分支,另外,最好能锁定文件,那些不能被修改的文件)。

        开发原则:总是知道哪些地方要做修改。知道什么代码应该放到要发布的版本——并且能够再次取得它。控制代码的修改和分支。

        目前,采用git等版本控制工具,Windows可视化管理工具有tortoise等。

/2、构建代码——自动化构建

        构建脚本文件分为四个基本块:项目、属性、目标、任务。

        良好的自动化构建脚本的功能:①生成文档、②编译你的项目、③清理所产生的混乱,另外还应有④项目中需要的参考库、⑤运行应用程序、⑥生成说明文档、⑦调出代码,运行测试,复制构建到归档目录,加密文件,当构建完成时email给你,执行SQL……

        构建脚本也是代码,代码隶属于版本控制系统,在那有版本号和标记,并且被保存以供以后之用。

        自动化构建工具:Makefile、Microsoft Visual Studio的MSBuild等

        开发技术:使用构建工具去构建脚本、打包软件、测试软件和部署你的应用系统。大多数IDE已有构建工具,需熟悉它。对待构建脚本要像对待代码一样,并且把它调入到版本控制系统中。

        开发原则:构建一个项目应该是可重复的和自动化的。构建脚本为其他自动化工具奠定了基础。构建脚本超越了步骤上的自动化,并且能捕捉编译和部署的逻辑决策。

        自动化构建代码,实质是采用自动化构建的工具/脚本,一键式的理清项目依赖并自动安装依赖,理清项目的文件逻辑并自动编译,另外还应包括自动编出文档,自动清理中间/无用文件等功能,从安装、编译、链接、执行、测试、打包、部署等一系列环节进行自动化。

 

 

七、测试和连续集成——智者千虑必有一失

        有三种方法检查系统:(1)用户从外面看系统,黑箱,注重功能性;(2)测试人员探究一点深入的东西,灰箱,注重系统性能情况,如数据的正确性、内存稳定、cpu等;(3)开发人员让系统全透明,白箱,优化代码。

        黑箱测试的重点在输入和输出:①功能性,系统能否按照其使用情节中的要求完成任务。②用户输入验证,各种异常输入,测试系统鲁棒性。③输出结果,给予系统的各类输入以及你期望的每个输出汇集在一张表中。④状态转换,系统能否按预期地从一个状态转移到另一个状态。⑤边界案例与缓存溢出错误,该值或是非常小或是超过了最大允许值。

        灰箱测试注重底层数据与系统性能:①检验审计与登陆,使用登陆浏览工具或审计报告,或可能直接查询数据库表单等内部数据来阅读;②供其他系统使用的数据,应该检查准备传送到其他系统的数据格式和数据等被传输的数据;③系统附加信息,对应用系统而言,创建数据的校验或数据的杂凑以保证数据能正确存储;④残留数据,确认要删除的数据已删除,同时确认不应该被删除的数据没被删除。

        白箱测试是了解被测试的代码后,进行细节性测试,倾向于用代码测试代码:①测试代码的所有逻辑分支;②妥善地处理错误,如非法的数据、资源是否相应的释放等错误信息需要明确化;③按照文档说明运行;④适当处理资源受限状况,如内存、磁盘或网络等。

        需考虑功能性测试、性能测试、边界情况、竞争条件、安全风险、合法数据、非法数据等。

        搭建测试库:①构建测试套件,收集测试所用的工具;②用一个命令执行所有测试;③免费获得回归测试,不仅要测试新添加的代码,也要测试其他所有代码,防止新添的代码对旧代码带来的风险。可以分成快速测试和缓慢测试,测试新添代码和所有代码。

        采用测试框架方便编写测试代码。

        连续集成把版本控制、编译和软件测试囊括在单一的、可重复的流程中。

        通过所有测试,有信心向客户演示构建的系统,只有代码通过所有测试才算完成。

        代码覆盖率:实际测试的代码占全部代码的比例。寻找相关工具进行测试,查看覆盖情况。争取做到85%-90%的覆盖率。良好的测试,测试代码与产品代码比例2:1或3:1。难以测试的功能,如音频、视频等,用真人测试。

        开发技术:你的系统有不同的视角,你必须全部测试到。测试必须说明成功和失败的原因。尽可能让测试自动化。使用持续集成工具使工具构建和测试你的代码自动化。

        开发原则:测试是让你时刻掌握项目状况的工具。持续集成给你信心,确保在你存储目录中正确存放,并且正确构建。代码覆盖率与测试数量相比是对测试有效性的一个较好的度量。

        黑、灰、白箱——功能性、底层、代码覆盖率。

 

八、测试驱动开发——让代码负起责任

        测试驱动开发TDD的宗旨是为特定的功能创建测试程序,然后编写代码满足功能要求。

        开发技术:先编写测试代码,再编写应用程序代码让测试通过。你的测试一开始会失败,然而,在它们通过后,你可以进行重构。使用模拟对象,提供测试需要的各种对象。

        开发原则:TDD迫使你集中于系统的功能性。自动化测试让重构更安全,如果你弄坏了什么,你会立刻知道。良好的低吗覆盖率在TDD中比较容易成功。

九、结束开发循环——涓涓细流归大海

        已经完成:以客户为导向的功能、编译代码、监控开发、持续测试代码、可靠地测试覆盖率、可靠地进展跟踪、适合团队的计划进度。还没完成:流程的改进、系统测试、利用所学的经验重构代码、代码清理和文档更新、更多的设计模式、开发环境更新、研发正在考虑的新技术、搜索新工具或阅读个人开发时间。

        针对不同的工作量完成情况趋势图,分析得到不同的问题和解决方案:图1有许多计划外任务,团队不得删去一些工作或使用情节;图2相吻合;图3低估任务时间,应减少使用情节。

        系统测试在真实环境、黑箱场景中,从前端到后端应用系统的功能性。应该组织不同的人来进行系统测试:开发人员、测试人员、初次接触的人。不要亲自对自己的代码进行系统测试!你太过了解,无法再测试时做到公正。

        在软件开发过程中,你碰到的大多数问题的关键在于沟通。当你有疑惑时,与你的团队、其他团队以及你的客户展开讨论。

        以下二种开发方式各有各的利弊:

  

        有效的系统测试需注意:①在客户、开发团队和测试团队之间保持良好而频繁的沟通。②熟悉系统开始和结束状况。③做好测试文档。④建立清晰的成功标准。⑤只要有可能,采用自动化方式测试。⑥开发团队和测试团队之间合作的动力。⑦测试人员清楚了解整个系统情况。⑧准确无误的系统文档。

        流程:测试人员发现一个软件错误 —> 测试人员提交软件错误报告(细致的步骤和出错信息等)—> 为修复软件错误创建一个使用情节或任务 —> 修复软件错误 —> 检查已经修复的错误,并验证它确实有效 —> 更新软件错误报告。

        软件错误在记录在错误记录器中,包括①摘要、②重现产生错误的步骤、③预期会发生什么和实际发生什么、④版本、平台和定位信息、⑤严重性和优先级。

        额外事情的优先级:①修复软件错误、②提前为下一个开发循环准备使用情节、③为下一个开发循环提供原型解决方案、④培训或学习时间。

        开发技术:注意你的工作量完成状况——尤其在开发循环结束后;开发循环的步调至关重要——需要保持其顺利,可以减少使用情节;别因为有人提起完成工作就处罚他——如果他的工作有效,让他利用额外时间继续向前或者学习新东西。

        开发原则:开发循环是一种设定中间期限的方式——要坚持。总是以平均团队成员的能力估计理想的工作日。规划开发循环时,心中要保持整体图像——那可能会包括系统的外部测试。通过开发循环回顾反复完善你的流程。

 

 

十、下一轮开发循环——无事就要生非

        可运行的软件包括:①完成你的开发循环工作、②通过所有测试、③让你客户满意。

        下一轮开发循环作计划:①额外的使用情节、②重新计算时间效率值、③重新设计工作量完成状况、④下一个使用情节、⑤软件错误。

        步骤:①估算新的时间效率值(重新计算时间效率值,可以更真实地考虑规划下一轮开发循环)。②算出可获得的工作天数。③把新工作填到大白板上(所有未完成或延误的任务或使用情节)。④与客户沟通下一轮使用情节的优先级。

        当谈到软件代码时,别相信别人。除非你亲眼看到代码正常运行,或者针对该代码你执行自己的测试程序,否则别人的代码都是一颗不知何时爆炸的炸弹。一旦整合入你的代码,你就要对它负责。

 

 

十一、软件错误——专业排错

        当第三方合并的代码不能工作时,首先,你必须和客户加强沟通,最好前期就确定第三方代码的可靠性。否则就要评估修正这些错误所用的时间。

        修正的方法:首先,通过之前章节的方法自动化构建代码、版本控制,然后将重心放在那些使用情节所依赖的功能性代码上,最后,还需进行功能性测试。

        评估修正时间的方法,峰值测试估计:通过在一段时间内观察正解决了多少部分问题,以此估计完成其他任务的时间。一段时间最好为一周。从失败的测试中随机选择错误进行修复。在周末计算错误修正速率,接着估算修复全部错误的总时间。最后取团队的平均信心水平,估算得到回旋空间(13-4)/0.8/70%。把排错时间估计值告诉客户,为下一轮开发循环腾出修改时间。

        出色的代码固然很棒,但按时交付测试过、具有可读性的代码更重要。

        成功的含义是开发出客户所需要的东西,使客户高兴。可能在你的代码库中仍有大量代码没被测试,但已经测试了所有使用情节所覆盖的功能性代码。你的代码不必完美,足够好就可以,只要代码中任何问题不会导致软件错误,那就是客户所需要的,就可以得到报酬。

        开发技术:在修改任何一行代码之前,你要确认是可控的和可构建的。当遇到不清楚的代码时,使用峰值测试来估计修复错误所需要的时间。在估计修正剩余的错误所需的工作量时,把团队信心因素考虑其中。运行测试告诉你错误何时被修正好。

        开发原则:诚实地对待客户,尤其有坏消息时。正常运行的软件是要优先考虑的。具有可读性和易理解性的代码是第二要务。如果没有进行代码测试,那就假定它不正常运行。软件中全部代码,甚至不是你写的那些,都属于你的责任。

 

 

十二、真实地世界——落实流程

        大白板——控制进度;使用情节——软件需求;版本控制——多个软件版本;连续集成——可构建编译测试运行;测试驱动开发——保证代码可测试;测试覆盖率——衡量测试方法。

        大多数客户关心的是他们的业务,而不是给你额外的工作。如果你打算把更多的文档资料、项目计划、用户案例等其他东西组织起来,要确认这对客户有帮助、利于团队沟通,那才是对项目有益的。

        使用情节可转换成使用案例(给使用情节增加更多细节),项目计划可使用项目管理软件,类图、类图关系、序列图可转换成设计文档。

        单元测试证明代码能正常运行。系统测试满足客户需求。重构改变代码内部结构,并不影响代码行为。

            

猜你喜欢

转载自blog.csdn.net/qccz123456/article/details/81235238