2009-03-17 7 views
1

Ich freue mich über ein Vertragsdesign für eine Java-Bibliothek, was ich in Bezug auf die Schnittstelle bisher gemacht habe.Design by Contract-Bibliothek (Schnittstelle) Gedanken?

Der Benutzer könnte executeContract aufrufen und executeContract ruft invokeContract nach dem Aufruf von 'require' auf. ensure wird nach executeContract aufgerufen, um die Korrektheit dessen zu gewährleisten, was von invokeContract zurückgegeben wird.

Dieser Code funktioniert auch als Callback-Methode (anonymer innerer Klassenaufruf).

Was sind Ihre Gedanken? Ist dieses Design vertraglich ?, das hilft mir bisher testbaren Java-Code zu schreiben.

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; 

} 

Antwort

1

Wenn Sie nach einer generischen Lösung suchen, empfehle ich die Java Modelling Language. Alle Vor-/Nachbedingungen (@requires/@ensures) können in den Anmerkungen über der Methode angegeben werden, die Sie überprüfen möchten. Es ist mein Verständnis, dass der JML-Compiler (jmlc) Laufzeit Assertions in den Bytecode einfügt.

Ich glaube ESC/Java2 hat eine ähnliche Art von Funktionalität, aber ich habe es noch nie zuvor verwendet.

0

Eigentlich, was Sie suchen in dieser Situation ist ein ein Muster mit einer Template Method genannt. Schnittstellen bestimmen nicht die Implementierung, was Sie in Ihrer Methode executeContract() versuchen.

0

Wie wissen Sie, die Menschen zur Durchführung dieses Verfahrens werden Ihre Regeln für executeContract gehorchen (das heißt, dass es invokeContract ruft nach dem Aufruf von erfordern)? Antwort - Sie nicht.

Besser zu haben executeContract in einer abstrakten Klasse, so dass Sie dieses Verhalten erzwingen können, vielleicht machen es endgültig, wenn Sie wirklich nicht wollen, dass Menschen dieses Verhalten ändern.

Wenn invokeContract und erfordern nur durch executeContract, dann genannt werden müssen, gibt es keine Notwendigkeit, sie zu veröffentlichen.

Ich bin überrascht, dass erfordern und gewährleisten Rückkehr Objekt da sie wie die Art von Methoden klingen, die ein boolean nur zurückkehren würden. In der Tat ist die Rückkehr Objekt etwas, das im Allgemeinen nicht gut ist, es sei denn, Sie müssen wirklich. So wie es jetzt ist, könnte der Verbraucher einer Klasse, die dies implementiert, alles zurückbekommen und es nicht tun wollen instanceof prüft überall.

Muss wirklich alles geworfen werden ContractError?

Hoffe, das hilft.