views:

86

answers:

4

I am using contracts in my Java project. (Contract = doing checks at the start and end of methods)

I am wondering if there is a nice way/pattern to write a contract for a generic method. For example:

public abstract class AbstractStringGenerator{
    /**
     * This method must return a new line as it's last char
     * @return string output
     */
     public abstract string generateLine(String input);
}

What I want is a nice way to check that the output of generateLine satisfies the contract (in this case, that last char must be a new line char).

I guess I could do this (but I wonder if there is a better way);

public abstract class AbstractStringGenerator{

     public string generateLine(String input){
         string result = generateLineHook(input);
         //do contract checking...
         //if new line char is not the last char, then throw contract exception...
         return result;
     }
    /**
     * This method must return a new line as it's last char
     * @return string output
     */
     protected abstract string generateLineHook(String input);
}

Hope this is not too vague. Any help appreciated.

+1  A: 

It's exactly that. you must create your method and use a final modifier on it so nobody can rewrite the contract. In this method you check your contract and call an internal method (your generateLineHook(String)) there is nothing more to do.

Colin Hebert
A: 

I use code contracts regularly and sometimes there are well defined and self-describing methods that it's very difficult to write a contract for.

I dont know about Java (I assume youre using iContract or something), but in C#/Code Contracts I'd do:

Contract.Ensures(result[result.Length-1] == @"\n");

or something similar....

I'm not sure what you mean by there being a better way to do this.

rmx
Thanks, but I was after the Template Class Design pattern (as answered [above](http://stackoverflow.com/questions/3510946/how-can-i-write-a-contract-for-an-abstract-method/3510997#3510997)).As an aside, I followed up on iContract (we are using an in-house implementation) and found a rather long list in wikipedia for java http://en.wikipedia.org/wiki/Design_by_contract#Languages_with_third-party_supportcheers :)
lindon fox
+3  A: 

This looks like the place to use the Template Method design pattern. With the template method pattern, the general algorithm can be implemented and finalized in the abstract class, whereas some of the specifics can be implemented in the child classes.

In order to implement the Template method:

  • You'll need to finalize the algorithm, to control the subclassing behavior. By disallowing subclasses from overriding the template method via the final keyword, one can ensure that the sufficient checks can be implemented in the template to ensure that the invariants in the algorithm are held good.
  • You'll need to allow subclasses to override the behavior that can vary. The subclass can completely override this behavior, and such methods are usually abstract in the parent class, often serving as places where subclasses can implement hooks.

The Template method can be implemented in your example as

public abstract class AbstractStringGenerator{

     // marked as final. Subclasses cannot override this behavior
     public final String generateLine(String input){
         String result = generateLineHook(input);
         //do contract checking...
         //if new line char is not the last char, then throw contract exception...
         if(!result.endsWith("\n")){
             throw new IllegalStateException("Result from hook does not contain new line");
         }
         return result;
     }
    /**
     * This method must return a new line as it's last char
     * @return string output
     */
     protected abstract string generateLineHook(String input);
}


public class ConcreteStringGenerator{

    /**
     * This method overrides the beh
     * @return string output
     */
     protected String generateLineHook(String input){
         return "blah\n";
     }
}
Vineet Reynolds
Thanks, the Template Method Design Pattern was exactly what I was looking for.
lindon fox
+1  A: 

I believe that is a nice wa to do it, just remember to add a "final" to the public method so sub-classes cannot override your checking.

simgron