一些编程上的策略
[原文链接]
这里将向大家分享的是一些我对编程的思考总结,这些经验在我毕生编程生涯中曾帮助我在无数的事情上作出正确的决定。这些编程策略有些是很显然的,但实际编程中往往被人们忽略。
下面的例子是用Python写的,但这些概念适用于任何编程语言。
2. 代码优化
找出程序的主执行路径——你的程序大部分时间都执行这些模块。首先优化这部分代码,但也不要在程序实现的第一次迭代中进行优化。那些处理边界情况或失败/异常处理的地方,这部分代码不需要优化,除非它们引起了值得注意的性能问题。 :).
3. 代码行数
不要试图压缩代码行数,但你应该压缩每个任务的代码行数。写简单的函数/方法,每个函数/方法只完成一个任务,而不是多个,除非你有很好的理由。
人们通常喜欢为了减少代码行数而在一个代码片段里完成大量的工作,这会导致代码异常复杂,这种代码试图支持各种情况的处理,而大多时候只是其中的一种情况会发生。多余的情况处理会给执行造成成本。
4. 多学习操作系统和编译器知识
了解机器,理解机器内部里事情是如何工作的。这将会帮助理解各种不同瓶颈产生的原因。这能帮助你找到代码运行时为什么会发生奇怪的现象。
5. 运用管理技术
在编程中运用管理技术。针对不同目的使用正确的工具。我有自己的喜好,但我努力克服。
1. 异常处理和if-else语句的用法
编程的时候,有些边界情况我们需要确保能正确的处理。对这些情况我们通常的做法是使用if
语句来检查是否是这种情况。当程序运行时,这些检查动作每次都会执行,来验证是否是遇到了这些特殊场景。如果你使用的编程语言有异常处理系统——你可以利用它们来处理这些边界情况。
C语言里没有异常处理系统。它依赖于错误码来通知调用的函数发生了什么。返回0是成功,负数则表示失败。所以,调用者需要用if-else
来检查返回码。没有其它的方法。
但对于那些有异常处理系统的编程语言,我们可以很好的利用它们。但我们需要使用if-else
配合异常处理机制来处理这些边界情况或错误。
一个简单的例子 :-
想象有一个后台运行程序,它在启动和停止时都会检查一个pid文件。它会调用下面的函数来获取pid。主调函数使用异常捕获来确保程序逻辑不会出现意外。
下列情况时这个函数会被调用 -
- 这个后台程序启动时
- 这个后台程序停止时
每种情况时主函数要做的事 -
- 启动时
- 如果pid文件存在,意味着后台程序中运行。这个程序自己会停止,会提示有另一个实例已经在运行。
- 读取这个文件时如果返回错误,这说明没有pid文件,说明这个程序没有运行(除非读取文件时发生意外)。这时就创建pid文件,启动程序。
- 停止时
- 如果发现了pid文件,停止前删除这个文件。
如果没有发现pid文件,那该怎么办?这说明后台程序根本没有运行。报告给用户。
下面就是我们上面提到的主程序会调用的获取pid的代码。注意我们使用异常捕获和if-else
语句来处理这些情况。
方法 1
# 这种使用异常的方式不好,属于被动防御式编程。
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
方法 2
# 使用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
方法 3
# 事实上,我们知道可能会发生什么,如果pid读文件
# 文件时有错误,主调函数会捕获它。
# 我们使用的编程语言有异常处理机制。
# 我们可以在这里利用上。
def read_pid_file():
f = open('daemon.pid', 'r')
return int(f.read())
我喜欢方法 3,因为它在大多数情况下都可行。如果极少的情况下出现了错误,主调函数里的异常处理会捕获这种情况。 :).
两种错误处理方式都是我们保证程序无误的重要途径。
- 何时使用
if-else
语句 - 当我们知道可能会有什么情况发生时。也许会分很多种情况。(C语言的错误码机制就是一个很好的例子)。
- 我们通常是基于输入值使用if-else来控制执行路径。
- 何时使用异常处理
- 你想捕获一个异常,或者捕获一些异常但自己不处理,交给系统去处理。支持异常机制的编程语言会在最顶层捕获这些异常,并报告给用户。
6. 忽略上面所有的策略 :).
有时候事情就是这样!而且这样并不一定是坏事。我们编程时经常这样——当我们开发一个新原型,或针对一个特殊问题找一个解决方案,这时我们如何实现并不重要,重要的是在定型后我们如何完成它们。我想大多时候我们都是这样做的。谁都知道,先打草稿,后动真的。
请在评论里留下你对这些观点的想法。