在设计方面,做决定的时候好必须有开发者参与。可是,在一个项目中,它们不应该做所有决定,特别是业务方面的决定。
Decide what you shouldn’t decide.
开发者(及项目经理)能做的一个最重要的决定就是:判断哪些是自己决定不来的,应该让企业主做决定。你不需要自己给业务上的关键问题做决定。毕竟那不是你的事情。如果遇到了一个问题,会影响到系统的行为或者如何使用系统,把这个问题告诉业务负责人。如果项目领导或经理试图全权负责这些问题,要委婉地劝说他们,这些问题最好还是和真正的业务负责人或客户商议。
当你和客户讨论问题的时候,准备好几种可选择的方案。不是从技术的角度,而是从业务的角度,介绍每种方案的优缺点,以及潜在的成本和利益。和他们讨论每个选择对时间和预算的影响,以及如何权衡。无论他们做出了什么决定,他们必须接受它,所以最好让他们了解一切之后再做这些决定。如果时候他们又想要其他的东西,可以公正地就成本和时间重新谈判。
毕竟,这是他们的决定。
“设计”是软件开发过程不可缺少的步骤。它帮助你理解系统的细节,理解不见和子系统之间的关系,并且指导你的实现。
一些成熟的方法论很强调设计,他们希望在开始编码之前,先有完整的设计和文档。另一方面,敏捷方法建议你早在开发初期就开始编码。是否那就意味着没有设计呢?不,绝对不是,好的设计仍然十分重要。画关键工作图是必不可少的,因为要使用类及其交互关系来描述系统是如何组织的。在做设计的时候,你需要画时间去思考各种不同选择的缺陷和益处,以及如何做权衡。
然后,下一步才考虑是否需要开始编码。如果你在前期没有考虑清楚这些问题,就草草地开始编码,很可能会被很多意料之外的问题搞晕。但是,即使之前已经提交了设计文档,也还会有一些意料之外的情况出现,时刻谨记,此阶段提出的设计知识基于你目前对需求的理解而已。一旦开始了编码,一切都会改变。设计及其代码实现会不停地发展和变化。
Design should be only as detailed as needed to implement.
严格的需求-设计-代码-测试开发流程源于理想化的瀑布式开发方法,它导致在前面进行了过度的设计。这样在项目的生命周期中,更新和维护这些详细的设计文档变成了主要工作,需要时间和资源方面的巨大投资,却只有很少的回报。
如果你自己都不清楚所谈论的东西,就根本不可能精确地描述它。
设计可以分成两层:战略和战术。前期的设计属于战略,通常只有在没有深入理解需求的时候需要这样的设计。更确切地说,它应该只描述总体战略,不应深入到程序方法、参数、字段和对象交互精确顺序的具体细节。那应该留到战术设计阶段,它应该在项目开发的时候再具体展开。这时更适合讨论如何设计类的职责。因为这仍然是一个高层次、面向目标的设计。事实上,CRC(类-职责-协作)卡片的设计方法就是用来做这个事情的。
如何知道一个设计上好的设计,或者正合适?代码很自然地为设计的好坏提供了最好的反馈。如果需求有了小的变化,它仍然容易去实现,那么它就是好的设计。而如果小的需求变化就带来了一大批基础代码的破坏,那么设计就需要改进。
Blindly picking a framework is the having kids to save taxes.
在考虑引入新技术或框架之前,先要把你需要解决的问题找出来。你的表述方式不同,会让结果有很大差异。找到了需要解决的问题,接下来就要考虑:
在产品的开发过程中,集成是一个主要的风险区域。让你的子系统不停地增长,不去做系统集成,就等于一步一步把自己置于越来越大的风险中,潜在的分歧会继续增加。相反,尽可能早地集成也更容易发现风险,这样风险及相关的代价就会相当低。而等的时间越长,你也就会越痛苦。
你能集成并且独立
集成和独立不是相互矛盾的,你可以一边进行集成,一边进行独立开发。
使用mock对象来隔离对象之间的依赖关系,这样在集成之前就可以先做测试。用一个mock对象模拟真实的对象(或者子系统)。mock对象就是真实对象的替身,它并不提供真实对象的功能,但是它更容易控制,能够模仿需要的行为,使测试更加简单。
你可以使用mock对象,编写独立的单元测试,而不需要立刻就集成和测试其他系统,只有当你自信它能工作的时候,才开始集成。
当早期就进行集成的时候,你会看到子系统之间的交互和影响,你就可以估算它们之间通信和共享的信息数据。相反,如果你推迟集成的时间,解决这些问题就会变得很难,需要大量和大范围地修改代码,会造成项目延期和一片混乱。
Checked-in code is always ready for action.
在团队里工作,修改一些东西的时候必须很谨慎。你要时刻经济,没错改动都会影响系统的状态和整个团队的工作效率。下面是一个简单的工作流程,可以防止你提交破坏系统的代码:
最好的办法是你有一个持续集成系统,可以自动集成并报告集成结果。持续集成系统就是在后台不停地检出、构建和测试代码的应用。你可以自己使用脚本快速实现这样的方式,但如果你选择已有的免费、开源的解决方案,它们会提供更多的功能且更加稳定。
系统能在你的机器上运行,或者能在开发者和测试人员对机器上运行,当然很好。但是它同时也需要能够部署在用户的机器上,如果系统能运行在开发服务器上,那很好,但是它同时也要运行在生产环境中。
QA should test deployment.
这就意味着,你要能用一种可重复和可靠的方式,在目标机器上部署你的应用。如果现在你还是手工帮助质量保证人员安装应用,花一些时间,考虑如何将安装过程自动化。这样只要用户需要,你就可以随时为它们安装系统。要提早实现它,这样让质量保证团队既可以测试应用,又可以测试安装过程。
有了自动化部署系统后,在项目开发的整个过程中,会更容易适应互相依赖的变化。很可能你在安装系统的时候,会忘记添加需要的库或组建——在任意一台机器上运行自动化安装程序,你很快就会知道什么丢失了。
从第一天起就开始交付
一开始就进行全面部署,而不是等到项目的后期,这会有很多好处。事实上,有些项目在正式开发之前,就设置好了所有的安装环境。
在我们公司,要求大家为预期客户实现一个简单的功能演示——验证一个概念的可行性。即使项目还没有正式开始,我们就有了单元测试、持续集成和基于窗口的安装程序。这样,我们就可以更容易更简单地给用户交互这个演示系统。
在签约之前,就能提供出如此强大的演示,这无疑证明了我们非常专业,具有强大的开发能力。
Requirements are as fluid as ink.
没有人的思想和观点可以及时冻结,特别是项目的客户。就算算他们已经告诉你想要的东西了,他们的期望和想法还是在不停地进化——特别是当他们在使用新系统的部分功能时,他们才开始意识到它的影响和可能发生的问题。这就是人的本性。
此处省略了数值分析中偏微分方程的例子……
应该定期地,每隔一段时间,例如一个迭代,就与客户会晤,并且演示已经完成的功能特性。如果你能与客户频繁协商,根据他们的反馈开发,每个人都可以从中受益。客户会清楚你的工作进度。反过来,他们也会提炼需求,然后趁热反馈到你的团队中。这样,他们就会基于自己进化到期望和理解为你导航,你编写的程序也就越来越接近他们的真实需求。客户也会基于可用的预算和时间,根据你们真实的工作进度,排列任务的优先级。
维护项目术语表(Wiki规格)
不一致的术语是导致需求误解的一个主要原因。企业喜欢用看似普通浅显的词语来表达非常具体、深刻的意义。
团队中的程序员们使用了和用户或者业务人员不同的术语,最后因为“阻抗失调”导致Bug和设计错误。这样的事情经常发生。
为了避免这类问题,需维护一份项目术语表。人们应该可以公开访问它,一般是在企业内部网或者Wiki上。
在项目开发过程中,从术语表中为程序结构——类、方法、模型、变量等选择合适的名字,并且要检查和确保这些定义一直符合用户的期望。
跟踪问题(工作项)
随着项目的进展,你会得到很多反馈——修正、建议、变更要求、功能增强、Bug修复等。要注意的信息很多,随机的邮件和潦草的告示帖上无法应付的。所以,要有一个跟踪系统记录所有这些日志。
统一过程和敏捷方法都使用迭代和增量开发。使用增量开发,可一次开发应用功能的几个小组。每一轮的开发都是基于前一次的功能,增加为产品增值的新功能。这时你就可以发布或者演示产品。
迭代开发式是,你在小且重复的周期里完成各种开发任务:分析、设计、实现、测试和获得反馈,所以叫做迭代。
Show me a detailed long-term plan and I will show you a project that’s doomed.
对付大项目最理想的办法就是小步前进,这也是敏捷方法的核心。大步跳跃大大的增加了风险,小步前进才可以帮助你很好地把握平衡。
大部分用户都希望现在就有一个够用的软件,而不是在一年之后,得到一个超级的好软件,确定使产品可用的核心功能,然后把它们放在生产环境中,越早找到用户的手里越好。
询问用户哪些是产品可用且必不可少的核心功能,不要为所有可能需要的华丽功能而分心,不要沉迷于你的想象而去做那些华而不实的用户界面。有一堆的理由,值得你尽快把软件交到用户手中:只要交到用户手里,你就有了收入,这样就有更好的理由,继续为产品投资了。从用户那里得到的反馈会让我们进一步理解什么是用户真正想要的,以及下一步该实现哪些功能。也许你会发现一些过去认为重要的功能,现在已经不再重要了。
使用短迭代和增量开发可以让开发者更加专注于自己的工作,如果别人告诉你有一年的时间来完成系统,你会觉得时间很长,如果目标很遥远,又很难让自己去专注于他。在这个快节奏的社会,我们都希望更快地得到结果,希望更快的见到有形的东西。这不一定是坏事。相反,他会使一件好事,只要把它转换成生产率和正面的反馈。
A fixed price guarantees a broken promise.
固定价格的合同会是敏捷团队的一大难题,我们一直在讨论如何用持续、迭代和增量的方式工作。但是现在却有些人跑过来,想提早知道他会花费多少时间及多少成本。软件项目,天生就是变化无常的,不可重复。如果要提前给出一个固定的价格,就几乎肯定不能遵守开发上的承诺。
根据自己的处境,选择不同的战略。
对客户来说,这种方式的好处是项目不可能会死亡。他们可以很早的看到工作的进度或者不足之处。他们总是可以控制项目,可以随时停止项目,不需要缴纳任何违约金。他们可以控制先完成哪些功能,并能精确的知道需要花费多少资金。总而言之客户会承担更低的风险。
原文:https://www.cnblogs.com/fr-ruiyang/p/11380367.html