关于敏捷开发的26个心得
用例一全然可以执行后再开发用例二。厨房里有一种说法正好可以印证这个问题:“做好一盘菜后你再做下一盘”. 对于软件开发来说一个最大的问题就是人们喜欢并行开发多个任务。
由于不可避免的,我们设计的功能中总会有一部分会被放弃砍掉,假设提前开发。非常可能做无用功。
一次仅仅开发一个用例(或非常少几个用例,这依据你的开发团队的大小而定)。 让这个用例功能完整; 让对应的測试用例都能通过。 对应的文稳都补齐; 仅仅有在当前的用例全然开发完毕后,才做为一个总体提交到版本号库。才进行下一个用例。
避免提交一个半成品。 这一点大家似乎都知道。但这条原则必须列入不论什么一个开发指导里。 可以听取这些忠告进行开发測试然后提交代码的程序猿一定不会发生代码提交到版本号库使整个项目无法编译码通过情况。
假设系统编译失败。那一定是有人抄近道到了。
一定不要在没有使用例的情况下往类里加入成员方法。 这跟上面一条极其相似,除了这里针对的是数据成员。
开发者非常easy想到:一个‘客户记录’里应该有‘送货地址’的信息,但一定不要在没有不论什么用例要求这个属性的时候实现这个属性。
敏捷开发的目的是应对客户需求的不确定。
开发前期你不可能获到所有的信息。 你应该尽可能的迟延做决定的时间,但一旦到了你该做决定的时候,你应该当机立断。让项目向前推进。 你不能说一直等到有了足够的信息才做决定。 相反,你要依赖现有的信息作出最正确们决定。 之后,当有新的信息出现后,不要害怕对曾经的决定作出更改。 (老辈人有的称之为触发器,但我称之为随环境而变)
不断的了解怎样改进系统。 这项工作没有尽头。你应该做好思想准备,持续不断的寻找能够改进的地方。收集各种关于怎样找到质量问题、解决质量问题的案例。
审查,审查,审查。 敏捷开发能够帮助我们应对需求在将来的不确定。但过去的事情也存在不确定性。 測试工作永远不能停下来。 程序每次执行的表现都要被评审和记录。
软件的设计要以人为本,而不是系统。 非常多开发者退而求其次、以技术为中心,让设计为技术服务。 永远不要忘记软件的终极目标是什么,是帮助人们完毕工作。
測试是产品的一部分。 很多开发者和经理都觉得产品就是你打包给客户的东西,其余的都不重要。 事实上測试也应该看作是产品的实际一部分,应该在设计时给予相当的重视,甚至,在非常多时候,測试功能也应该同产品一起提交给客户。 (后面说的这部分非常多人都不认可,一个内置的能自我測试软件包并不会占用多少额外的资源。但当你须要用到它时,你会发现它的巨大价值。)
先写測试用例,后写代码。 測试用例能够用来精确的说明我们的设计需求。 非常多时候我们都是通过执行測试用例后发现我们的设计中存在问题。 想想吧,先写測试用例后编码能节省多少时间。
可是:写完測试用例1,然后编写用例1,完后才開始用例2。
清理垃圾代码。 非常显然。又是一个尽人皆知的道理,但它也必须写入不论什么的开发原则里。由于它是如此的重要。 查找垃圾代码的工作永远没有尽头,找到它,消灭它。 要去除掉全部的不能给实际用户带来价值的代码。
假设你不能指出某段代码对用户有什么用处,那它非常可能就是无用的。
培养对集成失败问题马上做出反应的习惯。 你要明确,当集成构建失败时,它会影响项目中的每个人,所以没有比让核心程序能正确的集成和測试通过更重要的事情了。 我以前见到过有的团队的集成构建中断几个月都不去管它,由于他们有其它的工作要做。 每个人都在忍受这样的情况,但没人採取措施。
我们应该明确,应该广泛的认识到,仅仅要做出一点点工作。整个的团队会因此得到很大的回报。
团队的每一个成员都要知道客户的需求。 大型复杂的项目必需要切割到几个独立的团队去开发,然后派发到每一个开发者的手中,但这绝对不能变成程序猿能够不明确终于产品的使用用户的需求和目标是什么。
把意义相关的东西放在一起。
组织好代码,让高度相关的东西都放在一起,也就是放在一个类里。
这是标准的面向对象设计原则里的封装的概念。 理想情况下,类之外的程序并不须要知道类里面的工作细节。 有些开发者喜欢把代码放到好几个文件中,这样是为了按还有一种方式组织它们:比如把同样的数据类型的放到一起,或按字母顺序分类。 举个样例。有人会把全部的常量放在单独一个包下的一个类里,他们这样做毫无必要。添加了程序的复杂性。
依照指导原则。它们应该依照相关性进行分组,从而降低复杂性。
先測试后提交代码。
这个准则能让你确保“永远不要让集成构建失败”的准则。
最小化未完毕的编码任务的工作包(backlog)。
当开发者开发一个设计用例时。有的功能会牵涉到全部改动着的但未全然开发完毕、充分測试的代码。 把未改动完毕的代码保存到本地数天或数星期,这样添加了工作浪费的风险。会出现返工。 想象有三个任务,每一个预计都要一天。
假设三个一起开发。并行起来每一个都须要3天。这样一累计会有9个’单位’的风险。 假设顺序的开发,一个开发完毕后再开发还有一个。仅仅会有3个‘单位’的风险。 这个并不符合我们的直觉。 我们的直觉告诉我们,当我们在这样的情况下时,我们希望三个一起完毕。 可是软件不像盖房子。
小的、迅速的、完整的任务不只会降低我们的认知负荷,也降低了进行中的开发对其它人正在进行的开发的相互影响。
不要过度功能范化。 也就是我们所说的 “YAGNI – You Aren’t Going to Need It” 。 程序猿在编写一个类时喜欢料想:这个类可能在其他地方其他类中会有其他用途用. 假设这些用途是被当前的用例用到。那这样思考是没错的,但经常开发者想到的这些用途都是眼下不存在的用途,实际上可能是永远不会用到的用途。 (This subject always reminds me of the classic Saturday Night Live skit about the product which was both a floor wax, and a dessert topping.)
假设两行代码能完毕就不要写成三行。
简洁的代码永远都会给须要阅读这段代码的人带来优点。 但千万不要把代码压缩的难以理解了。 精简的、书写规范的代码易于维护和查找错误。冗长的、太多修饰的代码则相反。
尽可能的简化但不要过度。
永远不要按行数多少来评价代码头。 编写某个任务所产生的代码行数会因程序猿而异,因编码风格而异。 代码的行数不会提供不论什么关于程序完毕情况和代码质量的信息。 代码质量能够相差200倍之多,这是计算代码行数的方法不能胜任的。 应该计算功能性的用例数。
我们应不断的再设计、再分析。
应用这一条时你要非常的小心。由于有些代码非常脆弱、难以维护。但不要害怕改动这些代码、让它符合真正的需求。 一个数据成员曾经是整数型的,但如今有个用例须要它是浮点型,不要害怕去改变它,仅仅要你按步骤:測试。写文档,布署。
删除死代码。
当发现有一大段不能理解的代码时我们习惯的做法是“让死狗躺在哪”。
比方说,我们须要往类里加入一个新方法来替换曾经的旧方法。通用人们会保留老方法‘以防不測’。
事实上。我们应该花一些功夫去检查看看这个老方法是否还实用。假设没有证据显示它还实用,就该删掉它。
更糟糕的错误做法是把这些代码凝视掉。留下一堆凝视码。
凝视掉的代码一旦发现就该被删掉。不能留到測试时还有、甚至提交到代码库。 加入代码总是easy的,删除代码总是困难的。 因此,一旦发现有可能无用的代码。你应该花点时去确认它、删除它,这样会让代码更加可维护。
不要自创新语言。 程序猿喜欢使用文本文件来实现功能性的趋动,这样能够使程序变的可配置。
通过配置文件来改变软件行为所产生的后果是只是控的。 XML的诞生促使了一系列的特别的自己定义的‘脚本语言‘的出现,人们试图通过文件的配置以让终于用户‘编程’来控制软件的功能、避免又一次编译。 这样的设计上的缺陷是:软件里的各种操作的准确定义在脱离了详细上下文的特定实现的情况下不可能被准确的定义。这些各式各样的脚本型语言仅仅是对那些对软件代码的内部工作机理有着相关的知识背景的人才会价值。 所以,真正的终于用户是不可能知道软件的内部工作机理的,不可能推理出这些复杂的指令组合会产生什么样的预期结果。 脚本有它的用途,也不应该被抵制,但设计人员必须以很很安全的方式使用它们,尽可能使用现有的语言,必免使用新发明的语言。
仅仅有当准备好了实现和測试才去确定设计。 我应该有一个整体的认识我们要做什么,应该有个整体架构目标。而不是具体设计、具体的具体方法的实现,仅仅有当开发迭代到一定程度后、足以让我们定下设计细节后才去把它表现成文档。 具体设计仅仅应该包含当前需求用例中须要覆盖的部分。
软件开发中最大的浪费就是你花时间设计出来东西后被告知不须要了,或者是你的设计一開始就建立在错误的如果上。
软件是可塑的。
软件不像盖房子。我们能够轻易的改的面目全非。 无数事实表明软件比它的规格说明书善变的多。 并且,软件产品和设计之间的互动明显比规格说明书有效率。 所以,你应该直接实现你的设计,这样客户就能非常easy明确你的设计细节。
当发现有问题、要改变设计时。改动软件要比改动文档easy的多。
更重要的是。当客户看到了能执行的程序后,你也就更能搞清客户的需求是什么了。
设想假设仅仅是作者自己会遇到这样的错误,他会记得这样的一直使用的错误描写叙述信息是什么意思。 但站在客服技术支持的处境,他们由于这样的不准确的、不完整的错误描写叙述浪费了大量时间。
这些信息应该达到让一个刚走进屋里没有不论什么经验的人能看明确的程度。 客户和客服基本都是对编程不懂的人。