views:

191

answers:

3

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;

}
A: 

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.

Robin
+1  A: 

If you are looking for a generic solution to this I would recommend the Java Modelling Language (link text). 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.

Dr.Pil
A: 

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.