按合同库(界面)设计的想法?

发布于 2024-07-14 18:31:37 字数 1360 浏览 6 评论 0原文

我正在研究一个 Java 库的契约设计,这是我迄今为止在界面方面提出的想法。

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

}

I am looking at design by contract for a Java library, this what I came up with so far in terms of the interface.

The user could call executeContract and executeContract invokes invokeContract after calling 'require'. ensure is called after executeContract to ensure the correctness of what is returned by invokeContract.

This code also works as a callback method (anonymous inner class call).

What are your thoughts? Is this design by contract?, so far this helps me write testable Java code.

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;

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

阳光的暖冬 2024-07-21 18:31:38

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

最好在抽象类中包含 executeContract ,以便您可以强制执行该行为,如果您确实不希望人们改变该行为,则可以将其定为最终的。

如果invokeContractrequire只需要被executeContract调用,那么就不需要将它们公开。

我很惊讶 requireensure 返回 Object,因为它们听起来像是只返回 boolean 的方法>。 事实上,除非确实需要,否则返回Object通常不好。 现在的情况是,实现此功能的类的使用者可以获取任何内容,并且不想到处进行 instanceof 检查。

一切真的都需要抛出ContractError吗?

希望这可以帮助。

How do you know people implementing this method will obey your rules for executeContract (i.e. that it calls invokeContract after calling require)? Answer - You don't.

Better to have executeContract in an abstract class so that you can enforce that behaviour, maybe making it final if you really don't want people altering that behaviour.

If invokeContract and require only need to be called by executeContract, then there is no need to make them public.

I am surprised that require and ensure return Object as they sound like the sort of methods that would just return a boolean. In fact, returning Object is something that is generally not good unless you really need to. The way it is now, the consumer of a class implementing this could get anything back and doesn't want to be doing instanceof checks all over the place.

Does everything really need to throw ContractError?

Hope this helps.

别闹i 2024-07-21 18:31:37

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

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

If you are looking for a generic solution to this I would recommend the Java Modelling Language. All of the pre/post-conditions (@requires/@ensures) can be specified in the annotations above the method you wish to check. It's my understanding that the JML compiler (jmlc) inserts runtime assertions into the bytecode.

I believe ESC/Java2 has a similar type of functionallity but I've never used it before.

作死小能手 2024-07-21 18:31:37

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

Actually, what you are looking for in this situation is a a pattern called a Template Method. Interfaces don't determine the implementation, which is what you are trying to do in your executeContract() method.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文