按合同库(界面)设计思路?

时间:2009-03-17 15:26:45

标签: java design-by-contract contract

我正在考虑Java库的合同设计,这是我到目前为止在界面方面提出的。

用户可以调用executeContract,executeContract在调用'require'后调用invokeContract。 execute在executeContract之后调用,以确保invokeContract返回的内容的正确性。

此代码也可用作回调方法(匿名内部类调用)。

你有什么想法?这是设计合同吗?到目前为止,这有助于我编写可测试的Java代码。

public interface IContractHandler {

    /**
     * Execute contract will invoke the #invokeContract method.  In the execute method, 
     * check for the validity of the preconditions and the post conditions.
     * 
     * The precondition can be null.
     * 
     * @param    precondInput -  Precondition Input Data, can be null.
     * @return                   Post condition output
     */
    public Object executeContract(final Object precondInput) throws ContractError;

    /**
     * Require that the preconditions are met.
     */
    public Object require(final Object precondInput) throws ContractError;

    /**
     * Ensure that the postconditions are met.
     */
    public Object ensure(final Object precondInput) throws ContractError;

    /**
     * The precondition can be null if the contract allows for that.
     * 
     * @param    precondInput -  Precondition Input Data, can be null.
     * @return                   Post condition output
     */
    public Object invokeContract(final Object precondInput) throws ContractError;

}

3 个答案:

答案 0 :(得分:1)

如果您正在寻找通用的解决方案,我会推荐Java Modelling Language。所有前/后条件@requires/@ensures)都可以在您要检查的方法上方的注释中指定。我的理解是 JML编译器jmlc)将运行时断言插入到字节码中。

我相信 ESC / Java2 具有类似的功能,但我以前从未使用它。

答案 1 :(得分:0)

实际上,在这种情况下,您正在寻找的是一种称为Template Method的模式。接口不确定实现,这是您在executeContract()方法中尝试执行的操作。

答案 2 :(得分:0)

您如何知道实现此方法的人会遵守 executeContract 的规则(即在调用 require 后调用 invokeContract )?答案 - 你没有。

最好在抽象类中使用 executeContract ,以便您可以强制执行该行为,如果您真的不希望人们改变该行为,可能会将其作为最终行为。

如果 invokeContract require 只需要由 executeContract 调用,则无需将其公开。

我很惊讶要求确保返回对象,因为它们听起来就像返回布尔值的那种方法。事实上,除非你真的需要,否则返回 Object 通常是不好的。它现在的方式,实现这个的类的消费者可以得到任何回报,并且不希望在整个地方进行 instanceof 检查。

是否真的需要抛出 ContractError

希望这有帮助。