我正在考虑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;
}
答案 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 ?
希望这有帮助。