2009-07-02 10 views
45

Alcuni anni fa, ho eseguito un'indagine sui pacchetti DbC per Java e non ero completamente soddisfatto di nessuno di essi. Purtroppo non ho tenuto buoni appunti sulle mie scoperte e presumo che le cose siano cambiate. Qualcuno dovrebbe preoccuparsi di confrontare e contrastare diversi pacchetti DbC per Java?Una buona libreria Design-by-Contract per Java?

risposta

22

C'è una bella panoramica su WikiPedia about Design by Contract, alla fine c'è una sezione riguardante languages with third party support libraries, che include una bella serie di librerie Java. Molte di queste librerie Java sono basate su Java Assertions.

Nel caso in cui sia necessario solo Precondition Checking, è disponibile anche una soluzione leggera Validate Method Arguments presso SourceForge con Java Argument Validation (implementazione Plain Java).

A seconda del problema, forse il framework OVal, per la validazione dei vincoli di campo/proprietà è una buona scelta. Questo framework consente di posizionare i vincoli in tutti i tipi di forme diverse (annotazioni, POJO, XML). Creare vincoli ai clienti tramite POJO o linguaggi di scripting (JavaScript, Groovy, BeanShell, OGNL, MVEL). E fa festa anche implementa Programming by Contract.

+0

OVal sembra impressionante. Mi azzarderei a dire che è buono come DbC in Java. –

+8

Non sono sicuro che un commento qui sia il miglior posto/strada, ma solo per i prossimi a leggere: [Contracts for Java - cofoja] (http://code.google.com/p/cofoja/) è un recente Inoltre direttamente dalla ricerca del tempo del 20% di Google. – superjos

0

penso che molte biblioteche DBC sono stati surclassed dal incorporato assert parola chiave, introdotto dal Java 1.4:

  • è un builtin, non è necessaria alcuna altra libreria
  • funziona con l'ereditarietà
  • è possibile attivare/disattivare su base pacchetto
  • facile refactoring (ad esempio non affermazioni nei commenti)
+4

ma Sun scrive: "Non utilizzare le asserzioni di controllare i parametri di un metodo pubblico" in http : //java.sun.com/javase/6/docs/technotes/guides/language/assert.html –

+4

Più precisamente, DbC dovrebbe facilitare l'aggiunta di contratti al codice. Se non è facile, la maggior parte degli sviluppatori non lo farà. È possibile implementare invarianti di classi usando asserzioni e chiamate a un metodo invariante di classe, ma è maldestro. –

2

Ho testato contratto4J una volta e l'ho trovato utilizzabile ma non perfetto. Si stanno creando contratti per e dopo chiamate di metodi e invar sull'intera classe.

Il contratto viene creato come un'asserzione per il metodo. Il problema è che il contratto stesso è scritto in una stringa in modo da non avere il supporto IDE per i contratti o compilare il cheching del tempo se il contratto funziona ancora.

Un link alla library

2

E 'passato molto tempo da quando ho visto anche questi, ma ha trovato alcuni vecchi legami. Uno era per JASS.

L'altro che avevo usato (e piaciuto) era iContract di Reliable Systems. Aveva un compito ant che avresti eseguito come preprocessore. Tuttavia, non riesco a trovarlo con alcune ricerche su google, sembra che sia svanito. Il sito originale ora è un link farm. Controlla this link per alcuni possibili modi per raggiungerlo.

+0

La versione più recente di JASS è del luglio 2005. Non ho intenzione di speculare su quali versioni del JDK supporta. JASS ha un collegamento a JML, che sembra essere in fase di sviluppo attivo. –

1

Consiglio vivamente di prendere in considerazione il linguaggio di modellazione Java (JML).

2

Esiste un'estensione Groovy che consente la progettazione per contratto (tm) nel codice Groovy/Java - GContracts. Utilizza le cosiddette annotazioni di chiusura per specificare gli invarianti di classe, pre- e post-condizioni. Gli esempi possono essere trovati sul wiki github del progetto.

Vantaggio principale: è un solo barattolo senza dipendenze esterne e può essere risolto tramite repository compatibili Maven poiché è stato inserito in the central Maven repo.

+0

Non penso che possiamo usare GContracts in un progetto Java, poiché GContracts fa un uso massiccio di Groovy Closures – Sudarshan

+0

Esatto, è una libreria solo Groovy. –

6

Google ha una libreria open source denominata contracts for java.

Contratti per Java è il nostro nuovo strumento open source. Le precondizioni, le postcondizioni e le invarianti vengono aggiunte come espressioni booleane Java all'interno delle annotazioni. Di default questi non fanno nulla, ma abilitati tramite un argomento JVM , vengono controllati in fase di runtime.

• @Requires, @Ensures, @ThrowEnsures and @Invariant specify contracts as Java boolean expressions 
• Contracts are inherited from both interfaces and classes and can be selectively enabled at runtime 

contracts for java.

0

Personalmente ritengo che le librerie DbC attualmente disponibili abbiano lasciato molto a desiderare, nessuna delle librerie che ho visto ha funzionato bene con l'API di convalida del bean.

Le librerie che ho guardato sono stati documentati here

The Bean Validation API ha un sacco di oltre giro con i concetti da DBC. In alcuni casi l'API di convalida del bean non può essere utilizzata come il semplice POJO (codice gestito non CDI). IMO dovrebbe essere sufficiente per un think wrapper attorno all'API di convalida dei bean.

Ho scoperto che le librerie esistenti sono un po 'complicate da aggiungere ai progetti Web esistenti, dato che sono implementate tramite la strumentazione AOP o Byte. Probabilmente con l'avvento dell'API Bean Validation questo tipo di complessità per implementare DbC è ingiustificato.

ho anche documentato il mio sproloquio in questo post e la speranza di costruire una piccola biblioteca che fa leva sulle API Bean Validation

0

Se si desidera un supporto di base chiaro e semplice per esprimere i vostri contratti, avere uno sguardo su valid4j (trovato su Maven Central come org.valid4j: valid4j). Ti consente di esprimere i tuoi contratti utilizzando normali hamcrest-matcher in codice semplice (senza annotazioni o commenti).

Per precondizioni e postcondizioni (fondamentalmente asserzioni -> gettando AssertionError):

import static org.valid4j.Assertive.*; 

require(inputList, hasSize(greaterThan(0))); 
... 
ensure(result, lessThan(4.0)); 

Se non siete soddisfatti con la politica globale di default (gettando AssertionError), valid4j fornisce un meccanismo di personalizzazione che ti permette di fornire il proprio implementazione di org.valid4j.AssertiveProvider.

vicini:

+0

Qualcuno ha un foglio di calcolo dei confronti per questo? Una matrice di caratteristiche sarebbe grande. –

+0

valid4j assomiglia di più ad una libreria di asserzioni (proprio come il popolare AssertJ di Java o l'assert avanzato di Groovy), non come un completo strumento DBC (come OVal o Cofoja) – iirekm

1

vorrei suggerire una combinazione di alcuni strumenti:

  • di Java assert condition... o è il cugino Groovy più avanzato, Guava di Preconditions.checkXXXX(condition...) e Verify.verify(condition...), o di una libreria come AssertJ, se tutto ciò che serve è solo per fare semplici controlli nel codice 'principale' o 'test'

  • si otterrà più funzionalità con uno strumento come OVal; può controllare sia gli oggetti che gli argomenti e i risultati del metodo, è anche possibile attivare i controlli manualmente (ad es. per mostrare errori di validazione sull'interfaccia utente prima che venga chiamato un metodo). Può comprendere annotazioni esistenti, ad esempio da JPA o javax.validation (come @NotNull, @Pattern, @Column), oppure è possibile scrivere vincoli interni come @Pre(expr="x >= 0 && x <= y"). Se l'annotazione è @Documented, i controlli saranno visibili anche in Javadoc (non è necessario descriverli anche lì).

  • OVal utilizza la riflessione, che può causare problemi di prestazioni e altri problemi in alcuni ambienti come Android; allora si dovrebbe considerare strumento come Google's Cofoja, che ha meno funzionalità, ma dipende dal tempo di compilazione Annotazione di elaborazione dello strumento invece di riflessione

Problemi correlati