¿La necesidad de especificaciones de diseño de software disminuyó significativamente con la evolución de lenguajes de programación más expresivos?

16

Para muchas personas de TI, incluido yo mismo hace unos años, el proceso de desarrollo de software ideal implicaría la creación de documentos de diseño detallados con muchos diagramas UML antes de que se escriba una línea de código. (Esto parece una descripción del modelo de cascada, pero es lo mismo con ágil, excepto que las iteraciones son más pequeñas).

Durante los últimos dos o tres años, he cambiado completamente de opinión. Todavía creo que una especificación detallada de requisitos con casos de prueba asociados es absolutamente esencial. Para proyectos grandes, también requeriría un resumen de la arquitectura general antes de comenzar a codificar. Pero todo lo demás debe hacerse en código tanto como sea posible. En el caso ideal, no debería haber una descripción del diseño del software, excepto el código mismo.

¿Cómo llegué a esta conclusión? Aquí hay algunos argumentos:

Realimentación

Las herramientas para escribir documentos o crear diagramas proporcionan pocos comentarios. Sí, hay herramientas de modelado que realizan algunas comprobaciones de consistencia en los diagramas UML, pero son limitadas y conllevan muchos gastos generales.

Sin comentarios, es difícil reconocer y corregir errores.

Tan pronto como escriba el código, recibirá muchos comentarios, por ejemplo:

  • Errores y advertencias del compilador.
  • Resultados de análisis de código estático
  • Pruebas unitarias

Los errores se pueden reconocer y corregir rápidamente.

Consistencia

Para asegurarse de que el código sea coherente con sus documentos, debe verificar una y otra vez. Si hay cambios frecuentes, es difícil mantener el código y los documentos sincronizados.

Refactorización

Existen herramientas y técnicas poderosas para refactorizar código, mientras que refactorizar descripciones textuales o diagramas suele ser difícil y propenso a errores.


Hay una condición previa para que esto funcione: el código debe ser lo suficientemente fácil de leer y comprender. Esto probablemente no se puede lograr con Assembler, Basic o Fortran, pero los lenguajes modernos (y las bibliotecas) son mucho más expresivos.

Entonces, si mis argumentos son válidos, debería haber una tendencia hacia una especificación y documentación de diseño de software menos o más liviana. ¿Hay alguna evidencia empírica de esta tendencia?

Frank Puffer
fuente
2
El diseño inicial cayó en desgracia debido a que el desarrollo ágil ganó popularidad a medida que la industria maduró. Los idiomas cada vez más expresivos y las herramientas de peso más liviano facilitaron la creación rápida de prototipos, lo que permitió un desarrollo más ágil. Creo que hay alguna causalidad entre los dos.
Restablece a Monica
14
Según mi experiencia, "la creación de documentos de diseño detallados con muchos diagramas UML antes de que se escriba una línea de código" nunca fue una buena idea, al menos no en el tiempo desde que trabajaba como programador profesional, que es más de uno década más de lo que existe UML. Sin embargo, esbozar un diseño de alto nivel antes de la codificación es y fue una buena idea cuando se espera que los sistemas tengan un cierto tamaño. Pero UML es, en mi humilde opinión, no la herramienta adecuada para esto.
Doc Brown
2
Demasiado flojo para una respuesta adecuada: los lenguajes de programación más expresivos y las computadoras más potentes generan necesidades de programas cada vez más capaces y complejos, lo que lleva a especificaciones de requisitos más complicadas.
whatsisname
2
Lectura recomendada: superando los promedios .
Robert Harvey
1
He trabajado en un proyecto con un diseño UML completo. Del cual generamos código. Llegué a la conclusión de que nunca quise volver a hacerlo. Fue mucho más difícil cambiar el UML que cambiar el código; y un modelo UML grande es al menos tan difícil de manejar como una gran cantidad de código fuente. El código "generado" era difícil de leer y el generador dejó "marcadores" en el código.
Nick Keighley

Respuestas:

9

Cuestiono la premisa de que los idiomas son cada vez más expresivos. Con el código ASP.NET de hoy en c #, escribo aproximadamente al mismo nivel que cuando escribí el código ASP en Visual Basic. Todavía usamos c ++. Javascript ha agregado características, pero en general el idioma no ha cambiado. Lo mismo con SQL.

Creo que estos otros cambios son más significativos:

  1. Adopción de pruebas unitarias automatizadas. Algunos dirían que las pruebas son la especificación. Por lo tanto, no hemos eliminado la necesidad de escribir especificaciones; más bien, los escribimos en código en lugar de en documentos de Word.

  2. Cambios en la metodología de implementación. En el pasado, era muy costoso cometer un error porque necesitaría enviar una copia actualizada de su software. Entonces tenías que tener cuidado. Con las aplicaciones basadas en web, puede implementar soluciones para su uso inmediato, y puede permitirse reaccionar a los problemas en lugar de anticiparlos, reestructurando el código a medida que avanza.

  3. Adopción de patrones de diseño. Cuando todos conocen los patrones, casi no tienes que diseñar nada; simplemente puede decir "agregar una fábrica de repositorios" y su equipo debería hacerlo sin necesidad de ver UML.

  4. Los contratos de datos de SOA. Casi todo es SOA en estos días. Todo lo que necesitas es un WSDL. Los días de definir y documentar los formatos de transferencia de datos se han ido. El movimiento actual hacia más RESTful y microservicios continúa esta tendencia.

  5. Los softwares son más pequeños. En parte como resultado de las arquitecturas SOA, los equipos están escribiendo programas más pequeños que están unidos. Cada componente individual es menos complejo y requiere menos diseño inicial; Además, es más fácil cambiar parte de la arquitectura sin romper la solución general debido a los cortafuegos forzados por las definiciones de interfaz entre los componentes.

  6. Mucho, mucho más uso de bibliotecas establecidas. .NET CLR ofrece una tonelada de funcionalidad lista para usar, por lo que no es necesario diseñar, por ejemplo, un esquema para almacenar en caché los datos de la sesión. Las bibliotecas de terceros como jQuery UI o Bootstrap establecen estándares para escribir código para que funcionen de cierta manera. No necesita documentar esto; los equipos deberían poder usarlos.

  7. Madurez de la industria. Las SWE han aprendido que no existe el proyecto "Battlestar Galactica" en el que pasas años tratando de alcanzar un objetivo específico; para cuando hayan pasado esos años, la meta habrá cambiado. Hoy sabemos que el tiempo de comercialización es mucho más importante que obtener todo exactamente como lo queremos en el diseño.

  8. Ingenieros mejor y más consistentemente educados. En estos días, puede contratar ingenieros que entiendan las mejores prácticas (con suerte) y las implementen sin un documento de diseño que les diga qué hacer.

  9. Las herramientas de productividad como TFS le permiten escribir una tarea simple que hace referencia a un caso de uso y proporciona un par de puntos para cualquier decisión técnica ambigua. No necesitas mucho más que eso. Los desarrolladores pueden revisar, estimar, obtener revisiones de código, registrar, etc. todo a través de la herramienta. Esto es mucho más eficiente que trabajar con documentos externos, ya que une todo.

Todavía necesita documentos de diseño para algunas cosas ... por ejemplo, si su aplicación se divide en diferentes componentes desarrollados por diferentes equipos, al menos debe decirles qué componente es responsable de qué requisitos. Pero en su mayor parte, las metodologías de desarrollo actuales permiten mucha más libertad al tiempo que le brindan herramientas para administrar y contener cualquier riesgo que pueda surgir de un desarrollador que toma una mala decisión.

John Wu
fuente
3
Nuestra industria ha madurado ... un poco. El ítem 5 es, con mucho, el cambio más importante; Impacta positivamente a todos los demás. Pero el hecho de que cambiemos en todas nuestras tecnologías cada 5 años sugiere que todavía tenemos un largo camino por recorrer, y la expresividad del lenguaje (lo único que es relativamente estable con el tiempo porque la mejora significativa en esa área es tan difícil) produce más ganancias de las que le das crédito.
Robert Harvey
1
No todo es progreso: el principal avance fue, con gracia, con la invención del compilador. Pero aún enseñamos diagramas de flujo, una abstracción sobre el código del ensamblador (y muchas otras prácticas obsoletas). ¿Probablemente porque hemos olvidado por qué?
ctrl-alt-delor
6

Yo diría que para n .

Por una simple razón que

Para muchas personas de TI, incluido yo mismo hace unos años, el proceso de desarrollo de software ideal implicaría la creación de documentos de diseño detallados con muchos diagramas UML antes de que se escriba una línea de código.

Nunca se consideró "ideal", ya que la Programación Extrema ha existido desde la década de 1990 . Y como dices:

En el caso ideal, no debería haber una descripción del diseño del software, excepto el código mismo.

Fue discutido por años atrás. Por ejemplo, este legendario artículo de 1992: ¿Qué es el diseño de software ?

Lo anterior muestra que puede tener un proceso "extremo" con una arquitectura altamente evolutiva y un enfoque iterativo sin la necesidad de lenguajes complejos o IDE.

En cambio, diría que este cambio "aparente" desde el diseño inicial con muchos diagramas y documentos de casos de uso a un enfoque más evolutivo e iterativo es simplemente reemplazar a los gerentes de la "vieja escuela" por otros nuevos, que crecieron en mucho más entorno dinámico y para quien es mucho más fácil aceptar y trabajar en un entorno más "ágil".

Eufórico
fuente
6

Estoy bastante de acuerdo con esto, pero creo que comenzó mucho antes de lo que implica. También creo que hay otro gran factor aparte de la expresividad. Cuando mi padre comenzó a programar, tuvo que crear tarjetas perforadas y programar el tiempo en la computadora. Es posible que tenga una oportunidad al día para ejecutar su programa. No hubo mucho tiempo para desperdiciar el código de construcción, dejándolo fallar y luego reparándolo. Tienes quizás 2 o 3 tiros y si no funcionaba, estabas en problemas.

El riesgo de esto significaba que era crucial pasar mucho tiempo extra para planificar su programa. La gente escribiría su código con lápiz y luego lo transferiría a las tarjetas perforadas. A medida que avanzaba la tecnología, podía codificar directamente en el terminal, pero aún usaba recursos compartidos y la CPU era cara. Una metodología de prueba primero sería completamente insostenible en ese mundo. Si no planificó con anticipación, sus compañeros estarían en su escritorio con horquillas.

Los recursos informáticos se han vuelto más baratos y mejores a un ritmo increíble. Muchas de las limitaciones bajo las cuales se desarrollaron todas estas prácticas están completamente borradas. Como señala Euphoric, el alejamiento de esto realmente comenzó en los años 90. La continuación de gran parte del gran diseño inicial ha sido pura inercia.

Entonces, sí, la expresividad mejorada de los lenguajes de programación ha tenido un impacto en esto por el simple hecho de que es más fácil usar código expresivo como su propia documentación. El costo de producir un documento que le dice lo que dice el código es muy alto y su valor (es inevitablemente incorrecto en algún nivel). Al mismo tiempo, el costo de tirar mierda a la pared y ver qué se pega es básicamente insignificante.

JimmyJames
fuente
3

¡Creo que olvidas el propósito de tener documentos de diseño en primer lugar!

Los documentos de diseño (requisitos, casos de uso, maquetas, etc.) nos permiten describir, comprender y discutir el sistema a un alto nivel. La cantidad de detalles que quedan de dichos documentos es lo que los hace útiles.

No es necesario tener documentos que describan el comportamiento exacto del sistema del sistema en todos los detalles, ya que de hecho el código fuente sirve para este propósito.

El desarrollo de software podría considerarse el proceso de transformar especificaciones legibles por humanos de alto nivel en especificaciones inequívocas de bajo nivel que son ejecutables por una máquina. Pero necesita alguna información para este proceso.

JacquesB
fuente
Claro, la documentación de alto nivel que no trata con detalles es absolutamente necesaria. Pero eso es exactamente lo que espero de un buen lenguaje de programación. Debería permitir escribir código en diferentes niveles de detalle. El código no tiene que ser un desorden no estructurado de instrucciones de bajo nivel.
Frank Puffer
@FrankPuffer un diagrama vale 100.000 LoC.
RubberDuck
1
@RubberDuck Se me ocurre que la capacidad (o la falta de ella) de generar varios diagramas útiles a partir del código podría ser una medida de la expresividad de un lenguaje. No hay un diagrama que pueda dibujar que no pueda expresarse en algún tipo de lenguaje. La pregunta es si ese idioma puede transmitir la misma información de una manera que se pueda escribir o leer fácilmente.
JimmyJames
1
@RubberDuck: los diagramas tienen sentido en algunos casos, por ejemplo, para explicar la arquitectura general. Pero no creo que deberían ser los predeterminados. Definitivamente hay diagramas buenos y útiles, pero desafortunadamente la mayoría de los UML que he visto son más confusos que útiles. Y lo que es peor, a menudo difiere de la implementación real.
Frank Puffer
Me gusta que mencione generar diagramas @JimmyJames. Prefiero la generación sobre la creación manual. Tienes un punto muy válido, pero me pregunto si es una función de expresividad o de herramientas.
RubberDuck
1

En el caso ideal, no debería haber una descripción del diseño del software, excepto el código mismo.

Esto está más lejos de lo que implica. Incluso cosas como los tipos dependientes (que, según tengo entendido, son bastante prometedores en teoría) están varios años fuera.

La verificación formal es bastante difícil y, por esa razón, el único lugar donde se usa comúnmente la verificación formal es en las bibliotecas de criptografía.

Pruebas unitarias

Si las pruebas de propiedad no han llegado a la corriente principal, no creo que esto sea práctico durante mucho tiempo.

Además, escribir buenas pruebas (que no necesitarán ser editadas con cada refactor pero aún detectarán suficientes errores) es bastante difícil.

Para asegurarse de que el código sea coherente con sus documentos, debe verificar una y otra vez. Si hay cambios frecuentes, es difícil mantener el código y los documentos sincronizados.

Probablemente más fácil de usar una herramienta de prueba de documentación en este momento.

Hay una condición previa para que esto funcione: el código debe ser lo suficientemente fácil de leer y comprender.

Desafortunadamente, es difícil diseñar lenguajes que no solo sean extremadamente expresivos sino que también sean legibles eminentemente. Los lenguajes como Go priorizan la legibilidad y obstaculizan el pensamiento de alto nivel.

Finalmente, en mi experiencia, mejores lenguajes y herramientas no conducen a un software con menos errores, sino a proyectos más grandes. Realmente no hay ninguna forma plausible pandocque se hubiera escrito en 1970.


fuente