Il y a quelques années, j'ai mené une enquête sur les packages DbC pour Java et je n'étais totalement satisfait d'aucun d'entre eux. Malheureusement, je n'ai pas gardé de bonnes notes sur mes découvertes et je suppose que les choses ont changé. Quelqu'un voudrait-il comparer et contraster différents packages DbC pour Java?
Il existe un aperçu de Nice sur WikiPedia à propos de Design by Contract , à la fin se trouve une section concernant langues avec des bibliothèques de support tierces , qui inclut une série de bibliothèques Java de Nice. La plupart de ces bibliothèques Java sont basées sur des assertions Java.
Dans le cas où vous avez seulement besoin de vérification préalable il existe également une solution légère validation des arguments de méthode -, sous SourceForge validation d'argument Java (implémentation Java simple).
Selon votre problème, peut-être que le cadre OVal , pour la validation de contraintes de champ/propriété est un bon choix. Ce cadre vous permet de placer les contraintes sous toutes sortes de formes différentes (annotations, POJO, XML). Créez des contraintes client par le biais de POJO ou de langages de script (JavaScript, Groovy, BeanShell, OGNL, MVEL). Et il met également en œuvre partie Programmation par contrat .
Google dispose d'une bibliothèque open source appelée contracts for Java .
Contracts for Java est notre nouvel outil open source. Les préconditions, les post-conditions Et les invariants sont ajoutés sous forme d'expressions booléennes Java Dans les annotations. Par défaut, ils ne font rien, mais activés via un argument JVM , Ils sont vérifiés à l'exécution.
• @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
Il existe des extensions Groovy qui permettent la conception par contrat dans Groovy/code Java - GContracts . Il utilise ce que l’on appelle des annotations de fermeture pour spécifier les invariants de classe, les pré et post-conditions. Des exemples sont disponibles sur le wiki github du projet.
Avantage majeur: il ne s'agit que d'un seul fichier jar sans dépendances externes et il peut être résolu via des référentiels compatibles Maven puisqu'il a été placé dans le référentiel Maven central .
J'ai testé contract4J une fois et je l'ai trouvé utilisable, mais pas parfait. Vous créez des contrats pour et après des appels de méthodes et des invars sur l'ensemble de la classe.
Le contrat est créé en tant qu'assertion pour la méthode. Le problème est que le contrat lui-même est écrit dans une chaîne, de sorte que vous n'avez ni IDE support pour les contrats ni le temps de compilation cheching si le contrat fonctionne toujours.
Un lien vers la bibliothèque
Cela fait longtemps que je n’ai pas regardé cela, mais que j’ai trouvé de vieux liens. On était pour JASS .
L'autre que j'avais utilisé (et aimé) était iContract de Reliable Systems. Il y avait une tâche de fourmi que vous exécuteriez en tant que préprocesseur. Cependant, je ne peux pas sembler le trouver avec quelques recherches de Google, il semble qu'il ait disparu. Le site d'origine est maintenant une ferme de liens. Consultez ce lien pour quelques façons possibles d’y accéder.
Je suggérerais une combinaison de quelques outils:
Le code assert condition...
de Java ou son cousin plus avancé, celui de Preconditions.checkXXXX(condition...)
et Verify.verify(condition...)
de Guava, ou une bibliothèque telle que AssertJ , si vous avez simplement besoin de vérifier votre code "principal" ou "de test"
vous aurez plus de fonctionnalités avec un outil comme OVal ; il peut vérifier les deux objets ainsi que les arguments et les résultats de la méthode. Vous pouvez également activer les contrôles manuellement (par exemple, pour afficher les erreurs de validation sur l'interface utilisateur avant l'appel d'une méthode). Il peut comprendre les annotations existantes, par exemple celles provenant de JPA ou de javax.validation
(comme @NotNull
, @Pattern
, @Column
), ou vous pouvez écrire des contraintes en ligne telles que @Pre(expr="x >= 0 && x <= y")
. Si l'annotation est @Documented
, les vérifications seront également visibles dans Javadocs (vous n'êtes pas obligé de les décrire également).
OVal utilise la réflexion, ce qui peut entraîner des problèmes de performances et d’autres problèmes dans certains environnements comme Android; alors vous devriez considérer un outil comme Cofoja de Google , qui a moins de fonctionnalités, mais dépend de l'outil de traitement des annotations au moment de la compilation au lieu de la réflexion
Je vous recommande fortement de prendre en compte le langage de modélisation Java ( JML ).
Je pense que beaucoup de bibliothèques DbC ont été surclassées par le mot-clé builtin assert , introduit depuis Java 1.4:
Personnellement, je pense que les bibliothèques DbC disponibles actuellement laissent beaucoup à désirer, aucune des bibliothèques que j’ai examinées n’a bien fonctionné avec l’API de validation de bean.
Les bibliothèques que j'ai consultées ont été documentées ici
L'API de validation de bean a beaucoup de temps avec les concepts de DbC. Dans certains cas, l'API de validation de bean ne peut pas être utilisée comme un simple POJO (code géré non CDI). IMO, un wrapper de réflexion autour de l'API de validation de bean devrait suffire.
J'ai trouvé que les bibliothèques existantes sont un peu difficiles à ajouter à des projets Web existants, étant donné qu'elles sont implémentées via une instrumentation AOP ou Byte. Probablement avec l'avènement de l'API de validation de bean, ce genre de complexité pour implémenter DbC n'est pas justifié.
J'ai également documenté mon discours dans ce post et espère construire une petite bibliothèque qui exploite l'API de validation de bean
Si vous souhaitez une assistance de base simple et claire pour l’expression de vos contrats, consultez valid4j (disponible sur Maven Central sous la forme org.valid4j: valid4j). Il vous permet d’exprimer vos contrats à l’aide d’appariements classiques en code clair (sans annotations ni commentaires).
Pour les conditions préalables et postconditions (essentiellement des assertions -> jeter AssertionError):
import static org.valid4j.Assertive.*;
require(inputList, hasSize(greaterThan(0)));
...
ensure(result, lessThan(4.0));
Si vous n'êtes pas satisfait de la stratégie globale par défaut (en générant AssertionError), valid4j fournit un mécanisme de personnalisation vous permettant de fournir votre propre implémentation de org.valid4j.AssertiveProvider.
Liens: