《程序员修炼之道》读书笔记(4):注重实效的偏执(防卫策略)

第4章:注重实效的偏执

每个人都知道只有自己是好司机,其他人都不会好好开车。
——因此,你需要在麻烦发生之前小心谨慎、预判意外之事、从不让自己陷入无法解救自己的境地。

而一个“注重实效的”程序员会更进一步——他们连自己也不信任。因为他们知道没人能编写完美的代码,自己也不例外。

因此,需要对错误进行防卫性编码。
本章的内容即是各种防卫策略:

21《按合约设计》

合约既规定你的权利与责任,也规定对方的权利与责任。此外,还有关于一方未遵守的后果的约定。

我们也可以采用同样的理念来帮助软件模块进行交互。

DBC(Design By Contracts),通过合约进行设计
Meyer这样描述:

  • 前条件。为了调用例程,必须为真的条件。
  • 后条件。例程保证会做的事,例程完成时世界的状态。
  • 类不变项:类确保从调用者的视角来看,该条件总是为真。

“继承”和“多态”是面向对象的基石,也是DBC闪耀的领域。
比如 Liskov替换原则
子类必须能通过基类的接口使用,而使用者无需知道其区别

实现DBC:

  • 断言
  • 语言支持
  • 就算没有机制,也可以添加注释

可以使用DBC来早崩溃。在问题现场找到和诊断问题更容易。

不变项的其他用法?

  • 循环不变项?
  • 语义不变项?

动态合约与代理?

22《死程序不说谎》(提早崩溃)

如果有错误,那么提早崩溃

要崩溃,不要破坏。

虽然,有时简单地退出运行中的程序并不合适。
但是,要尽快终止它,死程序带来的危害通常小于有疾患的程序。

23《断言式编程》

无论何时你发现自己在思考“但那当然不可能发生”时——增加代码检查它,最容易的是使用断言。

注意:

  • 断言不应该有副作用
  • 断言可能会被关闭,所以不要把必须执行的代码放进去。
  • 不要用断言去替代真正的错误处理,因为断言检查的是决不应该发生的事

尽量保持断言开着:

  • BUG有可能没有找干净
  • 有一些突发情况(耗尽内存,塞满硬盘等)

24《何时使用异常》

检查每一个错误可能会导致代码很丑陋。
如果你用的语言支持异常,则可以用更简洁的方式表示。

什么是异常情况?
——问问你自己:“如果我移走所有的异常处理器,这些代码是否仍旧能运行?”
如果答案是“否”,那么异常也许就被用在了非异常的情形中。

25《怎样配平资源》(资源分配善始善终)

分配资源的例程也应该释放它。

对于一次不止需要一个资源的例程,两个建议:

  • 以与资源分配的次序相反的次序解除资源的分配。
  • 在代码不同地方分配同一组资源时,总以相同的次序分配它们。这降低死锁发生的可能性。

资源的配平可以与构造函数与析构函数结合。

配平与异常:
当异常时,需要释放资源,但是有可能违反DRY原则。
处理方法有多种,根据语言有所不同。

动态的数据结构往往有无法配平资源的情况。
比如有层级结构。三个主要选择:

  1. 顶层结构还负责释放它包含的子结构。这些结构随即递归地删除包含的数据等等
  2. 只解除顶层结构。它指向地(没在别处引用的)任何结构都会被丢弃。
  3. 如果顶层结构包含子结构,就拒绝解除自身的分配。

你可能需要个检查资源配平的工具

猜你喜欢

转载自blog.csdn.net/u013412391/article/details/115128143