¿Qué herramientas y técnicas utiliza para explorar y aprender una base de código desconocida?
Estoy pensando en herramientas como grep
, ctags
pruebas unitarias, pruebas funcionales, generadores de diagramas de clases, gráficos de llamadas, métricas de códigos sloccount
, etc. Me interesarían sus experiencias, los ayudantes que utilizó o escribió usted mismo y el tamaño de la base de código con la que trabajó.
Me doy cuenta de que conocer una base de código es un proceso que ocurre con el tiempo, y la familiaridad puede significar cualquier cosa, desde "Puedo resumir el código" hasta "Puedo refactorizarlo y reducirlo al 30% del tamaño". Pero, ¿cómo comenzar?
source-code
maintenance
miku
fuente
fuente
Respuestas:
lo que siempre he hecho es lo siguiente:
Abra varias copias de mi editor (Visual Studio / Eclipse / Whatever) y luego depure y realice saltos de línea a través del código. Descubra el flujo del código, apile el rastreo para ver dónde están los puntos clave y avance desde allí.
Puedo ver método tras método, pero es bueno si puedo hacer clic en algo y luego ver en qué parte del código se ejecuta y seguir. Permítanme tener una idea de cómo el desarrollador quería que las cosas funcionaran.
fuente
¿Cómo se come un elefante?
Un bocado a la vez :)
En serio, primero trato de hablar con los autores del código.
fuente
En gran medida, sí (lo siento).
Enfoques que puede considerar:
Algunas de las cosas que hago para aclarar el código son:
... y cualquier otra mejora simple que puedas hacer.
Poco a poco, el significado detrás de todo esto debería ser más claro.
¿En cuanto al lugar para comenzar? Comienza con lo que sabes. Sugiero entradas y salidas. A menudo puede obtener una idea de lo que se supone que son y para qué se utilizan. Siga los datos a través de la aplicación y vea a dónde van y cómo se cambian.
Uno de los problemas que tengo con todo esto es la motivación, puede ser un verdadero trabajo. Me ayuda a pensar en todo el negocio como un rompecabezas y a celebrar el progreso que estoy haciendo, por pequeño que sea.
fuente
Tu situación es realmente común. Cualquiera que tenga que ingresar a un nuevo trabajo donde haya un código existente para trabajar, tendrá que lidiar con algún elemento del mismo. Si el sistema es un sistema heredado realmente desagradable, entonces es muy parecido a lo que has descrito. Por supuesto, nunca hay documentación actual.
Primero, muchos han recomendado trabajar eficazmente con código heredado por Michael Feathers. Este es de hecho un buen libro, con capítulos útiles como "No puedo incluir esta clase en un arnés de prueba" o "Mi aplicación no tiene estructura", aunque a veces Feathers solo puede ofrecer más simpatía que solución. En particular, el libro y sus ejemplos están orientados principalmente a los lenguajes de llaves. Si está trabajando con procedimientos SQL retorcidos, puede que no sea tan útil. Creo que el capítulo, "No entiendo este código lo suficientemente bien como para cambiarlo", aborda su problema. Plumas menciona aquí las cosas obvias como tomar notas y marcar listados, pero también hace un buen punto de que puede eliminar el código no utilizado si tiene control de fuente. Mucha gente deja secciones de código comentadas en su lugar,
A continuación, creo que su enfoque sugerido es ciertamente un buen paso. Primero debe comprender a alto nivel cuál es el propósito del código.
Definitivamente trabaje con un mentor o alguien en el equipo si tiene que responder preguntas.
Además, aproveche la oportunidad para admitir el código si se revelan defectos (aunque a veces no tiene que ser voluntario para esto ... ¡el defecto lo encontrará!). Los usuarios pueden explicar para qué usan el software y cómo les afecta el defecto. Eso a menudo puede ser un conocimiento muy útil cuando se trata de comprender el significado del software. Además, entrar en el código con un objetivo específico para atacar a veces puede ayudar a enfocarte cuando te enfrentas a "la bestia".
fuente
Me gusta hacer lo siguiente cuando tengo un archivo fuente muy grande:
Te sorprendería lo extrañamente familiar que se ve el código cuando vuelves a tu editor normal.
fuente
Toma tiempo
No se sienta demasiado apurado al intentar comprender una base de código heredada, especialmente si está utilizando tecnologías / idiomas / marcos con los que no está familiarizado. Es solo una curva de aprendizaje inevitable que lleva algo de tiempo.
Un enfoque es ir y venir entre el código y los tutoriales sobre las tecnologías relacionadas. Usted lee / mira el tutorial, luego ve el código para ver cómo lo hicieron sus predecesores, observando cualquier similitud y diferencia, tomando notas y haciendo preguntas a los desarrolladores existentes.
"¿Por qué hiciste esta parte de esta manera"
"Noté que la mayoría de las personas en línea lo hacen de esta manera, y todos lo hicieron de otra manera. ¿Por qué es esto?"
"¿Qué los hizo elegir la tecnología X sobre la tecnología Y?"
Las respuestas a estas preguntas lo ayudarán a comprender la historia del proyecto y el razonamiento detrás de las decisiones de diseño e implementación.
Eventualmente, te sentirás lo suficientemente familiarizado como para comenzar a agregar / arreglar cosas. Si todo parece confuso o parece que está sucediendo demasiada "magia", no ha pasado suficiente tiempo revisándolo, digiriéndolo y diagramandolo. Crear diagramas (diagramas de secuencia, diagramas de flujo de procesos, etc.) es una excelente manera de comprender un proceso complejo, además de que ayudarán al "próximo tipo".
fuente
cscope puede hacer lo que ctags puede hacer para C, además, también puede enumerar dónde se llama a todas las funciones actuales. Además es muy rápido. Se escala fácilmente a millones de LOC. Se integra perfectamente a emacs y vim.
Contador de código C y C ++: cccc puede generar métricas de código en formato html. También he usado wc para obtener LOC.
doxygen puede generar sintaxis resaltada y código de referencia cruzada en html. Útil para navegar por la base de código grande.
fuente
La forma en que lo recomiendo con Drupal y no es realmente específico de Drupal: comience con el rastreador de problemas. Habrá informes de errores antiguos y no cerrados con seguridad. ¿Puedes reproducirlos? En caso afirmativo, actualice el ticket para confirmarlo. Si no, ciérrelo. Encontrará de esta manera un montón de formas de usar el software y puede comenzar a mirar en la base de código donde se bloquea. O puede comenzar a recorrer el código y ver cómo llega a donde se bloquea. De esta manera, no solo comenzará a comprender la base de código, sino que también acumulará una tonelada de karma y sus preguntas serán bienvenidas por la comunidad.
fuente
Una cosa importante que debe hacer es usar herramientas para generar gráficos de dependencia para explorar de arriba a abajo la arquitectura del código. Primero visualice el gráfico entre ensamblajes o frascos .NET, esto le dará una idea de cómo se organizan las características y capas, luego profundice en las dependencias de espacios de nombres (dentro de uno o algunos ensamblajes o frascos .NET relacionados) para tener una idea más precisa del código estructura y, finalmente, puede ver las dependencias de las clases para comprender cómo colabora un conjunto de clases para implementar una característica. Existen varias herramientas para generar un gráfico de dependencia, como NDepend para .NET, por ejemplo, que generó el siguiente gráfico.
fuente
Una vez tuve un ingeniero de software bastante fantástico que me dijo que la forma más cara de análisis de código y mantenimiento era recorrer el código, línea por línea; por supuesto, somos programadores, y eso viene más o menos con el trabajo. El medio feliz, creo, es (en este orden): 1. Obtener un cuaderno para crear notas sobre cómo entiende que funciona el código y agregarlo a medida que pasa el tiempo 2. Consulte la documentación sobre el código 3. Hable con autores u otras personas que hayan apoyado la base del código. Pídales un "volcado de cerebro" 4. Si está al punto de comprender algunas de las relaciones de clase de nivel de detalle, realice una depuración paso a paso del código para hacer una síntesis entre cómo pensó que funciona el código y cómo funciona realmente el código.
fuente
Primero entienda lo que debe estar haciendo, sin eso es probable que sea un galimatías. Habla con los usuarios, lee el manual, lo que sea.
Luego presione ejecutar y comience a caminar el código para lo que parecen ser las funciones clave.
fuente
Divide y conquistaras. Miro cada funcionalidad y el código asociado, paso por ellas y paso a la siguiente, construyendo lentamente una imagen del conjunto.
Si el proyecto tenía pruebas unitarias, también me gusta pasar por ellas, siempre son muy reveladoras e ilustrativas.
fuente
Vea a Michael Feathers trabajando eficazmente con el código heredado
fuente
Aquí está mi lista corta:
Si es posible, haga que alguien brinde una vista de alto nivel del código. ¿Qué patrones se consideraron, qué tipo de convenciones podría esperar ver? preguntar mientras trabajo a través de la cebolla del proyecto preexistente.
Ejecute el código y vea cómo se ven los sistemas. Es cierto que puede tener más de unos pocos errores, pero esto puede ser útil para tener una idea de lo que hace. No se trata de cambiar el código, sino de ver cómo funciona esto. ¿Cómo encajan varias piezas para ser un sistema en general?
Busque pruebas y otros indicadores de documentación básica que puedan ayudar a construir un modelo mental interno del código. Aquí es donde probablemente sugeriría al menos unos días, a menos que haya muy poca documentación y pruebas, por supuesto.
¿Qué tan bien conozco los idiomas y los marcos utilizados en este proyecto? La importancia aquí es la diferencia entre mirar algunas cosas y decir: "Sí, lo he visto una docena de veces antes y lo sé bastante bien", y "¿Qué demonios se está intentando aquí? ¿Quién pensó que era una buena idea?" tipo de preguntas que, si bien no las diría en voz alta, las pensaría especialmente si estoy mirando un código heredado que puede ser bastante frágil y las personas que lo escribieron no están disponibles o simplemente no recuerdan por qué las cosas se hicieron como estaban. Para áreas nuevas, puede valer la pena dedicar un tiempo extra a conocer cuál es la estructura y qué patrones puedo encontrar en este código.
Por último, pero no menos importante: conozca las expectativas de quienes ejecutan el proyecto en términos de lo que se supone que debe hacer en cada momento, dadas las siguientes ideas de lo que se puede esperar:
fuente
Siempre trato de comenzar con el punto de entrada al programa, ya que todos los programas tienen uno (por ejemplo, método principal, clase principal, init, etc.). Esto me indicará qué comienza y, a veces, cómo se relacionan las cosas.
Después de eso, profundizo. La base de datos y DAO están configurados en algún lugar, por lo que tengo una idea de cómo se almacenan las cosas. Quizás también se inicie algún tipo de clase de instancia global, y allí pueda averiguar qué se está almacenando. Y con buenas herramientas de refractorización, puedo averiguar quién llama qué.
Luego trato de encontrar dónde se configura y maneja la interfaz, ya que este es el siguiente punto de entrada de información. Las herramientas de refractorización, búsqueda y depuración ayudan en mi búsqueda. Luego puedo averiguar dónde comienza y termina el manejo de la información, abriéndome camino a través de todos los archivos de clase.
Luego trato de escribir el flujo en un papel, solo para comprender inicialmente las cosas. El botón de enviar pasa a la verificación genérica que luego se pasa al DAO o la base de datos y luego se almacena en la base de datos. Esta es una simplificación excesiva de la mayoría de las aplicaciones, pero es la idea general. El lápiz y el papel son extremadamente útiles aquí, ya que puede anotar todo rápidamente y no tener que preocuparse por formatear en un programa que supuestamente lo ayudaría.
fuente
Diría que comenzar con la documentación, etc., pero en mi experiencia, la profundidad de la documentación y el conocimiento local a menudo es inversamente proporcional a la edad, el tamaño y la complejidad de un sistema.
Dicho esto, generalmente trato de identificar un par de hilos funcionales. Por funcional me refiero a cosas como iniciar sesión, desplegar una lista de clientes, etc. Si los patrones son consistentes, un hilo debería darle una sección transversal agradable, no necesariamente completa, del sistema. La mejor manera de determinar si los patrones son consistentes es analizar un puñado de hilos.
Creo que no hace falta decirlo, pero, en mi opinión, es mejor entender el sistema desde una perspectiva funcional que desde una perspectiva técnica. En general, no me preocupo demasiado por las herramientas que se están utilizando (ORM, bibliotecas de registro, etc.) y me concentro más en los patrones (MVP, etc.) que se están utilizando. En mi experiencia, las herramientas son generalmente más fluidas que los patrones.
fuente
Hice mucho ...
Aquí está mi enfoque actual para situaciones en las que hay "algo funcionando", y debe hacerlo "funcionar de alguna otra manera".
Otra tarea opcional adicional que puede requerir entre cada paso: f fuera del administrador (propietario del proyecto) que le dice que "estos cambios ya deberían hacerse ayer". Después de algunos proyectos, incluso puede comenzar a ayudar a obtener especificaciones y documentos por adelantado.
Pero generalmente (especialmente para los scripts) simplemente no es posible en el ámbito empresarial (el costo será demasiado alto, mientras que el valor será bajo). Una opción es no hacer ningún cambio, hasta que se alcance la masa crítica, y el sistema deje de producirse (por ejemplo, vendrá un nuevo sistema) o la gerencia decidió que vale la pena hacer todo esto.
PD: recuerdo un código que se utilizó para 5 clientes con diferentes configuraciones. Y cada cambio (nueva función) se requería pensando en "qué partes se usan" y "qué configuración tienen los clientes" para no frenar nada y no copiar el código. Poner su configuración para proyectar cvs, y escribir especificaciones, reduce este tiempo de reflexión casi a 0.
fuente
Imprima el código fuente y comience a leerlo. Si es especialmente grande, solo imprima porciones selectas para comprenderlo mejor y tome todas las notas / comentarios que necesite.
Rastree a través del programa desde el comienzo de su ejecución. Si está asignado a una parte particular de la base de código, rastree la ejecución dentro de esa parte y descubra qué estructuras de datos se utilizan.
Si está utilizando un lenguaje orientado a objetos, intente hacer un diagrama de clase general. Esto le dará una buena visión general de alto nivel.
Desafortunadamente, al final, tendrás que leer la mayor cantidad de código posible. Si tiene suerte, los programadores anteriores han escrito la mayor cantidad de documentación posible para ayudarlo a comprender lo que está sucediendo.
fuente
Lo primero que debe hacer al aprender una nueva base de código es aprender sobre lo que se supone que debe hacer, cómo se usa y cómo usarlo. Luego comience a mirar la documentación arquitectónica para aprender cómo se presenta el código, también vea cómo funciona la base de datos en este punto. Al mismo tiempo que aprende la arquitectura, es un buen momento para revisar los flujos de procesos o los documentos de casos de uso. luego comience a sumergirse y leer el código después de comprender el panorama general, pero solo el código relacionado con cualquier trabajo que pueda estar haciendo en este código, no solo intente leer todo el código. Es más importante saber dónde está el código para hacer X que exactamente cómo se hace X, el código siempre está ahí para decirle cómo puede encontrarlo.
Me parece que tratar de saltar y leer el código sin un objetivo más allá de aprender el código generalmente no es productivo, intentar hacer pequeños cambios usted mismo o revisar el código de los cambios de otra persona es un uso mucho más productivo de su tiempo.
fuente
Si una base de código es grande, centre su atención en las partes en las que está trabajando actualmente. De lo contrario, se sentirá abrumado y posiblemente su cabeza explote. Creo que una descripción general de alto nivel es útil (si está disponible), pero es probable que pase mucho tiempo en el depurador para seguir el flujo del programa. Es una buena idea obtener una visión general de la aplicación y verla utilizada, para que pueda comprender cómo / para qué / por qué se está utilizando el código.
Por lo general, ejecuto algún tipo de herramienta de complejidad de código en el código para decirme dónde están las áreas problemáticas. Las áreas con puntajes altos son probablemente muy difíciles de actualizar. Por ejemplo, me encontré con una función que obtuvo 450 en la escala ciclomática. Efectivamente, cientos de FI. Muy difícil de mantener o cambiar eso. Así que prepárate para lo peor.
Además, no tenga miedo de hacer preguntas a los desarrolladores existentes, especialmente si trabajaron en el sistema. Mantén tus pensamientos internos para ti y concéntrate en resolver los problemas. Evite los comentarios que puedan hacer que los otros desarrolladores se enojen. Después de todo, puede ser su bebé y a nadie le gusta que le digan que su bebé es feo.
Tome pequeños pasos, incluso el cambio de código más pequeño puede tener un gran impacto.
Creo que es útil crear flujos de código de programa, por lo que si estoy haciendo cambios, puedo hacer búsquedas de dependencia para ver qué métodos / funciones llaman a qué. Supongamos que estoy cambiando el método C.
Si solo 1 método / función llama a C, entonces es un cambio bastante seguro. Si cientos de métodos / funciones llaman a C, entonces sería de mayor impacto.
Esperemos que su código base esté bien diseñado, escrito y mantenido. Si es así, tomará algún tiempo entenderlo, pero eventualmente cambiará la situación.
Si es una gran bola de lodo, es posible que nunca comprenda (o desee comprender) su funcionamiento interno.
fuente
Algunas cosas que hago ...
1) Use una herramienta de análisis de origen como Source Monitor para determinar los diversos tamaños de módulos, métricas de complejidad, etc. para tener una idea del proyecto y ayudar a identificar las áreas que no son triviales.
2) Explore el código de arriba a abajo en Eclipse (es bueno tener un editor que pueda buscar referencias, etc.) hasta que sepa qué está pasando y en qué parte de la base del código.
3) Ocasionalmente, dibujo diagramas en Visio para obtener una mejor imagen de la arquitectura. Esto también puede ser útil para otros en el proyecto.
fuente
Esto pasa mucho. Hasta que comencé a trabajar en una plataforma de código abierto, creo que nunca comencé un trabajo que no comenzó con una admisión de que el código tenía algunas 'peculiaridades'.
Puede recorrer un largo camino con un depurador de pasos y mucha tenacidad. Desafortunadamente, a menudo lleva tiempo y experiencia aprender una gran bola de lodo en particular e incluso después de años todavía puede haber algún subsistema que surja del que nadie tenga conocimiento.
fuente
Te animo a que escribas pruebas unitarias antes de cambiar cualquier cosa en la bola de lodo. Y solo cambie suficiente código en el momento para que las pruebas pasen. A medida que refactoriza, agregue pruebas unitarias de antemano para saber que la funcionalidad empresarial no se ha visto afectada por la refactorización.
¿La programación de pares es una opción? Tener a otra persona para intercambiar ideas es una gran idea para lidiar con esa cantidad de desagradable.
fuente
Aquí hay un procedimiento que usamos para eliminar duplicados.
[dupe]
justo después del marcador de comentario;[dupe][procedure_arbitrary_name]
antes del procedimiento duplicado;[dupe][procedure_arbitrary_name][n]
;grep
feliz!fuente
Creo que una de las cosas más importantes es tomar una función simple, elegir la más simple que se pueda imaginar e implementarla. Si hay una lista de deseos mantenida, úsela o hable con alguien familiarizado con la base del código y pídales que sugieran una función. Por lo general, esperaría que esto sea un cambio con 5 ~ 20 LOC. El punto importante no es que esté agregando una característica muy elegante, sino que está trabajando (o más bien lidiando :)) con la base del código y está pasando por todo el flujo de trabajo. Usted tendría que
La lista continúa, pero el punto es que un mini proyecto como este lo lleva a través de todos los elementos de su lista de verificación para familiarizarse con un sistema y también resulta en un cambio productivo.
fuente
Una pequeña cosa que quería agregar:
Una herramienta que comencé a usar recientemente para este tipo de problema que me ha ayudado enormemente es el mapeo mental. En lugar de tratar de incluir todos los detalles de cómo se implementa algo en mi cabeza, construiré un mapa mental que describa cómo funciona el sistema por el que estoy pasando. Realmente me ayuda a comprender más profundamente lo que está sucediendo y lo que aún necesito resolver. También me ayuda a realizar un seguimiento de lo que necesito cambiar a una escala muy precisa.
Recomiendo usar el avión libre entre la gran cantidad de opciones de mapas mentales.
fuente
No habrá ninguna documentación o habrá poca documentación, o estará desactualizada. Encuentra toda la documentación que existe. Si está en un repositorio de equipo, no haga una copia. De lo contrario, póngalo allí y pídale permiso a su gerente para organizarlo, tal vez con cierta supervisión.
Sube todo al repositorio para el equipo y agrega un Glosario. Todas las bases tienen jerga; documentarlo en el glosario. Haga secciones para herramientas, productos, específicos del cliente, etc.
Crear / actualizar un documento de creación de entorno de software. Todas las herramientas, peculiaridades, opciones de instalación, etc., vaya aquí.
Luego cargue un documento de Introducción a "ProductName" o similar. Que sea solo el flujo mental y la autoorganización con el tiempo. Luego revise los documentos desactualizados y vuelva a actualizarlos. Los otros desarrolladores lo apreciarán, contribuirás de una manera única mientras aprendes el código. Especialmente documente todas esas cosas que le confunden o que tienen un nombre incorrecto o son contraintuitivas.
Una vez que su curva inclinada esté llegando a su fin, no se preocupe por actualizar la documentación. Deja que el nuevo chico nuevo haga eso. Cuando llegue, muéstrale tu trabajo. Cuando continuamente te molesta por respuestas, no le contestes. Más bien, agregue la pregunta a su documentación y luego entréguele la url. Caña de pescar.
Un efecto secundario es que habrá creado una herramienta que usted mismo puede consultar en los próximos meses cuando se olvide.
Y aunque no se trata de documentación, un problema relacionado son los pequeños procedimientos extravagantes e intensivos manualmente que realizan sus compañeros de equipo. Automatícelos con lotes, scripts SQL y similares, y compártalos también. Después de todo, el conocimiento procesal es posiblemente tan grande como el conocimiento declarativo en términos de ser productivo en un nuevo entorno. Sea lo que sea, no lo hagas; más bien, escríbelo y ejecuta el script. La caña de pescar golpea de nuevo.
fuente
Escribí una publicación bastante larga sobre este tema. Aquí hay un extracto
Pensé en este problema durante bastante tiempo. Decidí escribir mi propia solución personal como un proceso general. Los pasos que he documentado son los siguientes:
Este proceso está escrito en el contexto de una aplicación de escritorio grande, pero las técnicas generales siguen siendo aplicables a aplicaciones web y módulos más pequeños.
tomado de: Un proceso para aprender una nueva base de código
fuente
Hay algunos pequeños consejos que puedo compartir.
Para un producto existente, empiezo a probarlo intensamente. Si selecciona / se le asigna una tarea, me enfocaré más en la característica particular.
El siguiente paso sería encontrar el código donde pueda entrar y comenzar a explorar En el camino encontraré los módulos dependientes, bibliotecas, marcos, etc.
El siguiente paso sería crear un diagrama de clase simple con sus responsabilidades (como las tarjetas CRC)
Comience a realizar cambios menores o elimine errores menores para corregirlos y confirmarlos. Para que podamos aprender el flujo de trabajo del proyecto; No solo el código. A menudo, los productos grandes tendrán algún tipo de contabilidad en aras de la autorización y las auditorías (por ejemplo, proyectos de atención médica)
Hable con las personas que ya están trabajando en el proyecto. Exprese sus ideas, pensamientos y, a cambio, obtenga su experiencia y puntos de vista sobre cómo trabajar con este proyecto durante mucho tiempo. Esto es bastante importante porque también te ayuda a llevarte bien con el equipo.
fuente
Ha pasado mucho tiempo desde que tuve que sumergirme en una gran base de código. Pero en los últimos años intenté muchas veces incorporar nuevos desarrolladores a equipos en los que teníamos una base de código existente, bastante grande.
Y el método que hemos utilizado con éxito, y diría que es la forma más efectiva, sin lugar a dudas, en mi humilde opinión, es la programación de pares.
En los últimos 12 meses, hemos tenido 4 nuevos miembros para el equipo, y cada vez, el nuevo miembro se emparejaría con otro miembro bien familiarizado con la base del código. Al principio, el miembro mayor del equipo tendría el teclado. Después de aproximadamente 30 minutos, pasaríamos el teclado al nuevo miembro, que trabajaría bajo la guía del miembro más antiguo del equipo.
Este proceso ha demostrado ser bastante exitoso.
fuente