异常是一个有效的后置条件吗?

时间:2016-05-19 18:42:10

标签: design-by-contract contract preconditions post-conditions

考虑以下界面:

public interface AISPI
{
    public Path getPath(Entity entity, Entity target, World world) throws NoPathException;
}

授予实体目标 world 都是有效输入。但是用于查找路径的算法(在这种情况下是Astar)由于例如而无法找到路径。 目标的位置被混凝土墙包围。

说明后置条件是路径实体目标(开始到目标)还是NoPathException(给定)是否有效没找到路径)?
- 前提条件是否必须有从开始到目标的有效路径?

这不是家庭作业,而是改善我们学期项目报告的问题。我不打算了解任何框架,这纯粹是关于合同设计的标准和手续问题。感谢您对此事的任何澄清。

1 个答案:

答案 0 :(得分:0)

这取决于术语后置条件的定义。通常,前提条件是输入状态和例程条目输入值的关系,后置条件是输入状态,输入值和输出状态以及例程退出时的输出值的关系。

因为例程可以正常退出或异常退出,所以可以为正常终止定义后置条件,为异常终止定义后置条件。显然,两者都涉及输入值,输入状态和输出状态。关键的区别在于输出值。在第一种情况下,这是在例程签名中指定的值,在第二种情况下 - 它取决于语言。在您的示例中,它可能是NoPathException,但如果存在内存分配错误,堆栈溢出或签名中未指定的其他异常或信号,该怎么办?事实上似乎可能有一个前提条件,即保证始终存在不涉及异常的有效结果。但事实并非如此,例如当与外部世界,并发等进行通信时,如果前提条件计算成本太高,那么做同样的工作两次并不好看 - 在客户端确保呼叫适用且供应商&# 39; s方面基本上进行相同的计算以获得结果。

根据按合同设计理念,后置条件是客户在调用例程后可以安全依赖的内容。回到特殊情况,从实际的角度来看,使异常后置条件足够强,以便程序可以继续执行,但足够弱以使签名中没有或不能指定的情况,在实践中是可能的,是允许的。

因此,除非语言真正保证所有可能的例外情况而不是其他内容,否则最重要的部分是输出状态,不应使关联对象不可用。这可以用显式或隐式后置条件表示,也可以用类不变量表示。

对于具有getPath的具体示例,预期路径不存在的情况是正常的,即可能发生的情况。一些指南建议使用正常值来指示正常终止案例。这里的值为null。使用null可能会导致调用者方面的其他问题,例如NullPointerException如果未检查结果是否为空,但是在某些语言中可以保证不存在此类异常(例如, Eiffel 中的void-safety)这将是指示缺少路径的首选方式(在这种情况下返回类型为detachable PATH)。