¿Cómo puedo refactorizar una base de código mientras otros se comprometen rápidamente?

18

Estoy en un proyecto privado que eventualmente se convertirá en código abierto. Tenemos algunos miembros del equipo, lo suficientemente talentosos con las tecnologías para crear aplicaciones, pero no desarrolladores dedicados que puedan escribir código limpio / hermoso y, lo que es más importante, a largo plazo.

Me propuse refactorizar la base del código, pero es un poco difícil de manejar ya que alguien en el equipo en otro país con el que no estoy en contacto regular podría actualizar esta cosa totalmente separada.

Sé que una solución es comunicarse rápidamente o adoptar mejores prácticas de PM, pero todavía no somos tan grandes. Solo quiero limpiar el código y fusionarme con lo que ha actualizado. ¿Usar una sucursal sería un plan adecuado? ¿La mejor combinación de esfuerzos? ¿Algo más?

Incógnito
fuente

Respuestas:

35

Una cosa que la gente a menudo no tiene en cuenta es que una arquitectura limpia no solo acelera el mantenimiento a largo plazo, sino que también acelera el desarrollo en este momento . No intente aislar sus cambios de sus colegas hasta que estén "listos". Sus cambios los ayudarán a ser más productivos y menos propensos a errores.

El error más frecuente que cometen las personas al emprender un gran refactor es no fusionarse con la frecuencia suficiente, en lugar de intentar hacerlo de una "gran explosión". La forma correcta de hacerlo es hacer el refactorizador más pequeño posible, probarlo, luego fusionarlo en la rama de su colega y enseñarle sobre el cambio para que pueda incorporarlo en el futuro. Idealmente, está haciendo una fusión por día, o una por semana como mínimo.

Karl Bielefeldt
fuente
17
Si si si. Resista la tentación de ir a un tour de fuerza en solitario de un mes solo para descubrir que la base de código que se supone que debe refactorizar ha cambiado por completo y que debe comenzar de nuevo. Mejor hacerlo paso a paso.
tdammers
¡Exactamente correcto! Las grandes refactorizaciones no van a ninguna parte (ver Netscape 6 , o la Pirámide del Proyecto )
Andomar
8

Nunca "no eres lo suficientemente grande como para comunicarte". Si sus dedos pueden escribir, sus labios también pueden hablar. Al final del día, la mejora tecnológica es 85% de comunicación y 15% técnica. El hecho de que prefiera sentarse allí codificando que tener conversaciones difíciles con alguien ... no significa que sea una buena idea. La comunicación es en realidad la parte difícil de lo que estás tratando de hacer, pero no solo la evites.

Michael Durrant
fuente
No es realmente la dificultad de comunicarse, es que no quiero que el desarrollador actual se ralentice. En realidad, ni siquiera estoy seguro de que necesite aprender de la manera correcta siempre que pueda ser refactorizado. No es un programador primero, es un científico en otro campo.
Incognito
+1. No puede compartir una base de código con alguien sin comunicarse
MarkJ
4

Sí, una sucursal es una buena solución para esto.

HEADMientras tanto, le sugiero que comience a trabajar en esto en una rama y se asegure de que se aplique limpiamente sobre su actual (es decir, haga rebases y fusiones de prueba a intervalos regulares para asegurarse de que puede aplicar sus cambios fácilmente y que sus pruebas aún pasen) - También busquegit rerere ayuda gitcon esto). Luego, una vez que haya terminado de rebase y combinar los cambios en su HEAD.

Cuanto antes comience a trabajar en esto, mejor ya que cambiar la arquitectura se vuelve más y más trabajo cuanto más frío se vuelve el código. Además, puede haber muchos casos de código codificado a mano dispersos en toda la base de código donde, por ejemplo, su nueva y brillante función de ayuda podría haber hecho las cosas mucho más simples.

Benjamin Bannier
fuente
1
-1: No. Ver la respuesta de @Karl Bielefeldt.
Jim G.
¿Si? No estoy en desacuerdo con Karl, por eso decidí comenzar rápido.
Benjamin Bannier
Y digo: "No ramifique y luego vuelva a fusionar". En el mejor de los casos, es un esfuerzo perdido. En el peor de los casos, harás un gran desastre.
Jim G.
3

¿Has considerado la opción "No lo hagas todavía"?

Si bien hacer este trabajo en una rama separada es probablemente el mejor enfoque, te estás preparando para una fusión masiva y dolorosa en el futuro.

Presumiblemente, los otros muchachos están agregando muchas funciones nuevas, cambiando las funciones existentes y posiblemente eliminando algunas funciones.

Una vez que el desarrollador principal funcionó se ha ralentizado un poco en algún momento en el futuro, entonces podría estar en una posición mucho más fácil de refactorizar.

ozz
fuente
+1. Si su base de código está en flujo masivo, probablemente no sea el mejor momento para intentar una gran reescritura. Elija un momento en su ciclo de desarrollo cuando las cosas estén más tranquilas.
anon
2

tl; dr - Parece que es hora de pasar a las grandes ligas. Poner lápiz labial en un cerdo no lo hace más bonito, a menos que te guste ese tipo de cosas ...

El problema de las personas

El primer problema es la sincronización de confirmación. SI tiene varias personas trabajando en el mismo código al mismo tiempo, solo necesita una regla para evitar problemas:

Rule 1: Always pull before you merge/rebase

Cuando se trata de DVCS, es difícil hacer cambios en una rama remota (es decir, el repositorio principal) y es muy fácil hacer cambios en el local. Cada persona es responsable de hacer que sus propias adiciones de código encajen en el todo sin problemas. A menos que 2 personas se comprometan al mismo tiempo, no deberías experimentar. El acceso de compromiso al origen / maestro remoto debe limitarse a solo unos pocos desarrolladores y deben extraer los cambios de los otros desarrolladores a través de ramas de seguimiento remoto.

El problema del código

¿Cómo sabes que los cambios que haces no rompen el código?

Respuesta simple ... Escribe pruebas para demostrar que no. Si ignora la escuela de pensamiento TDD (Test Driven Design), el objetivo de las pruebas es agregar un nivel de verificación que le permita cambiar el código sin romperlo.

Rule 2: Don't make assumptions, write proofs (ie tests).

Además de esto, se debe ejecutar toda la gama de pruebas antes de pasar al origen / maestro remoto.

Mantenga sus compromisos tan pequeños y concisos como sea posible. De esa manera, si necesita retroceder un cambio que rompió algo más adelante, evitará tener que volver a implementar las partes que no rompieron el código.

Es posible que primero necesite una reestructuración organizacional

Si las soluciones anteriores no se pueden aplicar fácilmente, probablemente haya algunos problemas con la estructura de desarrollo que deben abordarse primero.

El propietario del proyecto debe ser el guardián. Si hay problemas de sincronización de confirmación, probablemente haya demasiadas personas con acceso de confirmación. Incluso en proyectos masivos como el kernel de Linux, solo un puñado de desarrolladores tiene acceso de acceso al repositorio maestro de origen / remoto. En realidad, existen múltiples niveles de repositorios para administrar las confirmaciones. En lugar de un modelo de confirmación de una sola capa donde todos están empujando sus cambios al origen, el modelo jerárquico tiene guardianes que realizan cambios y verifican su calidad antes de incluirlos en el proyecto. El modelo de confirmación jerárquica puede escalar mucho más grande y más eficaz que el modelo de una sola capa sin sacrificar la calidad.

Para los desarrolladores que no consiga acceso de envío, deben aprender a crear su propia ramas de seguimiento remoto (GIT y gitorious son buenos para esto) para que los desarrolladores que hacen hayan acceso de confirmación puede tirar fácilmente / integrar ramas en el origen. Si los cambios son pequeños, los parches funcionarán igual de bien.

La capacidad de realizar cambios antes de hacer una fusión / rebase supone que no está desarrollando en su rama maestra local. La forma más fácil de manejar esto es hacer una extracción inicial antes de comenzar a codificar, luego hacer todo su trabajo en esa rama. La forma difícil es bifurcarlo justo antes de fusionarlo y deshacer el master.

Defina el estilo de codificación para el proyecto en general y haga que los desarrolladores lo sigan. Los desarrolladores contribuyentes deben escribir código que se ajuste a los estándares / normas del proyecto para minimizar la limpieza. El estilo de codificación puede ser una gran barrera para el ego en un proyecto abierto. Si no se establece un estándar, todos codificarán en su propio estilo preferido y la base de código se volverá muy fea muy rápido.

El mito del "Mes del hombre mítico"

Lo creas o no, los proyectos de código abierto más grandes / más exitosos no se ejecutan como una democracia. Se ejecutan como una jerarquía. Afirmar que un proyecto no puede crecer efectivamente más allá de 8-10 desarrolladores es ingenuo. Si eso fuera cierto, entonces no existirían megaproyectos como el Kernel de Linux. El problema más profundo es que otorgar acceso de compromiso a todos simplemente hace que la comunicación efectiva sea demasiado difícil de manejar.

El problema del mes mítico del hombre puede ser superado. Solo necesita ejecutar su proyecto como los militares. Hay muchos niveles dentro de la jerarquía porque es de conocimiento común que las personas individuales solo son realmente efectivas en la gestión de las comunicaciones con un puñado de personas. Mientras ningún individuo sea responsable de administrar el trabajo de más de 5-7 personas, el sistema puede escalar indefinidamente.

Puede limitar a los desarrolladores mejor / experimentados a hacer más integración y diseño / planificación de alto nivel, pero eso no es algo malo. Parte de la ampliación es hacer el movimiento para decidir que el proyecto necesita un plan a largo plazo. Las personas en los niveles más altos que tienen la mayor inversión (el tiempo también es un recurso) en el futuro del proyecto deben ser las encargadas de tomar las grandes decisiones.

Es bueno escuchar sobre un proyecto de código abierto que atraviesa dificultades de crecimiento. Felicidades y buena suerte.

Evan Plaice
fuente
-1

código mantenible limpio / hermoso y lo más importante a largo plazo.

En mi experiencia, limpio / hermoso es el enemigo de mantenible. Hermoso código a menudo:

  • Tiene una capa en el marco que introduce un mayor nivel de abstracción.
  • Optimiza la reutilización del código, lo que resulta en muchas dependencias
  • Intenta resolver el problema genérico en lugar del específico

Por otro lado, código mantenible:

  • Está escrito directamente en el marco, por lo que todos los desarrolladores pueden leerlo
  • Optimiza para un bajo número de dependencias, por lo que un cambio en un área no afecta a otra
  • No trata de resolver más problemas de los que tiene que resolver.
Andomar
fuente
La descripción de su hermoso código puede ir de la mano con un código que se pueda mantener también porque cuando introduce un mayor nivel de abstracción y optimiza su código para su reutilización, eso es lo que es más fácil de mantener de todos modos.
Karthik Sreenivasan
Excepto que la abstracción no resistirá la prueba del tiempo. Y cualquier problema con la abstracción convierte una solución local en una solución que potencialmente tiene un impacto en toda la aplicación.
Andomar