¿Cómo manejan los equipos profesionales de desarrollo de software la complejidad del diseño en proyectos no triviales?


9

Primero, me doy cuenta de que esta pregunta puede ser algo larga y vaga y me disculpo por esto. Este es probablemente un problema básico con un nombre corto para cualquiera que lo haya "entendido", pero como me parece que me falta en este sentido, tenga paciencia para describir el problema.

He estado programando de esta forma u otra desde que tenía unos 11 años. Esto significa que he estado enseñándome todo desde el principio. Recibí una educación técnica, pero no estrictamente en Ciencias de la Computación (me gradué con un título en Ingeniería Fotónica). Teníamos cursos de programación, por supuesto, pero esto era sobre todo cosas básicas para mí y no aprendí muchas cosas nuevas. Seguí educándome en el camino por el placer de hacerlo y siempre supe que seguiría una carrera en programación, pero todos mis proyectos eran bastante pequeños en ese momento. No tuve problemas para mantenerlos en mi mente y mantenerlos.

Ahora, me encuentro a la cabeza de un equipo, pero no en un entorno corporativo: trabajo para la universidad desarrollando software científico (en C ++) para aplicaciones de ingeniería. De repente, el proyecto está creciendo (relativamente) a gran escala y la mayoría de las veces tengo problemas para entenderlo. Estoy perdiendo mucho tiempo y esfuerzo en dos cosas principalmente:

  1. Cuando tengo que volver a una sección de código en la que no he trabajado durante un tiempo, me cuesta recordar cómo funcionó. Paso mucho tiempo revisando los archivos de encabezado para las clases relevantes y leyendo los comentarios que coloqué en el camino en los archivos de origen. Desearía que hubiera alguna forma de "esquema" que pudiera vislumbrar y recuperar la imagen más fácilmente;
  2. Cuando introduzco cambios, a veces me doy cuenta a medias de que lo que estoy tratando de hacer romperá las cosas en otro lugar (o peor, solo se muestra en el tiempo de ejecución como una sorpresa). Revierto y comienzo a hacerlo de manera diferente, solo para descubrir que descuidé la influencia en algún otro componente. Desearía que hubiera algún "diagrama de arquitectura" en el que pudiera ver cómo se hacen las cosas, cómo lo que estoy tratando de hacer influirá en otros componentes y una forma de planificar en detalle antes de comenzar a implementar cambios.

La mayoría de las personas con las que trabajo tienen historias similares a las mías: una fuerte orientación técnica y, a veces, excelentes habilidades, pero no tienen forma de organizar su trabajo. Sin embargo, sus proyectos suelen ser mucho más pequeños que los míos, por lo que se las arreglan de alguna manera. De todos modos, lo que eso significa para mí es que estoy solo y no tengo a nadie de quien aprender las buenas prácticas.

Tomé un curso de posgrado en administración de TI y, aunque lo encuentro bastante satisfactorio, está dirigido principalmente a no programadores, enseñando sobre metodologías de administración de proyectos, estimaciones de presupuesto / cronograma, arquitectura empresarial, etc., no diseño y planificación de software como tal. Está bien, también estoy tratando de aprender esas cosas. Por supuesto, se introdujeron algunas herramientas (como UML) y los tipos de procesos de desarrollo de software (en cascada, iterativo, ágil ...), pero obviamente no con gran detalle y es difícil decidir qué debo elegir y usar ( y en qué medida).

He estado leyendo muchas preguntas y respuestas sobre el diseño de software en SO; hay muchas sobre hacerlo usando esta o aquella herramienta o metodología en particular, y si estuviera convencido de que la documentación UML resolvería mis problemas, lo recogería y empieza a usarlo. Pero algunas personas juran por eso, otras dicen que es inútil. Estoy buscando una respuesta en un nivel más alto de abstracción: ¿hay maneras de resolver los dos problemas que tengo y cómo lo hace personalmente? ¿Qué debo aprender para poder hacerlo, posiblemente sin estar obligado a una herramienta en particular? De vez en cuando, estos pasan de moda y espero que su aplicabilidad varíe según el tipo de proyecto.

Muchas gracias por leer, no pude decir lo que quiero decir más brevemente (falta de experiencia en diseño de software y vocabulario).


2
Creo que la respuesta profesional más común a las dificultades de las que está hablando es "A la mierda", seguida de culpar a la administración, el producto o algún otro SOB aleatorio.
Edward Strange

Respuestas:


9

Cuando tengo que volver a una sección de código en la que no he trabajado durante un tiempo, me cuesta recordar cómo funcionó. Paso mucho tiempo revisando los archivos de encabezado para las clases relevantes y leyendo los comentarios que coloqué en el camino en los archivos de origen.

Imagina cómo se va a sentir el pobre hombre que viene después de ti: ni siquiera tiene el beneficio de haber sabido una vez cómo funciona tu código. En lugar de tratar de descifrar su código, debería revisar la documentación que escribió para el módulo en cuestión. Esa documentación debe ofrecer una visión razonablemente precisa de lo que hace el módulo por qué. No es "el módulo comienza inicializando tres matrices usando un triple for loop ...", sino: "este módulo recupera los datos recopilados por el sensor principal del Fabulotron, los reorganiza en formato estándar Neopolitan (chocolate, vainilla, fresa), y lo entrega al módulo de Análisis ".

En un mundo perfecto, tendrías un documento de diseño que establece los diversos módulos en el sistema y describe sus respectivas responsabilidades, y cada uno de tus módulos podría referirse a ese documento para explicar lo que hacen: "Este módulo proporciona el Servicio de recopilación de datos Fabulotron como se detalla en la sección 4.8 del documento de diseño: http://fabulotron.org/design/section4-8.html ". Si no tiene algo así, comience a escribir una descripción general de cada módulo a medida que trabaja en él. No necesita escribir un libro: unos pocos párrafos suelen ser suficientes para orientarse.

Cuando introduzco cambios, a veces me doy cuenta a medias de que lo que estoy tratando de hacer romperá las cosas en otro lugar (o peor, solo se muestra en el tiempo de ejecución como una sorpresa). Revierto y comienzo a hacerlo de manera diferente, solo para descubrir que descuidé la influencia en algún otro componente.

Eso podría ser una indicación de que sus módulos están demasiado interconectados. Cuanto más independientes sean sus módulos / clases / unidades, menos probable será que se encuentre con este tipo de problema. Intente hacer que las interfaces entre los módulos sean lo más explícitas posible, e intente limitarlas a lo que necesita estar allí. Una interfaz es un contrato: si sabe que algún módulo cumple con sus obligaciones según lo especificado en la interfaz, no necesita saber nada más al respecto. Eso evita que los cambios en el módulo en el que está trabajando afecten a otros módulos.

Desearía que hubiera algún "diagrama de arquitectura" donde pudiera ver cómo se hacen las cosas

El uso de piezas estándar puede ayudar a este respecto. C ++ proporciona partes estándar en forma de la Biblioteca de plantillas estándar, y el uso de esas partes cuando sea apropiado le permite trabajar en un nivel superior de abstracción. Si ha escrito su propio código para administrar estructuras de datos como listas, usted y aquellos que lo siguen tendrán que leer constantemente la fuente para descubrir qué está sucediendo. Si, en cambio, utiliza partes estándar proporcionadas por STL, cualquier programador de C ++ podrá saber rápidamente qué está haciendo su código sin profundizar en sus rutinas de administración de datos.

Otro tipo de pieza estándar proviene de los patrones de diseño. Son conceptos estándar que se pueden usar como una forma abreviada para explicar cómo funciona la relación entre dos objetos.


Gracias por la respuesta. Por supuesto, he estado usando STL durante muchos años, pero la secuencia de pasos que toma mi programa para realizar algunos cálculos artificiales a veces es difícil de imaginar en su totalidad, incluso con su uso. Lo mismo ocurre con los módulos. No quise decir que cambiar uno rompe a otro, sino que cambiar algo en alguna parte causa un error, por ejemplo, cuando un usuario hace algo no estándar en la GUI donde una secuencia complicada se complica aún más por el orden impredecible de los pasos que toman para completarla.
neuviemeporte

5

Solo he sido desarrollador profesional durante un corto período de tiempo, y luché mucho con cómo hacerlo cuando comencé. Era principalmente autodidacta, incluso a través de la universidad. Afortunadamente para mí, las personas con las que trabajé tienen mucha experiencia y pudieron educarme sobre las formas de administrar y trabajar en grandes proyectos.

Una de las primeras cosas que me hizo hacer fue sentarme y leer código limpio . El cual es un libro fantástico que me ayudó a entender cómo escribir código que podría entender cuando volviera o que alguien más pudiera entender.

Lo segundo fue escribir pruebas de buena calidad, Unidad, Integración, Aceptación. Si su código está bien probado, sabrá rápidamente cuándo ha roto algo y podrá diagnosticar el problema rápidamente. Hay muchos recursos de prueba buenos en Internet, y no estoy seguro de cuáles son los mejores para sugerirle.

Mis puntos clave son Testing y Clean Code.


Gracias por la sugerencia, me aseguraré de revisar el libro (aunque el "ágil" en el subtítulo parece indicar que es más relevante para esa metodología). Tengo pruebas y he leído muchos libros de estilo de codificación (p. Ej., Programador pragmático) Siempre me esfuerzo por crear interfaces limpias y bien separadas, pero para una prueba automatizada es difícil para la parte GUI de mi aplicación y todavía no tengo un forma de hacer un buen diseño general a mayor escala, que va más allá de implementar prácticas "limpias" en fragmentos de código relativamente pequeños.
neuviemeporte

2

Aquí hay algunas ideas de alto nivel para organizar grandes sistemas de software. La mayor parte de mi experiencia es en sistemas de internet, pero creo que estas ideas se aplican al software de ingeniería.

  • Funcionalidad separada en bloques modulares relativamente aislados. Por ejemplo, puede tener un módulo para cada familia de cálculos que proporciona su software.
  • Aplique el patrón de diseño MVC para la interfaz de usuario, si existe. Mantenga la interfaz y el modelo separados con límites bien definidos.
  • Considere usar capas para agrupar módulos. En una aplicación que usa capas de abstracción, cada capa depende solo de la capa debajo de ella.
  • Al escribir documentación, suponga que olvidará todos los detalles de implementación. Escribirás una gran cantidad de documentación bajo este supuesto, tal vez hasta la mitad de tu código serán comentarios, pero más tarde te confundirás mucho menos.
  • Las pruebas automatizadas de unidad, integración y aceptación son excelentes en algunos espacios, pero los desarrolladores de C ++ parecen tener sentimientos encontrados al respecto.
  • Dibuja mucho en los patrones de diseño . Además de ser generalmente buenas ideas, los patrones de diseño proporcionan un vocabulario común en ingeniería de software. Llamar a una clase un WidgetFactory es una forma concisa de comunicar que es una clase que existe para crear widgets.

Ha pasado mucho tiempo desde que trabajé con el software de ingeniería, por lo que su kilometraje puede variar según estas sugerencias. ¡Buena suerte!


1

La respuesta es la ingeniería de software.

Es decir, para proyectos grandes, usted sigue una secuencia establecida de recopilación de requisitos, definición de proceso, especificación, etc., mucho antes de que se realice cualquier codificación real.

Se utilizan varias metodologías según el entorno y la cultura. Las empresas de tipo empresarial tienden a seguir un " Proceso unificado racional " o similar, las empresas de nueva creación suelen tener alguna variación en Agile , los departamentos gubernamentales y algunas metodologías de Cascada con exceso de trabajo .

En todos los casos, el proceso lo ayuda a definir exactamente lo que está haciendo y, hacia el final del proyecto, le permite demostrar que lo ha hecho.


Suponiendo que los requisitos no cambian (una suposición poco realista en muchos casos, lo sé), ¿es realmente posible especificar todo antes de la codificación y luego crear un software de trabajo de la especificación sin mayores alteraciones en el camino? Simplemente no puedo imaginarlo. Tengo que empezar a codificar para sentirme. ajustar un poco, ajustar un poco más, etc ...
neuviemeporte

Esto podría funcionar para proyectos pequeños, pero para proyectos grandes primero debe familiarizarse con los requisitos. También una parte vital de RUP es modelar el sistema propuesto con diagramas de secuencia y UML. Es mucho más fácil modificar y refactorizar un modelo que el código real.
James Anderson

@neuviemeporte: Depende. A veces los requisitos cambian o se descubren nuevos requisitos durante el desarrollo. A veces, los requisitos son bastante claros desde el principio y solo algunos detalles menores cambiarán durante el desarrollo, pero la arquitectura general seguirá siendo la misma.
Giorgio

1

Recomiendo encarecidamente tener a Enterprise Architect , que si bien no es gratuito, ofrece precios académicos. Es una excelente herramienta para esquematizar proyectos tanto a nivel macro como micro. También puede aplicar ingeniería inversa a sus archivos de origen en diagramas de clases, lo que probablemente sería un buen comienzo para documentar y reorganizar el funcionamiento de su aplicación.

También recomendaría las recomendaciones de @ Klee. No se desanime por las supuestas herramientas "ágiles", ya que en realidad son solo elementos de mejores prácticas que también son útiles (si no es obligatorio) si está siguiendo un proceso ágil. Pero la integración continua (por ejemplo) es valiosa sin importar su metodología. Además, las pruebas unitarias (cppUnit?) Son tus amigos. Las pruebas unitarias deberían ser muy factibles si prueba las clases lógicas a las que llama su interfaz de usuario, en lugar de probar la interfaz de usuario directamente. También hay herramientas que podrían ayudarlo a automatizar las pruebas de interfaz de usuario, pero primero trataría de juntar las cosas del back-end.

¡Buena suerte!


1

Creo que tu problema tiene tres dimensiones.

  1. Orientado a programadores
  2. Orientado a programas
  3. Mantenimiento del programa - Orientado

Con respecto al primer problema, es posible que tenga programadores que no entiendan el concepto de lo que hace el programa (esto sucede a menudo en configuraciones corporativas). Pero siguiendo su pregunta y el dominio en el que se encuentra, parece que usted y su equipo tienen el control de lo que hace el programa, pero simplemente no pueden traducirlo a un programa de trabajo en poco tiempo (para citar un ejemplo, he oído hablar de personas Tener un posdoctorado en Física, tener problemas para entender los punteros en programación y estoy seguro de que la Física es mucho más difícil que C ++). Si ese es el caso, entonces su problema se centra principalmente en el Programa (debe sentirse lo suficientemente afortunado de que las personas que lo rodean puedan entender lo que está haciendo su programa y puedan apreciarlo).

En caso de problemas centrados en el programa, una de mis sugerencias escandalosas sería pasar a un nivel de abstracción más alto que C ++, como aprender un nuevo lenguaje como Python o Haskell (Python es bastante fácil de aprender y si tienes buenos matemáticos, Haskell es simplemente genial). Pasar a un nivel más alto de abstracción mantendría el tamaño de su código bajo, fácil de entender y mantener a largo plazo y produciría cambios rápidamente. Por lo tanto, puede tener 10 líneas de código en lugar de las 50 líneas de código originales. Además, tener a alguien con experiencia en programación de computadoras definitivamente ayudaría. Al estar en una universidad, también puede involucrar a algunos estudiantes en GUI e interfaces para que pueda concentrarse más en la funcionalidad. También recomiendo el libro Diseño de software C ++ a gran escala de John Lakos(Es un libro bastante grande, puedes convertirte en un programador de Python competente en el tiempo que tardaste en leer el libro)

Si clasifica las 2 primeras dimensiones de su problema, la tercera se resuelve automáticamente. Como creo que está trabajando en un solo proyecto grande, cualquier software de gestión de proyectos decente que lo ayude a superarlo. La planificación inicial es necesaria. Si comienza a codificar de inmediato, puede involucrarse demasiado en el programa como para olvidar el panorama general. Tener las cosas en mente no funcionaría para un gran proyecto. Ponga todo en papel (o en la computadora). Usa una wiki para compartir información. En cuanto a las metodologías, prefiero la metodología ágil (simplemente, ágil es un nombre elegante para el desarrollo de software incremental). También sugiero contratar a alguien con experiencia en esta área para que se encargue de esto y que pueda concentrarse en su programa principal. La conclusión aquí es que todas las metodologías de gestión de proyectos son solo una forma de garantizar el éxito del programa; para que pueda elegir a cualquiera que se adapte a usted y a su equipo en lugar de seleccionar algo que alguien recomiende mejor. Además, el siguiente software también puede ayudarlo

  • Free Mind - Software de mapas mentales
  • Trac: programa de errores de software rápido y fácil y un wiki
  • MoinMoin: wiki rápido para permitir el intercambio de conocimientos sobre el programa

Aunque los consejos anteriores tomarían algo de curva de aprendizaje, a la larga vale la pena. Y finalmente, la programación es más fácil que la Ingeniería Fotónica (aunque no la Programación C ++)


0

Al igual que su pregunta, cualquier respuesta que sea útil para usted será muy larga y vaga, pero la respuesta corta es "Ingeniería de software"

Le sugiero que dedique algo de tiempo libre, tanto como sea posible si se toma en serio una carrera de desarrollo de software, y comience visitando el sitio de Steve McConnells . La programación es fácil y puede enseñarse en un semestre, la Ingeniería de Software es un orden de magnitud más complejo y necesita mucho más tiempo para aprender.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.