Recientemente descubrí Design by Contract (DbC) y me parece una forma extremadamente interesante de escribir código. Entre otras cosas, parece ofrecer:
- Mejor documentación Como el contrato es la documentación, es imposible que uno esté desactualizado. Además, debido a que el contrato especifica exactamente lo que hace una rutina, ayuda a admitir la reutilización.
- Depuración más simple. Dado que la ejecución del programa se detiene en el momento en que falla un contrato, los errores no pueden propagarse y la afirmación específica violada se resaltará presumiblemente. Esto ofrece soporte durante el desarrollo y durante el mantenimiento.
- Mejor análisis estático. DbC es básicamente una implementación de la lógica de Hoare, y deberían aplicarse los mismos principios.
Los costos, en comparación, parecen ser bastante pequeños:
- Mecanografía extra con los dedos. Dado que los contratos tienen que ser explicados.
- Toma cierta cantidad de entrenamiento para sentirse cómodo con la redacción de contratos.
Ahora, estando familiarizado con Python principalmente, me doy cuenta de que de hecho es posible escribir condiciones previas (simplemente lanzando excepciones para entradas inapropiadas) e incluso es posible usar aserciones para probar nuevamente ciertas condiciones posteriores. Pero no es posible simular ciertas características como 'viejo' o 'resultado' sin un poco de magia adicional que, en última instancia, se consideraría no Pythonic. (Además, hay algunas bibliotecas que ofrecen soporte, pero en última instancia obtengo la sensación de que sería un error usarlas, ya que la mayoría de los desarrolladores no lo hacen). Supongo que es un problema similar para todos los demás idiomas (excepto, por supuesto, , Eiffel).
Mi intuición me dice que la falta de apoyo debe ser el resultado de algún tipo de rechazo a la práctica, pero la búsqueda en línea no ha sido fructífera. Me pregunto si alguien puede aclarar por qué la mayoría de los idiomas modernos parecen ofrecer tan poco soporte. ¿La DbC es defectuosa o demasiado cara? ¿O es simplemente obsoleto debido a la programación extrema y otras metodologías?
fuente
Respuestas:
Podría decirse que son compatibles en prácticamente todos los lenguajes de programación.
Lo que necesitas son "afirmaciones".
Estos se codifican fácilmente como declaraciones "if":
Con esto, puede escribir contratos colocando tales afirmaciones en la parte superior de su código para restricciones de entrada; aquellos en los puntos de retorno son restricciones de salida. Incluso puede agregar invariantes a todo su código (aunque en realidad no son parte del "diseño por contrato").
Así que sostengo que no están muy extendidos porque los programadores son demasiado vagos para codificarlos, no porque no puedas hacerlo.
Puede hacer que estos sean un poco más eficientes en la mayoría de los idiomas definiendo una "verificación" constante booleana en tiempo de compilación y revisando un poco las declaraciones:
Si no le gusta la sintaxis, puede recurrir a varias técnicas de abstracción del lenguaje, como las macros.
Algunos idiomas modernos le dan una buena sintaxis para esto, y eso es lo que creo que quiere decir con "soporte de idiomas modernos". Eso es soporte, pero es bastante delgado.
Lo que la mayoría de los lenguajes modernos no le dan son afirmaciones "temporales" (sobre estados arbitrarios anteriores o siguientes [operador temporal "eventualmente"], que necesita si desea escribir contratos realmente interesantes. Las declaraciones IF no ayudarán tu aquí.
fuente
super
método y posiblemente descartar los resultados si solo desea que se verifiquen los contratos sin duplicación. Esto realmente ayuda a implementar un código limpio que cumpla con LSP.Como usted dice, Design by Contract es una característica de Eiffel, que durante mucho tiempo ha sido uno de esos lenguajes de programación que es muy respetado en la comunidad, pero que nunca ha tenido éxito.
DbC no se encuentra en ninguno de los lenguajes más populares porque es relativamente reciente que la comunidad de programación principal ha aceptado que agregar restricciones / expectativas a su código es algo "razonable" que los programadores esperan. Ahora es común que los programadores comprendan cuán valiosas son las pruebas unitarias, y eso se tradujo en que los programadores acepten más poner código para validar sus argumentos y ver los beneficios. Pero hace una década, probablemente la mayoría de los programadores dirían "eso es solo trabajo extra para cosas que sabes que siempre estarán bien".
Creo que si tuviera que acudir al desarrollador promedio hoy y hablar sobre las condiciones posteriores, ellos asentirían con entusiasmo y dirían "OK, eso es como una prueba unitaria". Y si habla de condiciones previas, dirían "OK, eso es como la validación de parámetros, que no siempre hacemos, pero, ya sabes, supongo que está bien ..." Y luego, si hablas de invariantes , empezarían a decir "Caramba, ¿cuánto cuesta esto? ¿Cuántos errores más vamos a atrapar?" etc.
Así que creo que todavía queda un largo camino por recorrer antes de que DbC sea adoptado de manera muy amplia.
fuente
Falso.
Es una práctica de diseño . Se puede incorporar explícitamente en código (estilo Eiffel) o implícitamente en código (la mayoría de los idiomas) o en pruebas unitarias. La práctica del diseño existe y funciona bien. El soporte de idiomas está en todo el mapa. Sin embargo, está presente en muchos idiomas en el marco de prueba de la unidad.
Es caro. Y. Más importante aún, hay algunas cosas que no se pueden probar en un idioma determinado. La terminación de bucle, por ejemplo, no se puede probar en un lenguaje de programación, requiere una capacidad de prueba de "orden superior". Entonces, algunos tipos de contratos son técnicamente inexpresables.
No.
Usamos principalmente pruebas unitarias para demostrar que se cumple DbC.
Para Python, como notó, el DbC va en varios lugares.
Los resultados de la prueba de docstring y docstring.
Afirmaciones para validar entradas y salidas.
Pruebas unitarias.
Promover.
Puede adoptar herramientas alfabetizadas de estilo de programación para escribir un documento que incluya su información de DbC y que genere scripts de prueba unitarios Python plus limpios. El enfoque de programación alfabetizada le permite escribir una buena literatura que incluye los contratos y la fuente completa.
fuente
there are some things which cannot be proven
. La verificación formal puede ser excelente, ¡pero no todo es verificable! ¡Entonces esa característica realmente restringe lo que el lenguaje de programación puede hacer realmente!Solo adivinando. Quizás parte de la razón por la que no es tan popular es porque "Design by Contract" es una marca registrada de Eiffel.
fuente
Una hipótesis es que para un programa complejo suficientemente grande, especialmente aquellos con un objetivo en movimiento, la masa de contratos en sí puede volverse tan defectuosa y difícil de depurar, o más que el código del programa solo. Al igual que con cualquier patrón, puede haber un uso más allá de los rendimientos decrecientes, así como claras ventajas cuando se usa de una manera más específica.
Otra posible conclusión es que la popularidad de los "lenguajes administrados" es la prueba actual de soporte de diseño por contrato para las características administradas seleccionadas (límites de matriz por contrato, etc.)
fuente
La razón por la que la mayoría de los idiomas principales no tienen características de DbC en el idioma es que la relación costo / beneficio de implementarlo es demasiado alta para el implementador del lenguaje.
un lado de esto ya se ha visto en las otras respuestas, las pruebas unitarias y otros mecanismos de tiempo de ejecución (o incluso algunos mecanismos de tiempo de compilación con metaprogramación de plantillas) ya pueden brindarle gran parte de la bondad de DbC. Por lo tanto, si bien hay un beneficio, es probable que se considere bastante modesto.
El otro lado es el costo, la adaptación retroactiva de DbC en un idioma existente es probablemente un cambio demasiado grande y muy complejo para arrancar. Introducir una nueva sintaxis en un idioma sin romper el código antiguo es difícil. La actualización de su biblioteca estándar existente para usar un cambio de tan largo alcance sería costosa. Por lo tanto, podemos concluir que implementar funciones de DbC en un lenguaje existente tiene un alto costo.
También señalaría que los conceptos que son más o menos contratos para plantillas y, por lo tanto, algo relacionados con DbC, se eliminaron del último estándar C ++, ya que incluso después de años de trabajo en ellos, se estimó que todavía necesitaban años de trabajo. Este tipo de cambios grandes, amplios y amplios a los idiomas son demasiado difíciles de implementar.
fuente
DbC se usaría más ampliamente si los contratos pudieran verificarse en el momento de la compilación para que no fuera posible ejecutar un programa que violara cualquier contrato.
Sin el soporte del compilador, "DbC" es solo otro nombre para "verificar invariantes / supuestos y lanzar una excepción si se viola".
fuente
Tengo una explicación simple, la mayoría de las personas (incluidos los programadores) no quieren trabajo extra a menos que lo vean necesario. Programación de aviónica donde la seguridad se considera muy importante No he visto la mayoría de los proyectos sin ella.
Pero si está considerando la programación de sitios web, computadoras de escritorio o dispositivos móviles, los bloqueos y el comportamiento inesperado a veces no se consideran malos y los programadores simplemente evitarán el trabajo adicional al informar errores y luego corregirlos se considera lo suficientemente adecuado.
Esta es probablemente la razón por la que creo que Ada nunca se recuperó fuera de la industria de programación de aviación porque requiere más trabajo de codificación, aunque Ada es un lenguaje increíble y si desea construir un sistema confiable, es el mejor lenguaje para el trabajo (excluyendo SPARK, que es propietario lenguaje basado en Ada).
Las bibliotecas de diseño por contrato para C # fueron experimentales por Microsoft, y son muy útiles para construir software confiable, pero nunca cobraron impulso en el mercado, de lo contrario, las habría visto ahora como parte del lenguaje central de C #.
Las afirmaciones no son lo mismo que el soporte completamente funcional para condiciones previas / posteriores e invariante. Aunque puede intentar emularlos, un lenguaje / compilador con el soporte adecuado realiza el análisis del "árbol de sintaxis abstracta" y comprueba si hay errores lógicos que simplemente no pueden hacer las aserciones.
Editar: Hice una búsqueda y a continuación hay una discusión relacionada que podría ser útil: https://stackoverflow.com/questions/4065001/are-there-any-provable-real-world-languages-scala
fuente
La mayoría de las razones son las siguientes:
fuente