下面介绍的方法《编程珠玑》里也有所提及
下面的例子是用Python写的,但这些概念适用于任何编程语言。
找出程序的主执行路径——你的程序大部分时间都执行这些模块。首先优化这部分代码,但也不要在程序实现的第一次迭代中进行优化。那些处理边界情况或失败/异常处理的地方,这部分代码不需要优化,除非它们引起了值得注意的性能问题。 .
不要试图压缩代码行数,但你应该压缩每个任务的代码行数。写简单的函数/方法,每个函数/方法只完成一个任务,而不是多个,除非你有很好的理由。
人们通常喜欢为了减少代码行数而在一个代码片段里完成大量的工作,这会导致代码异常复杂,这种代码试图支持各种情况的处理,而大多时候只是其中的一种情况会发生。多余的情况处理会给执行造成成本。
了解机器,理解机器内部里事情是如何工作的。这将会帮助理解各种不同瓶颈产生的原因。这能帮助你找到代码运行时为什么会发生奇怪的现象。
在编程中运用管理技术。针对不同目的使用正确的工具。我有自己的喜好,但我努力克服。
编程的时候,有些边界情况我们需要确保能正确的处理。对这些情况我们通常的做法是使用if
语句来检查是否是这种情况。当程序运行时,这些检查动作每次都会执行,来验证是否是遇到了这些特殊场景。如果你使用的编程语言有异常处理系统——你可以利用它们来处理这些边界情况。
C语言里没有异常处理系统。它依赖于错误码来通知调用的函数发生了什么。返回0是成功,负数则表示失败。所以,调用者需要用if-else
来检查返回码。没有其它的方法。
但对于那些有异常处理系统的编程语言,我们可以很好的利用它们。但我们需要使用if-else
配合异常处理机制来处理这些边界情况或错误。
一个简单的例子 :-
想象有一个后台运行程序,它在启动和停止时都会检查一个pid文件。它会调用下面的函数来获取pid。主调函数使用异常捕获来确保程序逻辑不会出现意外。
下列情况时这个函数会被调用 -
每种情况时主函数要做的事 -
如果没有发现pid文件,那该怎么办?这说明后台程序根本没有运行。报告给用户。
下面就是我们上面提到的主程序会调用的获取pid的代码。注意我们使用异常捕获和if-else
语句来处理这些情况。
# 这种使用异常的方式不好,属于被动防御式编程。 def read_pid_file(): try: f = open('daemon.pid', 'r') pid = int(f.read()) return pid # 没有发现文件,也可能是IO错误 except IOError: raise "Faild to Read file" # 有人在文件里放的不是数字,这能怪谁? except ValueError: raise WrongPID # 捕获所有其它异常 # 这个有点像 # 过度使用异常处理 except Exception: raise SomeUnKnownError
# 使用If/else方法。主调函数需要检查无返回值情况 # 异常情况 def read_pid_file(): if os.path.exists('daemon.pid'): try: f = open('file.pid', 'r') # 对于支持异常处理机制的编程语言, # 如果有操作失败,抛出异常 # 这里跟C语言有区别 return int(f.read()) except (ValueError, IOError): pass
# 事实上,我们知道可能会发生什么,如果pid读文件 # 文件时有错误,主调函数会捕获它。 # 我们使用的编程语言有异常处理机制。 # 我们可以在这里利用上。 def read_pid_file(): f = open('daemon.pid', 'r') return int(f.read())
我喜欢方法 3,因为它在大多数情况下都可行。如果极少的情况下出现了错误,主调函数里的异常处理会捕获这种情况。 .
两种错误处理方式都是我们保证程序无误的重要途径。
if-else
语句
有时候事情就是这样!而且这样并不一定是坏事。我们编程时经常这样——当我们开发一个新原型,或针对一个特殊问题找一个解决方案,这时我们如何实现并不重要,重要的是在定型后我们如何完成它们。我想大多时候我们都是这样做的。谁都知道,先打草稿,后动真的。
请在评论里留下你对这些观点的想法。