《代码大全》阅读笔记-7-高质量的子程序
子程序是为实现一个 特定的目的而编写的一个被调用的方法或过程
创建子程序的正当理由
- 降低复杂度
- 引入中间、易懂的抽象
- 避免代码重复
- 支持子类化
- 隐藏顺序
- 隐藏指针操作
- 提高可一致性
- 简化复杂的布尔判断
- 改善性能
除此之外,创建类的很多理由也是创建子程序的理由
- 隔离复杂度
- 隐藏实现细节
- 限制变化所带来的影响
- 隐藏全局数据
- 形成中央控制点
- 促成可重用代码
- 达到特定的重构目的
好的子程序名字
- 描述子程序所做的所有事情
- 避免使用无意义的、模糊或者表述不清的动词
- 不要仅通过数字来形成不同子程序名字
- 根据需要确定子程序名字的长度
- 给函数命名时要对返回值有所描述
- 给过程起名时使用语气强烈的动词加宾语的形式(面向对象语言中不需要宾语)
- 为常用操作确定命名规则
如何使用子程序参数
-
按照输入->修改->输出排列参数
-
如果几个子程序都用了类似的一些参数,应该让这些参数的排列顺序保持一致
-
使用所有的参数
-
把状态或出错变量放在最后
-
不要把子程序的参数用作工作变量
-
在接口中对参数的假定加以说明(不要等把子程序写完之后再回头去写注释/API先行)
-
把子程序的参数的个数限制在大约7个以内
-
为子程序传递容易维持其接口抽象的变量或对象
-
(尽量)使用具名参数,使参数更加具有自我描述性
-
确保实际参数与形式参数相匹配
使用函数时要特别考虑的问题
函数是指有返回值的子程序;过程是指没有返回值的子程序(语义上)
设置函数的返回值
- 检查所有可能的返回路径
- 不要返回指向局部数据的引用或指针
核对表:高质量的子程序
大局事项
- 创建子程序的理由充分吗?
- 一个子程序中所有适用于单独提出的部分是不是已经被提出到单独的子程序中了
- 过程的名字是否用了强烈、清晰的“动词+宾语”词组?函数的名字是否描述了其返回值?
- 子程序的名字是否描述了它所做的全部事情?
- 是否给常用的操作建立了命名规则?
- 子程序是否具有强烈的功能上的内聚性?即它是否做且只做一件事。并且把它做得很好?
- 子程序之间是否有较松的耦合?子程序与其他程序之间的连接是否是小的、明确的、可见的和灵活的?
- 子程序的长度是否是由其功能和逻辑自然确定,而非遵循任何人为的编码标准?
参数传递事宜
- 整体来看,子程序的参数表是否表现出一种具有整体性且接口一致的接口抽象?
- 接口假定是否已在文档中说明?
- 子程序的参数个数是否没超过7个?
- 是否用到了每一个输入参数?
- 是否用到了每一个输出参数?
- 子程序是否避免了把输入参数用作工作变量
- 如果子程序是一个函数,那么他是否在所有可能的情况下都能返回一个合法的值?
要点
- 创建子程序最主要的目的是提高程序的可管理性,当然也有其他的一些好的理由。其中,节省代码空间只是一个次要的原因:提高可读性、可靠性和可修改性等原因都更重要一些‘
- 有时候,把一些简单的操作写成独立的子程序也非常有价值
- 子程序可以按照其内聚性分为很多类,而你应该让大多数子程序具有功能上的内聚性,这是最佳的一种内聚性
- 子程序的名字是它的质量指示器。如果名字糟糕但恰如其分,那就说明这个子程序设计得很差劲。如果名字糟糕而且又不准确,那么它就反映不出程序是干什么的。不管怎样,糟糕的名字意味着程序需要修改。
- 只有在某个子程序的主要目的是返回由其名字所描述的特定结果时,才应该使用函数
- 细心的程序员会非常谨慎的使用宏,而且只在万不得已的时候才用。
还真有人点开啊🤣随意随意😂