赞
踩
破窗户
一扇破窗户,只要有那么一段时间不修理,就会渐渐给建筑的居民带来一种废弃感,于是又一扇窗户破了,人们开始乱扔垃圾,出现了乱涂乱画,严重的结构损坏开始了,在相对较短的一段时间里,建筑就被损毁得超出了业主愿意修理的程度,而废弃感成了现实。
不要留着“破窗户”(低劣的设计,错误决策,或是糟糕的代码)不修。发现一个就修一个,如果没有足够的时间进行适当的修理,就用木板把它打起来,或许你可以把出问题的代码放入注释,或是用虚设的数据加以替代,采取某种行动防止进一步的损坏,并说明情势处在你的控制之下。
我们喜欢把程序员所指导的关于计算技术和他们所工作的应用领域的全部事实、以及他们的所有经验视为他们的知识资产,管理知识资产与管理金融资产非常相似。
重复劳动是怎样发生的?
- 强加的重复劳动。开发者觉得他们无可选择----环境似乎要求重复劳动。
- 无意的重复劳动。开发者没有意识到他们在重复信息。
- 无耐性的重复劳动。开发者偷懒,他们重复劳动,因为那样似乎更容易。
- 开发者之间的重复劳动。同一团队或不同团队的几个人重复了同样的信息。
你所需要做的是营造一种环境,在其中找到并复用已有的东西,比自己编写更容易。如果不容易,大家就不会去复用。而如果不进行复用,就会有重复劳动的风险。
如果你想要制作易于设计、构建、测试及扩展的系统,正交性是一个十分关键的概念。一旦学会了直接应用正交性原则,你将会发现,你制作的系统的质量立刻就得到了提高。“正交性”是从几何学中借来的术语,如果两条直线相交成直角,它们就是正交的。在计算技术中,该术语用于表示某种不相依赖性或是解耦性。如果两个或更多事物中的一个发生变化,不会影响其他事物,这些事物就是正交的。在设计良好的系统中,数据库代码与用户界面是正交的,你可以改动界面,而不影响数据库,更换数据库,而不用改动界面。
我们想要设计自足的组件:独立,具有单一、良好定义的目的。如果组件是相互隔离的,你就知道你能够改变其中之一,而不用担心其余组件。只要不改变组件的外部接口,就不会造成波及整个系统的问题。编写正交的系统有两个好处:提高生产效率与降低风险。
bug是你的过错还是别人的过错,并不是真的很有关系,它仍然是你的问题
对于许多开发者、调试本身是一个敏感、感性的话题。你可能会遇到抵赖、推诿、蹩脚的接口、甚或是无动于衷,而不是把它当作要解决的难题发起进攻。
要接受事实:调试就是解决问题,要据此发起进攻。
发现了他人的bug之后,你可以花费时间和精力去指责让人厌恶的肇事者,在有些工作环境中,这是文化的一部分,并且可能是“疏通剂”。但是,在技术竞技场上,你应该专注于修正问题,而不是发出指责。
当木匠面临一再地重复制作同一样东西的任务时,他们会取巧。他们给自己建造夹具或模板,一旦他们做好了夹具,他们就可以反复制作某样工件,夹具带走了复杂性,降低了出错的机会,从而让木匠能够自由地专注于质量问题。
作为程序员,我们常常发现自己也处在同样的位置上。我们需要获得同一种功能,但却是在不同的语境中。我们需要在不同的地方重复信息。有时我们只是需要通过减少重复的打字,使自己免于患上腕部劳损综合症。
以与木匠在夹具上投入时间相同的方式,程序员可以构建代码生成器。一旦构建好,在整个项目生命期内都可以使用它,实际上没有任何代价。
代码生成器有两种主要类型:
代码生成器不一定要很复杂,最复杂的部分通常是负责分析输入文件的解析器。让输入格式保持简单,代码生成器就会变得简单。
代码生成器不一定要生成代码,可以用它生成几乎任何输出:HTML、XML----可能成为项目中别处输入的任何文本。
在计算技术简短的历史中,没有一个人曾经写出过一个完美的软件。你也不大可能成为第一个。
我们不断地与他人的代码结合----可能不符合我们的高标准的代码----并处理可能有效,也可能无效的输入,所以我们被教导说,要防卫性地编码。如果有任何疑问,我们就会验证给予我们的所有信息,我们使用断言检测坏数据。我们检查一致性,在数据库的列上施加约束,而且通常对自己感到相当满意。但注重实效的程序亚un会更进一步,他们连自己也不信任,知道没有人能编写完美的代码,包括自己,所以注重实效的程序员针对自己的错误进行防卫性的编码。
“这些代码不会被用上30年,所以用两位数字表示日期没问题。”“这个应用决不会在国外使用,那么为司马要使其国际化?”“count不可能为负”“这个printf不可能失败”
无论何时发现自己在思考“但那当然不可能发生”,增加代码检查它,最容易的方法是使用断言。当然,传给断言的条件不应该有副作用,还要记住断言可能会在编译时被关闭----决不要把必须执行的代码放在assert中。
不要用断言代替真正的错误处理,断言检查的是绝不应该发生的事情。
细节会弄乱我们整洁的代码----特别是如果它们经常变化。每当我们必须去改动代码,以适应商业逻辑、法律或管理人员个人一时的口味的某种变化时,我们都有破坏系统或引入新bug的危险。所以说“把细节赶出去”,把它们赶出代码,当我们在与它作斗争时,我们可以让我们的代码变得高度可配置和“软和”,也就是,容易适应变化。
元数据是什么?严格地说,元数据是关于数据的数据。最常见的例子可能是数据库schema或数据词典。schema含有按照名称、存储长度及其他属性,对字段进行描述的数据。
我们的目标是以声明方式思考(规定要做什么,而不是怎么做),并创建高度灵活和可适应的程序。我们想要尽可能多地通过元数据配置和驱动应用。我们的目标是以声明方式思考(规定要做什么,而不是怎么做),并创建高度灵活和可适应的程序。我恶魔年通过采用一条一般准则来做到这一点:为一般情况编写程序,把具体情况放在编译的代码库之外。这种方法有若干好处:
假定警探已开始在会议室放置了一个大黑板,为侦破案件在上面写下线索,随着资料的累积,某位侦探可能会注意到某种关联,并张贴他的看法和推断,这个过程持续进行,直到案件了结。
黑板方法的一些关键特性:
- 没有侦探需要知道其他任何侦探的存在,他们查看黑板,从中了解新的信息,并且加上他们的发现。
- 侦探可能接受过不同的训练,具有不同程度的教育背景和专业经验,甚至有可能是在同一管辖区工作。他们都渴望破案,但这就是全部共同点。
- 在这个过程中,不同的侦探可能会来来去去,并且工作班次也可能不同。
- 对放在黑板上的内容没有什么限制,可以是图片、判断、物证等等。
我们可以用黑板协调完全不同的事实和因素,同时又使参与方保持独立,甚至隔离。
当然,可以用更蛮力的方法获得相同的结果,但得到的将是更脆弱的系统,当它出故障时,出动所有人马也许都无法使你的程序再工作起来。
也可以使用工作流系统,设法处理每一种可能的组合和情况,存在许多这样的系统,但它们可能会很复杂,并且需要许多程序员。当规章制度发生变化时,工作流也必须重新组织:人们也许必须改变他们的流程,硬性连接的代码也许必须重写。
数据到达的次序无关紧要,在收到某项事实时,它可以触发适当的规则,反馈也容易处理,任何规则集的输出都可以张贴到黑板上,并触发更为适用的规则。
O()表示法时处理近似计算的一种数学途径,当我们写下某个特定的排序例程对n个记录进行排序所需的时间是O(n2)时,我们的意思是,在最坏的情况下,所需时间随n的平方变化,使记录数加倍,时间大约将增加4倍,把O视为“阶为。。。”的意思。O(n)表示法对我们在度量的事物(时间、内存等等)的值设置了上限,如果我们说某函数需要O(n2)时间,那么我们就知道它所需时间的上限不会比n2增长得更快。有时我们会遇到相当复杂的O()函数,但因为随着n的增加,最高阶的项主宰函数的值,习惯做法是去掉所有低阶项,并且对任何常数系数都不予考虑,O(n2/2+3n)和O(n2/2)一样,后者又与O(n2)等价。这实际上是O()表示法的一个弱点,某个O(n2)算法可能比另一个O(n2)算法要快1000倍,但你从表示法上却看不出来。
可以使用常识估算许多基本算法的阶
最好的并非总是最好的
假定输入集很小,直截了当的插入排序的性能将和快速排序一样好,而你用于编码和调试的时间将更少。如果你的选择的算法有高昂的设置开销,你也需要注意,对于小输入集,这些设置时间可能会使运行时间相形见绌,并使得算法变得不再适用。
大多数开发者都讨厌测试。许多团队都会为他们的项目精心制定测试计划。我们发现,使用自动测试的团队成功的机会要大的多。与待在架子上的测试计划相比,随每次构建运行的测试要有效得多。
事实上,好的项目拥有的测试代码可能比产品代码还要多,编写这些测试代码所花的时间是值得的。长远来看,它最后会便宜得多,而实际上有希望制作出接近零缺陷的产品。此外,知道你通过了测试将给你高度的自信:一段代码已经“完成”了。
测试什么
怎样测试
何时测试
许多项目往往会把测试留到最后一分钟----dead-line马上就要来临时,我们需要比这早的多地开始测试,任何产品代码一旦存在,就需要进行测试。大多数测试都应该自动完成。通常,只需要回归地运行各个单元测试和集成测试,这并不成问题。但有些测试肯呢个不容易这样频繁地运行,例如,压力测试肯呢个需要特殊的设置或设备,以及某种手工操作。这些测试的运行可以不那么频繁,但让它们按照计划定期运行,这很重要,如果无法自动完成,那就确保让它出现在计划中,并给这项人物分配所需资源。
某公司宣布利润创记录,其股价却下跌了20%,当晚的金融新闻解释说,该公司没有实现分析家预期的业绩。一个小孩打开昂贵的圣诞礼物,却大哭起来,这不是他想要的廉价玩具。某个项目团队奇迹般地实现了一个极其复杂的应用,但却遭到用户的抵制,因为该应用没有帮助系统。在现实中,项目的成功是由它在多大程度上满足了用户的期望来衡量的。不符合用户预期的项目注定是失败的,不管交付的产品在绝对的意义上有多好。但是,像希望得到廉价玩具的小孩的父母一样,你走得太远也会失败。
用户在一开始就会带着他们对所需要的东西的想象来到你面前,那可能不完整、不一致、或是在技术上不可能做到,但那时他们的,而且就像过圣诞节的小孩一样,他们也在其中投入了一些感情,你不能简单地忽视它。随着你对他们的需要的理解的发展,你会发现在他们的有些期望无法满足,或是他们的有些期望过于保守。你的部分角色就是要就此进行交流。与你的用户一同工作,以使他们正确地理解你将要交付的产品,并且要在整个开发过程中进行这样的交流。决不要忘了你的应用要解决的商业问题。
如果你和用户紧密协作,分享他们的期望,并同他们交流你正在做的事情,那么当项目交付时,就不会发生多少让人吃惊的事情了。这是一件糟糕的事情,要设法让你的用户惊讶。请注意,不是惊吓他们,而是要让他们高兴。给他们的东西要比他们期望的多一点,给系统增加某种面向用户的特性所需的一点额外努力将一次又一次在商誉上带来回报。只是要记住,不要因为增加新特性而破坏了系统。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。