《代码大全2》读书笔记 第七章 高质量的子程序

7 高质量的子程序

7.1 创建子程序的正当理由

  • 降低复杂度。
  • 引入中间、易懂的抽象。
  • 避免代码重复。
  • 支持子类化。(重载)
  • 隐藏顺序。
  • 隐藏指针操作。
  • 提高可移植性。
  • 简化复杂的布尔判断。
  • 改善性能。
  • 创建类的很多理由也是创建子程序的理由。

  • 心理障碍:不情愿为一个简单的目的而编写一个简单的子程序。

7.2 在子程序层上设计

内聚性(cohesion):

  • 功能上的内聚性(functional cohesion):最强也最好的一种内聚性。子程序只执行一项功能。

不够理想的内聚性:

  • 顺序上的内聚性(sequential cohesion):子程序内包含有需要按特定顺序执行的操作,这些步骤需要共享数据,而且只有全部完成才完成一项功能。
  • 通信上的内聚性(communicational cohesion):一个子程序中的不同操作使用了同样的数据,但不存在其他任何联系。
  • 临时的内聚性(temporal cohesion):含有一些因为需要同时执行才放到一起的操作的子程序。

不可取的内聚性:

  • 过程上的内聚性(procedural cohesion):一个子程序中的操作是按特定顺序进行的。
  • 逻辑上的内聚性(logical cohesion):若干操作被放入同一个子程序中,通过传入的标志选择执行一项操作。
  • 巧合的内聚性(coincidental cohesion):子程序中的各个操作之间没有任何可以看到的关联。(无内聚性、混乱的内聚性)。

7.3 好的子程序名字

  • 描述子程序所做的所有事情。
  • 避免使用无意义的、模糊或表述不清的动词。
  • 不要仅通过数字来区分不同的子程序。
  • 根据需要确定子程序名字的长度。
  • 要对返回值有所描述。
  • 用语气强烈的动词加宾语。
  • 准确使用对仗词。
  • 为常用操作确立命名规则。

7.4 子程序可以写多长

  • ……200行顶多了。

7.5 如何使用子程序参数

  • 参数顺序:输入、修改、输出。
  • 考虑创建INOUT关键字。
  • 如果几个子程序都用了类似参数,让他们的排列一致。
  • 使用所有的参数。
  • 把状态或出错变量放在最后。
  • 不要把子程序的参数用作工作变量。
  • 在接口中对参数的断言加以说明。包括:

    • 参数时仅用于输入、要被修改的、还是仅用于输出的。
    • 参数的单位。
    • 没有用枚举的话,状态代码和错误值的含义。
    • 所能接受的数值的范围。
    • 不该出现的特定数值。
  • 参数数量限制在7个以内。

  • 采用某种命名规则。
  • 为子程序传递用以维持其接口抽象的变量或对象。(传整个对象还是其中特定几个参数。)
  • 使用具名参数。(需语言支持)
  • 确保实参和形参匹配。

7.6 使用函数时要特别考虑的问题

  • 语义上:

    • 函数:有返回值。
    • 过程:无返回值。

7.7 宏子程序和内联子程序

  • 把宏表达式整个包含在括号内。
  • 把含有多条语句的宏用大括号括起来。
  • 除非必要,避免使用宏。
  • 用给子程序命名的方法给宏命名,以便需要时用子程序替换宏。
  • C++中,可以用constinlinetemplateenumtypedef等替代宏。
  • 节制使用 inline 子程序。因为它违反了封装原则,也增加了整体代码的长度。