Comment puis-je place la validation des contraintes sur ma méthode de paramètres d'entrée?
Ici est typique de la façon d'atteindre cet objectif:
public void myContractualMethod(final String x, final Set<String> y) {
if ((x == null) || (x.isEmpty())) {
throw new IllegalArgumentException("x cannot be null or empty");
}
if (y == null) {
throw new IllegalArgumentException("y cannot be null");
}
//Now I can actually start writing purposeful
// code to accomplish the goal of this method
Je pense que cette solution est laid. Vos méthodes de remplir rapidement avec passe-partout de code de vérification de la validité des paramètres d'entrée du contrat, obscurcissant le cœur de la méthode.
Voici ce que je voudrais avoir:
public void myContractualMethod(@NotNull @NotEmpty final String x, @NotNull final Set<String> y) {
//Now I have a clean method body that isn't obscured by
// contract checking
Si ces annotations ressembler à de la JSR 303/Bean Validation Spec, c'est parce que j'ai emprunté. Unfortunitely ils ne semblent pas fonctionner de cette façon; ils sont prévus pour l'annotation des variables d'instance, puis l'exécution de l'objet par le biais d'un programme de validation.
Qui de la de nombreux Java conception par contrat de cadres fournissent le plus proche de la fonctionnalité mon "aiment avoir" exemple? Les exceptions qui obtiennent lancés doivent être des exceptions d'exécution (comme IllegalArgumentExceptions) afin d'encapsulation n'est pas rompu.
OriginalL'auteur Robert Campbell | 2009-11-27
Vous devez vous connecter pour publier un commentaire.
Si vous êtes à la recherche pour l'une à part entière de la conception par contrat mécanisme je voudrais prendre un coup d'oeil à certains des projets énumérés sur la Page Wikipedia pour DBC.
Si vous cherchez quelque chose de plus simple cependant, vous pouvez consulter la Conditions préalables classe de google collections, qui fournit un checkNotNull() la méthode. De sorte que vous pouvez réécrire le code que vous avez posté:
Aha, toujours utile d'avoir de la bibliothèque de créateur à portée de main 🙂
OriginalL'auteur Jared Russell
J'ai vu une technique par Eric Burke c'est à peu près comme suit. C'est une façon élégante de l'utilisation de la statique des importations. Le code se lit très bien.
Pour se faire une idée, voici la
Contract
classe. C'est minime, mais peut facilement être complété en tant que de besoin.Et voici un exemple d'utilisation. Le
foo()
méthode illustre la statique des importations:Remarque: lors de l'expérimentation, notez que il y a peut être un bug autour de le faire dans le package par défaut. J'ai certainement perdu les cellules du cerveau de l'essayer.
OriginalL'auteur Michael Easter
Il y a un petit Java Argument De Validation paquet, mis en œuvre dans la Plaine de Java. Il est livré avec plusieurs vérifications et les validations. Et pour le cas où quelqu'un a besoin de sa propre plus validations spécifiques, il est livré avec des méthodes d'assistance. Pour les validations qui se produisent plusieurs fois, il suffit de prolonger l'interface ArgumentValidation, avec votre propre Et de créer la mise en œuvre de la classe qui s'étend à partir de la classe ArgumentValidationImpl.
OriginalL'auteur Verhagen
Cela ne veut pas répondre directement à votre question, mais je pense qu'une partie de votre problème est que vous êtes trop la validation. Par exemple, vous pouvez remplacer le premier test avec:
et de s'appuyer sur l'île de Java pour lancer une
NullPointerException
six
estnull
. Vous avez juste besoin de modifier votre "contrat" pour dire que les NPE est levée pour certains types de "vous m'avez appelé illégal" paramètres de situations.OriginalL'auteur Stephen C
Jared pointu vous à divers cadres d'ajouter le support pour les DBC à Java.
Ce que j'ai trouvé la meilleure solution: il suffit d'un document de votre contrat dans la JavaDoc (ou quel que soit Documentationframework que vous utilisez; Doxygen en charge de la DBC des balises.)
Avoir votre code obscurci par un grand nombre de lancers et les contrôles de vos arguments n'est pas vraiment utile de votre lecteur. La Documentation est.
Je suis d'accord. Mais, habituellement, il n'y a pas de meilleure façon. Soit vous apportez dans une structure lourde et prendre tout l'apprentissage et de l'obscurcissement de frais généraux ou de vous y tenir. Si vous voulez vraiment utiliser DBC vous sont les meilleurs avec un langage supportant nativement.
Encore pire que d'arriver à une exception aléatoire, le programme peut ne pas lever une exception à tous, de sorte que vous n'avez même pas averti que quelque chose est mauvais jusqu'à ce qu'un utilisateur trouve comportement involontaire.
OriginalL'auteur pmr
Je voudrais utiliser le Paramètre d'Annotations, de Réflexion et d'un générique classe de validation pour créer une application à l'échelle de l'établissement. par exemple, vous pouvez code d'une méthode de classe comme:
.. myMethod( @notNull Chaîne x, @notNullorZero Chaîne y){
}
Les méthodes de la classe sont "marqués" pour annoter leurs conditions de contrat. Utiliser la réflexion pour détecter automatiquement les paramètres, leurs valeurs et leurs annotations. Envoyer le tout à une classe statique pour valider et vous permettent de connaître le résultat.
OriginalL'auteur srini.venigalla
Pas entièrement une solution de travail, mais de la JSR-303 a une proposition pour un méthode de validation au niveau de l'extension. Parce que c'est juste une proposition d'extension tout à l'heure, les implémentations de la JSR-303 êtes libre de l'ignorer. Trouver une mise en œuvre est un peu plus délicat. Je ne pense pas que Hibernate Validator soutient-il encore, mais je crois agimatec-validation a un support expérimental. Je ne l'ai pas utilisé pour ce but, donc je ne sais pas comment ils fonctionnent bien. Je serais intéressé d'en savoir bien que, si quelqu'un vous donne un rendez-vous.
OriginalL'auteur GaryF
Si vous êtes à l'aide de Java 8, lambdas peuvent être utilisés pour créer un très élégant et lisible de la solution pour la validation:
Vous l'utilisez comme:
L'exception ressemblera:
La première est sympa, c'est que la classe Assert est tout ce qu'il faut vraiment:
Bien sûr
that()
peut être mis en œuvre dans un certain nombre de façons: avec une chaîne de format et d'arguments, de lancer d'autres types d'exceptions, etc.Il n'est pas, cependant, doivent être mises en œuvre afin d'effectuer différents tests.
Pas que vous ne pouvez pas pré paquet de tests si vous aimez:
Je n'ai aucune idée si c'est mauvais pour la performance ou non une bonne idée pour une autre raison. (Juste commencé à regarder les lambdas moi-même, mais le code semble fonctionner comme il se doit...) Mais j'aime que
Assert
peut être court (pas besoin de dépendances qui peuvent ne pas être cruciale pour le projet) et que les tests sont très visibles.Voici une méthode pour une meilleure message d'erreur:
Vous l'appeler comme:
Et il en sort:
Mise à jour: Si vous souhaitez utiliser le
x = Assert...
de construction avec un produit de test, le résultat sera jeté du type utilisé dans la préemballés test. Il doit donc être rejetés sur le type de la variable...SomeClass x = (SomeClass) Assert.that(x, isNotNull)
Merci... mais, j'ai eu le temps d'examiner tous les côtés et si vous n'avez pas besoin d'obtenir la valeur de retour, je vous conseille d'aller juste avec un "isTrue" ou "isFalse" la méthode. Il s'avère que si plus d'une valeur, la levée d'une exception à mi-chemin à travers n'est vraiment souhaitable, dans un constructeur.
OriginalL'auteur Erk