Je ne sais pas d'où vient l'affirmation selon laquelle "il ne fait pas et ne peut souvent pas effectuer une analyse statique". La première partie de l'affirmation est manifestement erronée. Le second dépend de ce que vous entendez par «souvent». Je dirais plutôt que souvent , il effectue une analyse statique et rarement, il échoue. Dans une application commerciale ordinaire, devient rarement beaucoup plus proche que jamais .
Le voici donc, le premier avantage:
Avantage 1: analyse statique
Les assertions ordinaires et la vérification des arguments ont un inconvénient: elles sont reportées jusqu'à l'exécution du code. En revanche, les contrats de code se manifestent à un niveau beaucoup plus précoce, soit à l'étape de codage, soit lors de la compilation de l'application. Plus vous détectez une erreur tôt, moins il est coûteux de la corriger.
Avantage 2: sorte de documentation toujours à jour
Les contrats de code fournissent également une sorte de documentation toujours à jour. Si le commentaire XML de la méthode SetProductPrice(int newPrice)
indique que celle-ci newPrice
doit être supérieure ou égale à zéro, vous pouvez espérer que la documentation est à jour, mais vous pouvez également découvrir que quelqu'un a changé la méthode de sorte que newPrice = 0
jette un ArgumentOutOfRangeException
, mais n'a jamais changé la documentation correspondante. Étant donné la corrélation entre les contrats de code et le code lui-même, vous n'avez pas le problème de documentation désynchronisée.
Le type de documentation fourni par les contrats de code est également précieux d'une manière qui, souvent, les commentaires XML n'expliquent pas bien les valeurs acceptables. Combien de fois je me demandais si null
ou string.Empty
ou \r\n
était une valeur autorisée pour une méthode, et les commentaires XML étaient silencieux à ce sujet!
En conclusion, sans contrats de code, beaucoup de morceaux de code sont comme ça:
J'accepterai certaines valeurs mais pas d'autres, mais vous devrez deviner ou lire la documentation, le cas échéant. En fait, ne lisez pas la documentation: elle est dépassée. Parcourez simplement toutes les valeurs et vous verrez celles qui me font lever des exceptions. Vous devez également deviner la plage de valeurs qui peut être renvoyée, car même si je vous en disais un peu plus, ce n'est peut-être pas vrai, compte tenu des centaines de modifications qui m'ont été apportées ces dernières années.
Avec les contrats de code, cela devient:
L'argument title peut être une chaîne non nulle d'une longueur de 0 à 500. L'entier qui suit est une valeur positive, qui ne peut être nulle que lorsque la chaîne est vide. Enfin, je vais retourner un IDefinition
objet, jamais nul.
Avantage 3: contrats d'interfaces
Un troisième avantage est que les contrats de code renforcent les interfaces. Disons que vous avez quelque chose comme:
public interface ICommittable
{
public ICollection<AtomicChange> PendingChanges { get; }
public void CommitChanges();
...
}
Comment garantissez-vous, en utilisant uniquement des assertions et des exceptions, que vous CommitChanges
ne pouvez être appelé que lorsqu'il PendingChanges
n'est pas vide? Comment garantiriez-vous que ce PendingChanges
n'est jamais null
?
Avantage 4: appliquer les résultats d'une méthode
Enfin, le quatrième avantage est de pouvoir bénéficier Contract.Ensure
des résultats. Et si, lors de l'écriture d'une méthode qui renvoie un entier, je veux être sûr que la valeur n'est jamais inférieure ou égale à zéro? Y compris cinq ans plus tard, après avoir subi de nombreux changements de la part de nombreux développeurs? Dès qu'une méthode a plusieurs points de retour, cela Assert
devient un cauchemar de maintenance pour cela.
Considérez les contrats de code non seulement comme un moyen d'exactitude de votre code, mais comme un moyen plus strict d'écrire du code. De la même manière, une personne qui utilise exclusivement des langages dynamiques peut se demander pourquoi appliquer des types au niveau du langage, alors que vous pouvez faire la même chose dans les assertions si nécessaire. Vous pouvez, mais la saisie statique est plus facile à utiliser, moins sujette aux erreurs par rapport à un tas d'assertions et à l'auto-documentation.
La différence entre le typage dynamique et le typage statique est extrêmement proche de la différence entre la programmation ordinaire et la programmation par contrats.