这取决于术语postcondition的定义。一般来说,前置条件是程序进入时输入状态和输入值的关系,后置条件是程序退出时输入状态、输入值和输出状态以及输出值的关系。
因为例程可以正常退出或异常退出,所以可以定义正常终止的后置条件和异常终止的后置条件。显然两者都涉及输入值、输入状态和输出状态。主要区别在于输出值。在第一种情况下,这是例程签名中指定的值,在第二种情况下 - 它取决于语言。在您的示例中,它可能是NoPathException
,但如果出现内存分配错误、堆栈溢出或其他未在签名中指定的异常或信号怎么办?似乎确实可以有一个前提条件来保证始终存在不涉及异常的有效结果。但情况并非如此,例如,当与外部世界进行通信、并发等时。此外,如果先决条件的计算成本太高,那么两次执行相同的工作看起来并不好——在客户端以确保call 是适用的,并且在供应商方面进行基本相同的计算以获得结果。
根据契约式设计理念,后置条件是客户在调用例程后可以安全依赖的条件。回到例外情况,从实际的角度来看,使异常后置条件足够强以使程序可以继续执行是有意义的,但又足够弱以使签名中没有或不能指定的情况,但是在实践中是可能的,是允许的。
因此,除非该语言确实保证所有可能的例外情况,否则最重要的部分是输出状态,它不应使相关对象不可用。这可以用显式或隐式后置条件表示,也可以表示为类不变量。
对于带有 的具体示例getPath
,路径不存在的情况是正常的,即可能发生的情况,是可以预料的。一些指南建议使用正常值来表示正常终止情况。这将是 value null
。使用null
可能会导致调用方出现其他问题,例如,NullPointerException
如果未检查结果是否为空,但在某些保证不存在此类异常的语言中(例如,Eiffel中的 void-safety ),这将是指示的首选方式没有路径(detachable PATH
在这种情况下返回类型)。