No sé de dónde viene la afirmación de que "a menudo no se puede realizar un análisis estático". La primera parte de la afirmación es claramente errónea. El segundo depende de lo que quiere decir con "a menudo". Prefiero decir que a menudo realiza análisis estáticos, y rara vez falla. En la aplicación comercial ordinaria, rara vez se acerca mucho más que nunca .
Así que aquí viene, el primer beneficio:
Ventaja 1: análisis estático
Las afirmaciones ordinarias y la comprobación de argumentos tienen un inconveniente: se posponen hasta que se ejecuta el código. Por otro lado, los contratos de código se manifiestan a un nivel mucho más temprano, ya sea en el paso de codificación o al compilar la aplicación. Cuanto antes detecte un error, menos costoso será solucionarlo.
Beneficio 2: tipo de documentación siempre actualizada
Los contratos de código también proporcionan una especie de documentación que siempre está actualizada. Si el comentario XML del método SetProductPrice(int newPrice)
indica que newPrice
debe ser superior o igual a cero, puede esperar que la documentación esté actualizada, pero también puede descubrir que alguien cambió el método para que newPrice = 0
arroje un documento ArgumentOutOfRangeException
, pero nunca cambió la documentación correspondiente. Dada la correlación entre los contratos de código y el código en sí, no tiene el problema de documentación fuera de sincronización.
El tipo de documentación proporcionada por los contratos de código también es valioso de una manera que a menudo, los comentarios XML no explican bien los valores aceptables. ¿Cuántas veces me preguntaba si era null
o string.Empty
o \r\n
es un valor autorizado para un método y comentarios XML guardaron silencio en eso!
En conclusión, sin contratos de código, muchos códigos son así:
Aceptaré algunos valores pero no otros, pero tendrá que adivinar o leer la documentación, si corresponde. En realidad, no lea la documentación: está desactualizada. Simplemente recorra todos los valores y verá los que me hacen lanzar excepciones. También tiene que adivinar el rango de valores que pueden devolverse, porque incluso si le contara un poco más sobre ellos, puede que no sea cierto, dados los cientos de cambios que me hicieron durante los últimos años.
Con los contratos de código, se convierte en:
El argumento del título puede ser una cadena no nula con una longitud de 0..500. El entero que sigue es un valor positivo, que puede ser cero solo cuando la cadena está vacía. Finalmente, devolveré un IDefinition
objeto, nunca nulo.
Ventaja 3: contratos de interfaces
Un tercer beneficio es que los contratos de código potencian las interfaces. Digamos que tienes algo como:
public interface ICommittable
{
public ICollection<AtomicChange> PendingChanges { get; }
public void CommitChanges();
...
}
¿Cómo podría, utilizando solo afirmaciones y excepciones, garantizar que solo CommitChanges
se puede llamar cuando PendingChanges
no está vacío? ¿Cómo garantizarías que PendingChanges
nunca es así null
?
Beneficio 4: hacer cumplir los resultados de un método
Finalmente, el cuarto beneficio es poder obtener Contract.Ensure
los resultados. ¿Qué pasa si, al escribir un método que devuelve un número entero, quiero estar seguro de que el valor nunca es inferior o igual a cero? ¿Incluso cinco años después, después de sufrir muchos cambios de muchos desarrolladores? Tan pronto como un método tiene múltiples puntos de retorno, se Assert
convierte en una pesadilla de mantenimiento para eso.
Considere los contratos de código no solo como un medio de corrección de su código, sino como una forma más estricta de escribir código. De manera similar, una persona que usaba lenguajes dinámicos exclusivamente puede preguntar por qué impondría los tipos a nivel de lenguaje, mientras que puede hacer lo mismo en afirmaciones cuando sea necesario. Puede hacerlo, pero la escritura estática es más fácil de usar, menos propensa a errores en comparación con un montón de aserciones y la autodocumentación.
La diferencia entre la escritura dinámica y la escritura estática es extremadamente cercana a la diferencia entre la programación ordinaria y la programación por contratos.