• 2009-08-19

    《程序员修炼之道》 第六章 当你编码时 - [新知随笔]

    版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
    http://liuyangsl.blogbus.com/logs/44571745.html

    1. 靠巧合编程
    有些情况下,程序只是由于一些偶然因素才运行得不错。这些程序没有在更极限的边界情况、或是一个新的环境、一个新的扩展下接收考验,甚至没有经过程序员自己的仔细斟酌,这是危险的。

    一些约定上的误解、不规范的测试、文档中隐含的动作,都使程序成为一个巧合的短暂成功。

    一些有效编码的建议:
    <a> 时刻意识到在做什么。
    <b> 不要盲目编程。要按照计划行事。
    <c> 依靠可靠的事物,为所有的假定建立文档。
    <d> 设定工作的优先级,注重难点和基础。
    <e> 不要让已有的代码支配将来的代码,勇于改变。

    ------------------------------------------------------------------------------------

    2. 算法的速率
    通常一个应用中输入的规模会影响到算法的效果。输入越多,越是消耗资源。但是多数时候这种关系并不是线性的。

    O()表示法
    O(n*n)表示随着输入数量的增长,运算消耗将会成平方增长。
    当n不断变大时,O()中一些低阶项可以忽略,比如 O(n*n/2+3n) 和 O(n*n) 等价。

    O()表示法只能表示一种输入量和运算成本之间的关系,并不能表达实际运算速度的优劣,可能O(n*n)比O(n)还要快。

    常用模型:
    <a> 简单循环:O(n)
    <b> 嵌套循环:O(n*n)
    <c> 二分法(比如二叉树搜索):O(lg(n))
    <d> 分而治之(把输入分成两部分,分别处理后再合并在一起,比如快速排序):O(nln(n))
    <e> 组合(考察事物的可能组合方式):阶乘,失去规律控制。

    如果应用的输入是取决于外部输入的,那么即便是简单的循环,都应该仔细考虑使用的资源。嵌套循环更加如此。设法找到低阶的算法来替代高阶的算法。

    如果应用的输入是可控的,低阶算法不一定优于高阶算法,尤其是当低阶算法中有耗费资源的内循环时。
    因此对估算的测试十分重要,牢记要注重实效。

    ------------------------------------------------------------------------------------

    3. 重构
    与建筑相比,软件更像是园艺,更加有机,富于变化。

    当代码出现了一下问题,就需要重构:
    <a> 重复。
    <b> 非正交的设计。
    <c> 过时的知识。
    <d> 性能。

    时间压力并不应阻止重构,花在修补问题上的功夫将远远超出重构的工作量。
    重构要及早进行、经常进行。

    重构也是一项需要慎重、深思熟虑进行的活动,只有在对项目有了更深的理解、知识基础或需求发生了变化时,重构才更有意义。

    重构时应该注意:
    <a> 不要在重构的同时增加功能。
    <b> 重构前后进行良好地测试,保证重构结果的正确。
    <c> 小改动,深思熟虑。不要把程序撕毁。
    <d> 修改所有相关依赖的部分。

    ------------------------------------------------------------------------------------

    4. 易于测试的代码
    软件应该被模块化,且在集成前,每个模块都应该可以被单独测试质量。

    单元测试:在隔离状态下,对每个模块进行测试。单元测试的辅助设施代码可继续用于系统集成测试。
    单元测试的代码应该放在一个与测试对象临近的位置。这样单元测试的代码可以做为例子来说明模块的用法。也方便构建回归测试。

    针对合约进行测试:根据合约编写测试用例,确保单元遵守其合约。

    测试程序应该有以下功能:
    <a> 指定设置和清理。
    <b> 选择个别或所有测试方法。
    <c> 分析输出的正确性。
    <d> 标准化的故障报告。

    软件发布之后,可以通过日志、定义热键、诊断控制窗口等方法,来在实际应用环境中进行测试。

    ------------------------------------------------------------------------------------

    5. 邪恶的向导

    供应商提供的各种编程向导虽然十分快速,但是它屏蔽了太多细节,以至于一旦出现问题,很难入手解决。

    使用向导,要理解向导产生的代码。因为向导产生的代码并不是模块化的,它们和我们自己的代码混杂在一起。


    收藏到:Del.icio.us