¿Cómo gestionar los cambios en el marco?

Trataré de ser conciso para no convertir esto en una entrada de blog. Si hay preguntas específicas, hágamelo saber y haré todo lo posible para responderlas.

Básicamente, estoy interesado en las metodologías que se le han ocurrido a las personas y qué beneficios y deficiencias experimentaron para administrar la transición de un proyecto de un marco (o un lenguaje de programación o una pila de tecnología) a otro.

La puesta en marcha

Suponga que tiene una aplicación web simple escrita en un marco de back-end que alguna vez fue popular y que se ejecutaba en un solo servidor Apache/Nginx/lo que sea y entregaba páginas renderizadas del lado del servidor. Cada vez que un usuario hace clic en un enlace para realizar una acción, la solicitud se envía al servidor, el único servidor maneja la solicitud, se conecta a la única base de datos, realiza los cambios y luego entrega una nueva página con los resultados visibles de su acción.

Ahora suponga que 10 años después, su aplicación se ha convertido en un gigante muy popular y tiene problemas de escalamiento, tiene problemas de rendimiento, no puede crear funciones muy rápido porque todo el código está estrechamente acoplado, algunos los grandes nombres han comenzado dependiendo de que su servicio esté "siempre disponible" ™, o por alguna otra razón, ahora necesita cambiar el motor subyacente de su aplicación.

Después de semanas de investigación, es posible que haya tomado una pequeña decisión como "Usemos React y descarguemos gran parte del procesamiento y la lógica de visualización en la CPU del cliente", o puede haber tomado varias decisiones que implican dividir su aplicación en varios microservicios y reinventando la base de datos utilizando un algoritmo de reducción de mapas y un poco de aprendizaje automático. Cualquiera que sea la decisión final, debe mantener la paridad de características con su aplicación anterior y trasladarla al nuevo marco.

La pregunta

Esta pregunta no se trata de los detalles técnicos de esta decisión (p. ej., "¿Cómo se hace eso?"), se trata de los detalles administrativos de esta decisión. ¿Cómo gestionas un cambio así?

¿Lo trata como si estuviera creando una nueva aplicación desde cero y cada característica de la aplicación anterior es solo una historia de usuario en la nueva?

¿O lo trata como una nueva función para la aplicación existente?

¿Debería ramificarse a partir del código anterior y comenzar la reelaboración en una nueva rama del repositorio anterior?

¿O debería comenzar un nuevo repositorio para el nuevo marco, ya que los conflictos de fusión no solo son esperados, sino casi un obstáculo, ya que sus modelos y suposiciones subyacentes podrían ser completamente diferentes?

¿Qué pasa con la aplicación anterior durante el período de transición? ¿Debería congelarlo para facilitar la paridad? ¿O debería continuar desarrollándose en paralelo?

He visto muchas metodologías para la gestión de proyectos y he seleccionado y elegido mis herramientas favoritas de todo lo que he visto. Pero nunca he visto a alguien lograr cambiar bien los marcos. Incluso algo supuestamente simple como pasar de ReactJS a Vue (tienen el mismo propósito, ambos están escritos en JavaScript y muchas de las suposiciones subyacentes y los modelos mentales son idénticos) puede llevar meses de desarrollo y pérdida de tiempo antes de que se produzca el cambio. descartado porque simplemente no valía la pena el esfuerzo.

Etiquetas

Literalmente no tenía idea de qué etiquetas elegir. Por favor ayuda.

Respuestas (2)

He hecho esto un par de veces, aunque no siempre fue una aplicación web y no fue por razones de escala. Esto es lo que hicimos:

  • Trátelo como una nueva aplicación. En nuestro caso, cambiamos el nombre de la aplicación cuando lo hicimos.
  • Póngalo en su propio repositorio.
  • Congele el desarrollo en el anterior, excepto para las correcciones de errores críticos, de modo que todos los recursos puedan dedicarse a la migración.
  • Reduzca el conjunto de funciones si es posible, al menos para la primera versión. Por ejemplo, si tiene características que rara vez se usan, no se comprometa con ellas. Obviamente, haga esto en consulta con las partes interesadas, explicando que está tratando de administrar el alcance para mantener un cronograma razonable.
  • Defina muy claramente los criterios de aceptación. Ayude a sus partes interesadas a comprender por qué el comportamiento, la apariencia o los resultados pueden no ser idénticos, debido a cosas ocultas en las que normalmente no piensan y/o porque el nuevo marco tiene cosas diferentes integradas.
  • Anticipe que encontrará errores en el código existente, que deben corregirse en el nuevo código. Sin embargo, tenga en cuenta que es posible que deba parchear el nuevo código para reproducir el mal comportamiento del código anterior para facilitar las pruebas de aceptación, sabiendo que después de la aceptación, eliminará esos parches y obtendrá la aprobación del nuevo comportamiento.
  • Resista la tentación de hacer cambios o mejoras en el comportamiento durante la migración. Presente boletos para ellos; quizás deje ganchos arquitectónicos para ellos, o comentarios en el código; pero no intente "migrar a un nuevo marco" y "cambiar el comportamiento existente" al mismo tiempo.
  • Planee escribir un informe de puesta en marcha al final, que explique cómo examinó el nuevo código contra el código anterior y aborde los cambios que se realizaron, incluido un apéndice con los informes de prueba relevantes. Escríbelo sobre la marcha, te ahorrará dolores de cabeza más tarde.
  • Permítase una generosa cantidad de holgura en su horario, porque es probable que se encuentre con dificultades técnicas imprevistas. Siempre es mejor prometer poco y cumplir en exceso.
  • Asegúrese de que sus partes interesadas estén al tanto de ese cronograma y lo acepten por adelantado. Esto maneja las expectativas y te da algo que señalar cuando se impacientan porque está tomando tanto tiempo.

Un par de puntos técnicos:

Ya teníamos un gran conjunto de pruebas de regresión y la preocupación se centraba principalmente en los resultados numéricos. Pusimos todos nuestros parches para reproducir errores en el mismo módulo con un nombre obvio, y mantuvimos el código correcto presente en los comentarios, para que fuera fácil eliminar los parches cuando terminara.

Existe una tensión entre hacer las cosas fáciles primero para que pueda probar el concepto y obtener un subconjunto en funcionamiento y bajo revisión lo antes posible, y hacer las cosas más complicadas primero para que no tenga que volver a diseñar. a medio camino. La suposición ágil habitual de hacer lo más simple que funcione y refactorizar según sea necesario a medida que avanza es un poco incompatible con esta situación, en mi opinión, porque en este caso SÍ sabes que "lo vas a necesitar". Podría sugerir que parte del equipo invierta en el análisis de las partes más complicadas mientras se desarrolla la infraestructura inicial, la selección de tecnología/curva de aprendizaje, etc.

Menciono esto porque esta fue la razón por la que uno de mis proyectos de migración superó significativamente el cronograma planificado: primero hicimos las cosas fáciles y luego tuvimos que calzar la complejidad bajo presión de tiempo.

¡Espero que esto ayude! Estaré interesado en otras respuestas también.

No creo que haya una respuesta "correcta" para esto. La respuesta de Vicki es perfectamente válida. Voy a dar otra respuesta que creo que también es correcta.

Comience por hacer una lista de los mayores problemas que tiene su aplicación ahora. Tal vez se deba a la redundancia de la base de datos, el tiempo de carga, la fragilidad de la arquitectura, la cobertura de las pruebas, lo que sea. Ahora clasifique esa lista en una acumulación de mejoras. Ahora comience en la parte superior y avance hacia abajo.

Fácil, ¿verdad? Bueno, hay algunas cosas a considerar:

1) ¿El código de su aplicación está débilmente acoplado o, mejor aún, está desacoplado? ¿Cuántas piezas puedes separar? Si tiene muchos componentes estrechamente acoplados, probablemente esté atascado en un enfoque de reemplazo completo como sugiere Vicki o tenga que esforzarse para mejorar la arquitectura y la capacidad de mantenimiento de su aplicación antes de poder hacer cualquier otra cosa.

2) ¿Pequeñas correcciones parciales o grandes correcciones? Tomemos su ejemplo de React. Supongamos por un momento que su interfaz de usuario existente se comunica con los servicios web para la lógica empresarial. Simplemente podría reemplazar todo el lado de la interfaz de usuario y dejar que Reaccione se comunique con los servicios web. Eso también puede significar algunos ajustes de los servicios web para REST si usó SOAP o el protocolo de servicio web de Microsoft antes. Esta es una gran solución para el problema de los recursos. Por otro lado, una pequeña solución puede ser tan simple como agregar hardware o una solución de equilibrio de carga. Si lo hace, es posible que no solucione el problema de forma permanente, pero puede reducirlo mucho más en la cartera de pedidos. Por el costo de uno o tres servidores, acaba de comprar un año en su aplicación y puede concentrarse en otros problemas que son más difíciles de resolver que comprar algunas CPU adicionales.

3) Concéntrese en resolver problemas, no en implementar diseños. Para cada uno de esos elementos, el objetivo es mejorar la velocidad de carga X cantidad o reducir los errores al umbral Y. Si solo está implementando una solución predefinida poco a poco, es mejor que adopte un enfoque de reemplazo completo, porque básicamente lo está haciendo de todos modos. Este enfoque solo vale la pena si obtiene los beneficios de resolver cada problema sobre la marcha.

Como dije, no hay necesariamente una respuesta "correcta", en cuál de estos enfoques de la imagen o cómo pasaría por este enfoque. En este enfoque, iterativamente toma las mejores decisiones en el momento y obtiene beneficios sobre la marcha. En el otro enfoque, puede comenzar desde cero sin restricciones, pero solo al final descubre si su nuevo enfoque resuelve el problema. Tienes que mirar tu situación y decidir cuál es la correcta.