《编程匠艺》读书笔记之十三

第十五章 改良与革命——代码是如何成长的
  • 软件是一种有生命的实体。
  • 我们确实有机会来反复提高代码的质量,这在某种程度上模拟了进化的过程。
  • 优秀的代码也会遇到糟糕的事情。永远都不要低估代码在其生命周期内出现缺陷和瑕疵的能力。
  • 软件开发的维护阶段通常是软件成长的最长阶段。不管你做什么,最初的代码都会被更改,腐烂就是从这里开始的,这是一种你“做也不是,不做也不是”的情况,不管你做什么,代码都会腐烂。
  • 即使你的确在代码成长的过程中对它进行扩展和修正,它仍然会腐烂,在修正一个错误时,作为副作用,程序员往往会引入更多的缺陷。
  • 要明白随着代码的修改,它有多么容易退化,不要对使系统变得更加糟糕的更改而感到满意。
  • 任何到只代码的清晰度降低或使系统更加复杂的更改,都会造成腐烂。

    以下是一些代码腐烂的信号:
  • 代码中遍布许多大型的类和复杂的函数。
  • 函数的名称很隐晦或者会误导人。
  • 没有任何结构:应该在哪里寻找某个功能非常不清晰。
  • 内容重复:有许多相互独立的代码在做着相同的事情。
  • 高耦合性:复杂的模块相互连接和依赖的关系,意味着在某个地方的小更改会影响整个代码,甚至会影响看起来不相关的模块。
  • 当数据流过系统时,它将在各种表示法之间反复转换。
  • API变得模糊不清。
  • API在不同的代码版本中快速的变化。
  • 公共API中泄露了一部分私有实现。
  • 代码中到处都是权宜之计:治标不治本的修改。
  • 有些函数的参数太多。
  • 你发现代码太可怕了,以至于你都不想去改善它。
  • 添加新功能时没有提供任何支持文档,现有的文档已经过时了。
  • 代码在编译时产生了很多警告信息。
  • 你发现有的注释说:“不要动这段代码”。

  • 我们要学习如何发现腐烂的代码,了解这些内容,并尽一切可能小心的对待腐烂的代码。
  • 我们会把代码弄的一团糟的原因:复杂性。我们没有能够很好的处理这种复杂性。


    我们在开发软件的过程中,总会将新的代码加入到我们的系统中,新代码的加入有以下几种方式:
  • 运气。这是一种最可怕的编码方式,并且极为常见;碰运气的修改可能只是掩盖了即时的问题,却使得以后真正的修改更加困难。
  • 增长。我们需要添加新的功能,正确的添加需要拆开一些重要的模块之间的接口,并修改大量的代码但是工期在那里,我们没有足够的时间,所以我们只是在另外一块代码中进行嫁接,新的功能将挂在现有的某个模块上,并使用它们自己的特殊后门接口与这些模块进行通信。这将称为一个畸形的系统,模块也不会有清晰的角色和职责。
  • 重写。重写往往比对乱作一团的代码胡乱进行修改更加快捷和安全,然而,很少有人选择重写,这需要勇气和眼光。
  • 重新调整。重新调整是对代码主体进行少量修改的过程,其目的是改善代码的内部结构,而不改变它的外部行为;重新调整改善了代码的设计,从而使你将来可以更容易的处理这些代码。
  • 为成长而设计。扩展性是以复杂性为代价的。

  • 一个优秀的管理人员会倾听程序员们的反对意见,而一位优秀的程序员也会想办法让他或她的老板倾听,但是在更多时候,这两种情况都没有发生,最后倒霉的是软件。
  • 我们应该认真负责的编程,优秀的程序员更关心的是经过几年的努力他们的代码会怎样,而不是现在要花多少时间来编写。

    在编写新代码时,我们需要考虑以下问题:
  • 考虑模块之间的相互连接关系,尽量减少耦合性。
  • 模块化和信息隐藏是现代软件工程的基础。
  • 在设计时需要考虑扩展性和可塑性。
  • 编写整洁、清晰的代码,使之易于理解和处理,并且具有良好的文档和定义良好、命名清晰的API。
  • KISS。Keep It Simple Stupid。

    在维护现有代码时,需要考虑以下问题:
  • 将任何需要进行的更改按重要性进行排序。
  • 只进行必要的修改。
  • 监控一次所进行的修改量,自己一个人同时做好多个项目的修改,要么证明你无比聪明,要么证明你无比愚蠢。
  • 审慎的管理修改,确保你知道还有谁要在你正在处理的代码附近进行修改。
  • 修改同样需要被审查,组织正式的审查会议。审查敏感的修改,尤其是在发布的预备阶段,即使是最简单的修改也可能会破坏其他代码。

    对于如何进行代码的修改,有以下建议:
  • 为了进行良好的修改,你必须非常了解你要处理的代码。
  • 采取正确的态度——避免“再试着修改一次吧”的心理,不要因为以为某些代码将来会被抛弃而放弃。
  • 时刻准备好做一些重新设计的工作,不要害怕拆散代码,并且在必要时对它进行大的手术。
  • 尽量不要在添加新代码的同时引入新的依赖关系。
  • 要保留你正在处理的源文件的编码风格,即使这种风格不是你喜欢的风格,也不是公司内部的风格。
  • 使用代码的测试套件来检查是否造成了什么破坏。认真测试你所做的任何修改,不论这个修改有多简单。
  • 如果你准备修正一个缺陷,那么你是否真的明白了它的原因呢。
  • 如果你所做的修改非常糟糕,那么就要尽快的取消它。
  • 作为一个编码高手,你应该尽力避免去做那些快速修补的工作。

  • 与软件本身的质量相比,软件的寿命更多的取决于它所处的市场的状况。开放源码的软件并不能避免这些竞争性的问题和与市场相关的问题。
  • 许多人都把代码行数作为评价开发过程的标准,除非能够给出正确的解释,否则这种衡量标准毫无用处,这仅仅是代码编写量的一个度量,而与代码的质量和设计的正确性无关。
  • 在软件的发展过程中,向后兼容是指兼容就有版本;向前兼容是指兼容将来版本。
  • 代码会在你试图更改它的情况下腐烂的最快,粗心的维护和随意的扩展是会毁掉代码的。
  • 维护代码常常会使代码不可维护。

  • 优秀的程序员:1. 使用清晰的结构和逻辑化的版面,编写可维护的软件;2. 能够确定并时刻准备处理糟糕的代码;3. 在处理代码之前,尽量多的了解它,以及原作者的初始设计理念;4. 关心他们所处理的代码的质量,决绝粗鄙的给代码打补丁。
  • 糟糕的程序员:1. 创建复杂的代码,根本不考虑维护程序员的需求;2. 避免维护旧代码,更愿意忽略问题,而不是解决它们;3. 更喜欢打一个简单的补丁,而不是想出一个好的解决方案;4. 使代码中遍布快速但不严谨的修补,并利用所有他们能找到的捷径;5. 将注意力放在错误的地方,对根本不需要修改的代码进行修补。
posted @ 2008-11-13 22:56  李潘  阅读(368)  评论(0编辑  收藏  举报