|更简洁,更优雅,但是很难看懂的代码

|更简洁,更优雅,但是很难看懂的代码

文章图片

|更简洁,更优雅,但是很难看懂的代码

文章图片

|更简洁,更优雅,但是很难看懂的代码

文章图片

|更简洁,更优雅,但是很难看懂的代码

似乎有些人将我几个月前的一篇文章的标题”更干净、更优雅、更错误”解释为对异常使用的一则引用 。(请看参考书目参考[35
;请注意 , 引用者甚至将我的文章的标题改了!)
如你所看到的 , 今天文章的标题是对我从一本书中引用的一段代码 , 这本书的作者声称他提供的代码”更干净、更优雅” 。我指出 , 这段代码片段不仅更干净、更优雅 , 而且也是错误的 。
你可以编写正确的基于异常的程序 。
但是我得提醒你了:这不是一件容易的事情 。
换句话说 , 某件事很难 , 但不意味着不应该做这件事 。
下面我们看一个例子:

不管使用哪一种错误模型 , 编写一段坏代码都很容易 。
编写一段基于错误代码的代码很困难 , 因为你需要检查每个调用的返回值 , 并思考如果错误发生时 , 应该如何处理 。
而编写一段基于异常的好代码更加困难 , 因为你需要检查每一行代码(别吃惊 , 每一行代码) , 并思考这段代码是否有可能抛出一个异常 , 以及如何处理它 。 (在C++中还算好 , C++异常只会在执行的某些特定阶段被抛出 , 而在C#中 , 异常可能在任意时刻被抛出)
但是 , 这也不是什么大事儿 。 就像我上面所说的 , 一件事很苦难 , 不意味着我们就不应该做这件事 。 就比如 , 驱动程序开发起来很难 , 但是人们还是继续开发它们 , 这是好事 。
【|更简洁,更优雅,但是很难看懂的代码】下面是另外一张表格:

我举一个使用了错误代码的代码片段 , 你可以试试判断它到底是好代码 , 还是坏代码 。

这段代码很显然是坏代码 。 所有函数调用的的返回值都没有检查 , 当人们急于完成一段功能时可能会写出这样的代码 , 然后在下次版本的迭代中不断优化和完善 。
而且我们很容易知道代码的哪些地方需要完善 , 很直接 。
下面是另外一个版本:

这段代码依然是错误的 , 但我们可以明显地看出来 , 代码的作者还是很想改善它 。 这就是我为什么说它是”没那么坏的代码” 。
下面我们来看看一段基于异常模型的代码:

(这是一篇关于任务栏通知图标的文章中的程序的实际代码 , 只是在原始版本的基础上做 了一点小改变)
下面是可能经过完善之后的版本:

很微妙 , 对吧?
对于错误代码模型的代码来说 , 很容易判断代码是好代码还是坏代码:好代码会做错误代码检查 , 而坏代码不会 。 诚然 , 很难判断针对错误代码的处理方式是否是合适的 , 但是至少你可以看出来代码的好坏来 。 (可能也并不是那么好 , 但是绝对不差)
而对于使用异常模型的代码来说 , 就很难看出来好坏了 。
当我编写基于异常模型的代码的时候 , 我没有机会先编写一段坏代码然后慢慢优化它 。 因为如果这样做了 , 我就无法再找出坏代码出来 , 因为在这种错误模型下 , 好代码和坏代码之间几乎没有什么变化 。