《代码整洁之道》笔记(二)函数

本文探讨了函数设计的重要原则,包括保持函数短小、使用描述性名称、避免副作用、合理使用异常处理、避免重复代码等,旨在提高代码的可读性和维护性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

函数作为代码中最重要的一环之一,如何让代码从晦涩难懂变得简单易读,是一个必须要考虑的问题。

1. 短小

函数的第一规则是要短小。第二规则是还要更短小。每个函数都应该一目了然,一个函数只说一件事,而且,每个函数都依序把你带到下一个函数。只做一件事的函数无法被合理的切分为多个区段。

2. 代码块和缩进

if语句、else语句、while语句等,其中的代码块应该只有一行。该行大抵应该是一个函数调用语句。这样不仅仅能保持函数短小,而且,因为块内调用的函数拥有较具说明性的名称,从而增强了文档上的价值。这也意味着函数不应该大到足以容纳嵌套结构。所以,函数的缩进层级不该多于一层或两层。

3. 每个函数一个抽象层级

要确保函数只做一件事,函数中的语句都要在同一抽象层级上。

4. 使用描述性的名称

别害怕长名称,长而具有描述性的名称,要比短而令人费解的名称好,要比描述性的长注释好。使用某种命名约定,让函数名称中的多个单词容易阅读,然后使用这些单词给函数取个能说清其功用的名称。命名方式要保持一致。使用与模块名一脉相承的短语、名称和动词给函数名称。

5. 函数参数

最理想的参数数量是零,其次是一,再次是二,应尽量避免三个数量的参数函数。输出参数比输入参数更难以理解。读函数时,我们惯于认为信息通过参数输入函数,通过返回值从函数输出。我们不太期望信息通过参数输出。所以,输出参数往往让人苦思之后才恍然大悟。

(1)如果函数看来需要两个、三个或三个以上的参数,就说明其中一些参数应该封装为类了。

(2)给函数取个好的名字,能较好地解释函数的意图,以及参数的顺序和意图。对于一元函数,函数和参数应形成一种非常良好的动词/名词对形式。例如,write(name)就相当令人认同;assertEqual改成assertExpectedEqualsActual(expected, actual)可能会好些。这大大减轻了记忆参数顺序的负担。

6. 无副作用

函数承诺只做一件事,但还是会做其他被藏起来的事。有时,它会对自己类中的变量做出未能预期的改动。有时,它会把变量搞成向函数传递的参数或是系统全局变量。无论哪种情况,都是具有破坏性的,会导致古怪的时序性耦合及顺序依赖。如果一定要时序性耦合,就应该在函数名称里说明,尽管这样可能会违反“只做一件事”的原则。

7. 分隔指令与询问

函数要么做什么事,要么回答什么事,二者不可得兼。函数应该修改某对象的状态,或是返回该对象的有关信息。

8. 使用异常替代返回错误码

从指令函数返回错误码轻微违反了指令与询问分隔的规则。它鼓励了在if语句判断中把指令当做表达式使用。这不会引起动词/形容词混淆,但却导致更深层次的嵌套结构。当返回错误码时,就是在要求调用者立刻处理错误。另一方面,如果使用异常代替返回错误码,错误处理代码就能从主路代码中分离出来,得到简化。

(1)Try/catch 代码块丑陋不堪。它们搞乱了代码结构,把错误处理与正常流程混为一谈。最好吧try/catch代码块的主题部分抽离出来,另外形成函数。

(2)函数应该只做一件事。错误处理就是一件事。因此,处理错误的函数不该做其他事。这意味着如果关键字try在某个函数中存在,它就该是这个函数的第一个单词,而且在catch/finally代码块后面也不该有其他内容。

9. 别重复自己

重复可能是软件中一切邪恶的根源。许多原则与实践规则都是为控制与消除重复而创建。

10. 结构化编程

每个函数、函数中的每个代码块都应该有一个入口、一个出口。遵循这些规则,意味着在每个函数中只该有一个return语句,循环中不能有break和continue语句,而且永永远远不能有任何goto语句。不过,对于小函数,这些规则助益不大。只有在大函数中,这些规则才会有明显的好处。所以,只要保持函数短小,偶尔出现的return、break或continue语句没有坏处,甚至还比单入单出更具有表达力。另一方面,goto只在大函数中才有道理,所以应该尽量避免使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值