Mejores prácticas para entregar el código heredado

66

En un par de meses, un colega se mudará a un nuevo proyecto y yo heredaré uno de sus proyectos. Para prepararme, ya he ordenado a Michael Feathers ' Trabajar de manera efectiva con el código heredado .

Pero estos libros, así como la mayoría de las preguntas sobre el código heredado que encontré hasta ahora, se refieren al caso de heredar el código tal como está. Pero en este caso, realmente tengo acceso al desarrollador original y tenemos algo de tiempo para una entrega ordenada.

Algunos antecedentes sobre el código que heredaré:

  • Está funcionando: No hay errores conocidos, pero a medida que aumentan los requisitos de rendimiento, algunas optimizaciones serán necesarias en un futuro no muy lejano.
  • Sin documentar: Hay prácticamente cero documentación a nivel de método y clase. Sin embargo, lo que se supone que debe hacer el código en un nivel superior está bien entendido, porque he estado escribiendo en contra de su API (como una caja negra) durante años.
  • Solo pruebas de integración de nivel superior: Solo hay pruebas de integración que prueban la interacción adecuada con otros componentes a través de la API (de nuevo, caja negra).
  • Nivel muy bajo, optimizado para la velocidad: Debido a que este código es fundamental para todo un sistema de aplicaciones, muchos de ellos se han optimizado varias veces a lo largo de los años y son de muy bajo nivel (una parte tiene su propio administrador de memoria para ciertas estructuras / registros).
  • Simultáneamente y sin bloqueo: Aunque estoy muy familiarizado con la programación simultánea y sin bloqueo y en realidad he contribuido con algunas piezas a este código, esto agrega otra capa de complejidad.
  • Base de código grande: Este proyecto en particular tiene más de diez mil líneas de código, por lo que no hay forma de que se me explique todo.
  • Escrito en Delphi: Voy a poner esto en práctica, aunque no creo que el lenguaje sea pertinente a la pregunta, ya que creo que este tipo de problema es agnóstico.

Me preguntaba cómo sería mejor pasar el tiempo hasta su partida. Aquí hay un par de ideas:

  • Obtenga todo para construir en mi máquina: A pesar de que todo debe estar incluido en el control de código fuente, quien no se ha olvidado de registrar un archivo de vez en cuando, por lo que este debe ser el primer orden de negocio.
  • Más pruebas: Aunque me gustaría realizar más pruebas unitarias de nivel de clase para que cuando haga los cambios, cualquier error que presente pueda detectarse desde el principio, el código tal como está ahora no es verificable (enorme clases, métodos largos, demasiadas dependencias mutuas).
  • Qué documentar: creo que, para empezar, sería mejor enfocar la documentación en aquellas áreas del código que de otra forma sería difícil de entender, por ejemplo. Debido a su naturaleza de bajo nivel / altamente optimizada. Me temo que hay un par de cosas allí que pueden parecer desagradables y que necesitan refactorización / reescritura, pero en realidad son optimizaciones que han estado ahí por una buena razón que podría pasar por alto (véase Joel Spolsky, Cosas que nunca debes hacer, Parte I )
  • Cómo documentar: creo que algunos diagramas de clase de la arquitectura y diagramas de secuencia de funciones críticas acompañados de cierta prosa serían los mejores.
  • A quién documentar: Me preguntaba qué sería mejor, que escribiera la documentación o que me la explicara, para poder escribirla. Me temo que las cosas que son obvias para él, pero no para mí, no estarían cubiertas adecuadamente.
  • Refactorización usando programación de pares: Esto podría no ser posible debido a limitaciones de tiempo, pero tal vez podría refactorizar parte de su código para hacerlo más fácil de mantener mientras todavía estaba allí para proporcionar información sobre por qué las cosas son como son.

Por favor comenta y agrega a esto. Ya que no hay tiempo suficiente para hacer todo esto, estoy particularmente interesado en cómo priorizaría.

Actualización: Al finalizar el proyecto de traspaso, he ampliado esta lista con mis propias experiencias en esta respuesta a continuación .

    
pregunta PersonalNexus 07.11.2011 - 20:44

11 respuestas

25

Cuando tenga acceso al desarrollador que codifique, pregunte: -

  • ¿Qué módulos fueron los más difíciles de codificar / implementar? Cuáles fueron los problemas y cómo fueron superados.

  • Qué módulos han generado la mayoría de los errores.

  • Qué módulos han resultado en los errores más difíciles de resolver.

  • De qué bits de código está más orgulloso.

  • Qué partes de código realmente le gustaría refactorizar, pero no ha tenido el tiempo.

Estas preguntas le darán una idea de lo que le causará la mayoría de los problemas y, lo que es más importante, un control sobre los procesos de pensamiento y las perspectivas del desarrollador original.

    
respondido por el James Anderson 08.11.2011 - 05:53
17

Al terminar el proyecto de entrega, creo que me tomaría el tiempo y escribiría mi propia respuesta con las cosas que mejor me funcionaron.

  • Obtenga todo bajo el control de versiones: después de asegurarme de que todo lo que necesitaba construir estaba bajo el control de versiones, también busqué en el disco duro del viejo desarrollador, para buscar scripts adicionales o utilidades que serían útiles para implementar y / o probar la aplicación pero no se registró.
  • De arriba a abajo: Comenzaría con una mirada de alto nivel a las clases principales y una visita guiada con el antiguo desarrollador de las áreas principales. Luego me gustaría profundizar en el resto por mi cuenta, marcando cosas que no tenían sentido para mí con los marcadores //TODO .
  • Escriba toda la documentación por mí mismo: Mientras el desarrollador anterior revisaba mis escritos para asegurarme de que lo hacía bien, insistí en escribir todo yo mismo. De esta manera, me aseguraría de que la escritura tuviera sentido para mí y no solo para el desarrollador anterior.
  • Comentarios en todas partes: agregué resúmenes de documentación XML a cada clase y cada método. De esta manera, me aseguré de haber mirado al menos cada pieza de código y tener suficiente entendimiento para resumir lo que hizo en una oración. También hizo que la comprensión de los métodos utilizando métodos / clases de resumen sea más fácil a medida que IntelliSense recoge esta información. También pude identificar fácilmente las áreas del código que aún tenía que ver.
  • Documento cercano a la fuente: Para facilitar la conexión entre el código fuente y la documentación, coloco la mayor parte de mi documentación en el código fuente. Para la documentación de alto nivel que describe la interacción entre varios subsistemas, utilicé una wiki, ya que poner esta información en un solo lugar en el código no funcionó. Toda la documentación debe ser de búsqueda electrónica y de texto completo.
  • Diagramas: Para obtener una descripción básica, utilicé diagramas de clase de diversas granularidades para los diferentes subsistemas. Para las partes concurrentes, los diagramas de objetos e interacciones han sido realmente útiles; vea también mi otra pregunta sobre el tema .
  • Refactorización como un par: Aunque realicé un poco de refactorización con el desarrollador anterior para tener una idea del código y hacer que las cosas fueran más fáciles de mantener, este fue un proceso lento y también arriesgado, debido a la falta de bien. Herramientas de refactorización y un montón de dependencias desagradables entre las distintas partes. El Trabajo eficaz con el código heredado de Michael Feathers es una muy buena ayuda para esto, a pesar de que la refactorización sin el apoyo adecuado de la herramienta todavía es dolorosa. Mientras lo refactorizaba, le permitía controlar el mouse y el teclado, ya que era más divertido para él (vea también mi última viñeta) y era libre de escribir lo que estaba aprendiendo.
  • Controles separados para comentarios y cambios: Después de que accidentalmente presenté un error al escribir un comentario sobre un override , he tenido cuidado de hacer comentarios y cambios en los registros separados. Utilicé una pequeña utilidad para eliminar todos los comentarios del código fuente antes de registrar algo, por lo que una diferencia de un registro solo para comentarios mostraría 0 diferencias. Todos los cambios (por ejemplo, la eliminación de campos no utilizados) se revisaron cuidadosamente con el desarrollador anterior para asegurarse de que no estaba eliminando las cosas que aún eran necesarias.
  • Recorrido línea por línea de pasajes críticos: Para los pasajes más optimizados / complejos, revisaría el código línea por línea con el desarrollador anterior y, a veces, incluso con un tercer colega. De esta manera obtuve una comprensión profunda del código y, a medida que más personas lo revisaban, identificamos algunos errores y otras cosas que podrían optimizarse aún más.
  • Sea rápido y mantenga motivado al desarrollador anterior: noté que el desarrollador anterior estaba cada vez menos interesado a medida que se acercaba su último día (no es sorprendente). Por lo tanto, me aseguraría de que las partes más críticas se entregaran primero, dejando el resto para que yo averigüe por mi cuenta, si es necesario. También traté de dejarle las cosas más divertidas (por ejemplo, el control del teclado cuando se programan en par) y hacer las cosas aburridas como la documentación que escribo yo mismo.
  • Identificar solicitudes de funciones: encontré útil pedirle al desarrollador anterior una lista de funciones que la gente había pedido pero que aún no se habían agregado. Hubo algunas cosas que para mí parecían fáciles de agregar, pero donde había una buena razón para no agregarlas, ya que se habrían roto otras cosas cuando se implementaran de la manera que pensé al principio.
respondido por el PersonalNexus 01.02.2012 - 21:55
14

Habiendo estado en una situación similar, creo que también valdría la pena considerar lo siguiente:

  • Asegúrese de que puede realizar y probar una implementación: haga su propia implementación del producto desde cero y verifique que esta sea idéntica a una realizada por la persona que se va Esto aseguraría que los scripts e instrucciones sean claros para usted, y detectaría cualquier descuido accidental, como que los ingredientes no se hayan registrado en su sistema de control de versiones. (No estoy diciendo que esto pasaría , solo que si ha sucedido , será mucho más fácil lidiar ahora, antes de que la persona se vaya)

    (Esto puede no ser relevante para usted, por ejemplo, si ya realiza Integración Continua o Implementación Continua, pero vale la pena mencionar, por si acaso ...)

  • Escribiendo más pruebas: Esta es una buena forma de realmente para probar su comprensión de un sistema. Lo habilitará (o lo forzará) para que mire más de cerca las áreas del código y confirmará que el código está libre de errores como lo sospecha, o revelará las áreas en las que pensó entendió la intención, pero en realidad es necesario pedirle a su colega una aclaración antes de que se vaya

  • Escritura en pares de la documentación: esta es una forma efectiva de escribir resúmenes. Le sugiero que haga que su colega describa una característica o área, y luego usted la escriba, en la documentación, en sus propias palabras. Descubrimos que esto era enormemente más fácil cuando lo hacían dos personas juntas.

Yo pondría la escritura de las pruebas como una prioridad más alta que la escritura de la documentación, personalmente, ya que las pruebas probablemente le darán una comprensión mayor o más firme.

En lo que respecta a Refactorización usando la programación por pares , lo único que diría es que existe el peligro de que esto se convierta en un pozo sin fondo, especialmente dado que usted dijo que solo ha alcanzado el límite. Pruebas de nivel. Podría encontrar que termina usando mucho más tiempo disponible del que esperaba.

    
respondido por el Clare Macrae 09.11.2011 - 22:38
10

+1 para las respuestas que ya tiene en su pregunta!

Visita guiada
10k líneas de código es mucho, pero creo que todavía no es imposible que el otro te dé una "visita guiada". Se sientan juntos frente al código y él lo lleva en un viaje de arriba abajo, trabajando las "capas". Tendrías que hacerlo en ráfagas breves, todo de una vez te mataría a ambos.

Acercar, alejar
La ventaja de hacer esto es que, si bien te lo está explicando, es casi seguro que tendrá algunos momentos "oh, sí, hay esto también" que podría no tener si solo intentara documentarlo por su cuenta. Y sus preguntas ayudarán a concentrarse en los bits obvios para él y para nadie más. Este tipo de interacción zoom-in / zoom-out solo es posible uno-a-uno, tratar de escribir o leer algo así es difícil de manejar.

Documentación
Creo que ambos deberían estar documentando cosas de forma independiente: él debería comenzar desde abajo (en caso de que no tenga tiempo para llegar a estar juntos), y debería comenzar desde arriba, sobre la base de lo que ha entendido de su visita guiada y como si fuera para otra persona [en un trabajo anterior, heredé una carga de código 'heredado', y solo tuve el tiempo de documentarlo antes de irme:)].

¿Dónde está qué?
El objetivo de la mayor parte de esto es que usted pueda tener una idea de dónde suceden las cosas. Por lo tanto, dado un error o modificación en particular, puede encontrar muy rápidamente el lugar en el código en el que necesita concentrarse. Usted podría probarse a sí mismo tomando la lista de errores antiguos y viendo si puede predecir con precisión dónde se encontraba el problema.

Bombéalo seco
No importa si él termina odiándote (sonríe), tu trabajo es obtener la mayor cantidad de información del cerebro de ese chico que puedas en el tiempo disponible. Asegúrate de que la administración esté de tu lado y que prioricen la transferencia de conocimientos sobre "solo corregir los últimos errores antes de que se vaya" (a menos que los estés solucionando juntos ...).

    
respondido por el Benjol 10.11.2011 - 08:49
7

Sugiero lo siguiente (además de lo que ya está identificado): primero, pídale a su gerente que le dé tiempo para trabajar con este tipo tanto como sea posible y trate de sentarse con él cada vez que tenga la tarea de hacer un cambio. No tienes que saber todo lo que está haciendo, pero trata de atrapar todo lo que puedas. Lo más importante es ser amigo de él.

Considere la entrega como un proyecto, elabore un plan e implique a la administración.

0: asegúrate de saber cómo usar el sistema.

1 - Haga un inventario claro de los componentes de la solución, la fuente de cada uno y dónde se encuentra (en diferentes repositorios)

2 - Obtenga y, si es posible, administre las contraseñas para los diferentes servidores que comienzan ahora. Asegúrate de tener toda la información de la cuenta de administrador

3: obtenga las licencias de cada componente externo a menos que esté fuera de su alcance (por ejemplo, dlls especiales, base de datos, etc.)

4 - Obtenga un informe escrito sobre el estado actual del sistema por parte del desarrollador y sus clientes (si son locales para su empresa)

5 - Obtenga la documentación para las reglas comerciales, fórmulas de cálculo, etc. Puede hacerlo con él. Pídale correos electrónicos, información sobre reuniones, documentos de requisitos del usuario, documentos de diseño y similares que se le entregarán.

6 - Obtenga una lista de eventos programados (ejecuciones mensuales de trabajos, ejecuciones semanales de trabajos) a las que el software debe responder

7 - Aprenda los procedimientos de copia de seguridad / restauración

8 - Entienda el (los) marco (s) utilizado (s) en la construcción de la aplicación

9 - Conozca las modificaciones solicitadas / esperadas / planificadas y el estado de cualquier solicitud de usuario pendiente. Comience a tratar de identificar cómo hacer esos por su cuenta.

10: asegúrese de que sus entornos de prueba y desarrollo sean muy similares.

11: intente identificar las dependencias principales (en otros sistemas o entre componentes) que no se puedan detectar fácilmente.

12 - Identifique y documente las versiones requeridas de cada uso de software y su contacto con el proveedor (si es necesario)

13 - Identifica las herramientas especiales que estaba usando y que no tienes, en caso de que te puedan ayudar.

14 - Obtenga un flujo de sistema de alto nivel. y comienza a construir tu biblioteca de documentación

15 - Comprende cómo administrar la seguridad del usuario para la aplicación

16: obtenga el registro de errores e intente comprender las acciones y cómo afectó la acción a los datos más antiguos (si corresponde)

17: sepa los procesos que demoran demasiado y qué debe vigilar (por ejemplo, tamaños de archivos inusuales, ftp de archivos duplicados, etc.) cuando corresponda.

18 - Verifique el reloj del servidor de producción

19 - Identifique dónde están las configuraciones y compare cada configuración de entorno con la producción para saber qué parámetros son diferentes y por qué

20 - Obtén la información de contacto de este chico

21 - Si el sistema es interno, programe una reunión con los usuarios del sistema (debe saber quiénes son y cuál es el rol que desempeña cada uno) y se los presentarán. Escuche lo que tienen que decir sobre el sistema y sobre sus problemas actuales, si los hay. Asegúrese de estar incluido en los correos electrónicos lo antes posible (después de la aprobación de su gerente)

22: evalúe su comprensión una semana antes de que se vaya e informe de cualquier problema que considere un riesgo

Como mencionó que no tiene una base de datos, esta lista se acortó.

Buena suerte.

    
respondido por el NoChance 11.11.2011 - 22:26
5

Consideraría primero las partes más complicadas y optimizadas para el rendimiento. Le pediría que primero documentara esas partes y se las explicara una por una, luego intentaría escribir pruebas contra esas partes (incluidas las pruebas de rendimiento antes y después, para que pueda ver si una nueva optimización mejora o empeora las cosas). ) y haga que la otra persona revise las pruebas. De esta manera, él documenta y explica, usted usa la explicación para escribir pruebas (mientras está documentando un área diferente), y su revisión lo ayudará a asegurarse de que entiende lo que debe estar haciendo las pruebas. De esa manera, también obtendrá un control de prueba adicional para algunas de las partes más críticas de la aplicación y la documentación de las optimizaciones de rendimiento especializadas.

Si hay tiempo después de cubrirlos, a continuación, pasaré por un proceso similar con las partes de la aplicación que más frecuentemente han sido cambiadas a través de los años, pero que no están en el primer grupo de cosas documentadas.

Luego documenta todo lo que queda.

    
respondido por el HLGEM 07.11.2011 - 21:50
5

Creo que la mejor manera de asimilar un código grande es mediante un enfoque de arriba hacia abajo. Intente comprender el panorama general primero y luego profundice gradualmente en los componentes uno por uno.

Ahora, en cada nivel de excavación, pídale que priorice las partes que necesitan más atención. Pídale que le explique lo más posible, pero siempre documéntelo usted mismo.

Lo mejor de documentarlo usted mismo es que cuando vuelva más tarde, no tendrá ningún problema en recordar el mismo estado cognitivo en el que se encontraba, cuando se lo explicó. Puedes entender más fácilmente lo que escribiste que lo que otra persona hizo. En mi experiencia, dos personas que documentan el mismo fragmento de código no producen fragmentos de texto de aspecto similar.

Esto, supongo que también soluciona tus problemas de "qué y cómo documentar". Cuando él le explica todo, puede decidir qué desea que se documente cuando regrese al código, y documentar solo esas partes.

La idea es primero entender completamente el código (en su presencia), y luego escribir / hacer todo lo que le permita asimilarlo más tarde (en su ausencia).

Al entender por completo el código, quiero decir que necesita tener una idea de la imagen general, y cómo cada componente se relaciona con esta imagen general. Me ha resultado especialmente útil hacer un seguimiento de cómo cada pieza suma el conjunto. No intentes comprender nada de forma aislada, nunca pierdas de vista su contexto.

Por último, una vez que haya hecho lo anterior, tome el control de manera proactiva. Decida usted mismo para qué piezas necesita cobertura de prueba unitaria. qué partes deben ser (o pueden ser) optimizadas, cómo puede refactorizar algún componente, etc. Confíe en que si conoce el sistema, puede tomar todas las decisiones una vez que se haya ido.

    
respondido por el treecoder 08.11.2011 - 07:33
5

Lo siento por ti.

Algunas sugerencias:

  1. Grabe todas las conversaciones que tenga con el programador que se va.
  2. Pregunte por la motivación detrás de los problemas "grandes". Es bueno que entiendas la API, pero busca las decisiones internas: ¿por qué se particionó el código como está? cuáles son las responsabilidades.
  3. Haz un esfuerzo para estudiar realmente el código. Cuando asume tareas de mantenimiento y soporte, a veces hay la presión de "estudiar el código mientras se avanza". Resiste si puedes, y estudia realmente el código.
  4. Busca escenarios. Usted conoce la API - vea cómo se comporta el código. Un ejemplo que viene a la mente es el de un módulo de fax. Como usuario de la API, tiene que preparar previamente una imagen de página y enviar un código al comando para transmitir la página. Pídale al programador saliente que rastree con usted el código para ver cómo se lleva a cabo este escenario. Luego, por supuesto, vaya al escenario de "página de recepción".
  5. 80/20: intente cubrir los escenarios más comunes primero.
  6. Considere una reescritura. Si el código es antiguo y las interfaces están bien definidas, quizás la tecnología haya cambiado lo suficiente como para justificarlo.
  7. Odio decir esto, pero considera buscar un nuevo trabajo.
respondido por el user18254 12.11.2011 - 19:50
3

Si desea una documentación decente, compre una copia de Pascal Analyzer (PAL) . Lo he usado en los proyectos de Delphi y fue excelente: ahora pueden haber dividido la funcionalidad de documentación en un producto con el que no estoy familiarizado (Pascal Browser), por lo que es posible que tenga que comprar ambos (< 300 USD), pero PAL fue una excelente herramienta para comprender dónde se estaban utilizando las variables desde donde se llamaban las funciones desde etc & recogiendo todo tipo de posibles problemas con el código.

Utilice PAL para tener una idea de cómo está estructurado el código y, probablemente, una lista de aproximadamente 1000 mejoras sugeridas si mi experiencia fuera algo sobre lo que continuar. Trabajar en la lista mejorará la calidad del código, lo simplificará enormemente & Haz tu vida más fácil para el futuro. Delphi es compatible con la refactorización en versiones recientes (los últimos 5 años aproximadamente). Necesitabas incluir todo en el archivo dpr para que realmente funcione correctamente cuando lo estaba haciendo, así que tenlo en cuenta.

Si desea pruebas de unidad, descargue DUnit & Comience a crear algunas pruebas con el codificador original. Probablemente sea una forma constructiva de usar al menos parte de su tiempo.

    
respondido por el mcottle 10.11.2011 - 09:33
2

Aunque no ha mencionado sobre una base de datos de back-end, pero suponiendo que haya una debería

  1. Obtenga el modelo de datos documentado especialmente las columnas y PK-FK
  2. Configure una traza de sql y registre todas las consultas que se activan mientras usa la aplicación. El orden de ejecución de las consultas le dará una buena idea sobre el flujo de la aplicación y también ayudará en la depuración.
respondido por el NRS 10.11.2011 - 19:13
2

Estoy en la misma situación en que nuestro Arquitecto se mudó a Australia y dejó mucho legado como lo fue en la compañía de los últimos 8 años. Él mismo heredó las cosas heredadas de un arquitecto anterior que era un contratista.

Usted y otros ya han mencionado buenos puntos, pero aquí hay problemas que enfrentamos después de que se fue Puede ser que puedas prepararte mejor ...

1) (Persona técnica) Detalles de contacto de los clientes con los que está tratando.

2) Su cuenta con la que compró licencias de software, claves que deben renovarse cada año y procesos / costos para renovarlas.

3) Documento de configuración de bibliotecas / componentes y productos de software de terceros que se integran con sus productos. Luchamos durante 4 días para recuperar una máquina que se perdió debido a que la TI eliminó espacio y se les pasó alguna instrucción incorrecta.

4) Documentos / pasos que se utiliza para depositar el código fuente a las compañías de depósito de software, por ejemplo, el fideicomiso.

5) Todavía hay una larga lista, pero es posible que no sea aplicable a usted. Ninguna cantidad de documentación puede reemplazar a una persona real, así que mantenga sus detalles a la mano, permanezca en buenos términos y buena suerte :)

Tampoco sé si esta es la primera vez para ti. Para mí, he trabajado con 5/6 empleadores y siempre he heredado el código con documentación errónea o sin documentación. Así que, junto con toda la documentación, manténganse positivos :)

    
respondido por el Surjit Samra 12.11.2011 - 12:37

Lea otras preguntas en las etiquetas