1

我正在研究 Java 库的合同设计,这是我迄今为止在接口方面提出的。

用户可以调用executeContract,并且executeContract 在调用'require' 后调用invokeContract。在executeContract 之后调用ensure 以确保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;

}
4

3 回答 3

1

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

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

于 2009-03-17T16:38:50.833 回答
0

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

于 2009-03-17T16:34:37.693 回答
0

你怎么知道实现这个方法的人会遵守你的executeContract规则(即它在调用require之后调用invokeContract)?答案 - 你没有。

最好将executeContract放在一个抽象类中,这样您就可以强制执行该行为,如果您真的不希望人们改变该行为,则可以将其定为 final。

如果invokeContractrequire只需要被executeContract调用,则无需公开。

我很惊讶requireensure return Object因为它们听起来像是那种只会返回boolean的方法。事实上,除非你真的需要,否则返回Object通常是不好的。现在的方式是,实现这一点的类的消费者可以得到任何东西,并且不希望到处进行instanceof检查。

真的需要抛出ContractError吗?

希望这可以帮助。

于 2009-03-17T17:37:42.830 回答