Sugerencia de modelo de ramificación para el mismo proyecto para varios clientes

11

Tenemos un proyecto muy grande que incluye varias aplicaciones que sirven de base para diferentes clientes.

Cada cliente tiene su propia personalización del producto, diferentes hitos, diferentes requisitos, etc. y, por lo tanto, cada proyecto evolucionará de forma independiente en función de sus propias necesidades.

El núcleo del proyecto es similar (pero no igual) en cada proyecto y la organización está hecha para que haya equipos que manejen a cada cliente de forma independiente (pero con comunicación entre ellos según sea necesario). Hasta ahora, no he podido encontrar ningún esquema que se adapte a nuestras necesidades, ya sea buscando en Internet o surgiendo alguna idea brillante :)

Hasta ahora, hemos estado trabajando para que el producto se adapte a todas las necesidades, con ramas específicas para los cambios necesarios, pero, aunque el producto tiene una buena arquitectura, lentamente se está convirtiendo en un gran problema. Estos son los principales problemas que enfrentamos:

  • Diferentes hitos para cada cliente: lo que significa que cada equipo debe producir versiones en diferentes momentos sin que el resto de los compromisos afecten la estabilidad o su producto.
  • Diferentes requisitos, que pueden o no afectar el núcleo del sistema en algunos casos.
  • Grandes equipos (más de 20 miembros del equipo)
  • Manejo de errores en el sistema: ¿Qué hacer si un equipo encuentra un error en su proyecto que podría afectar a otros clientes?

Nota: Estamos hablando de un proyecto que tiene 10 + M LOC.

Nota: Estamos usando Team Foundation System, Visual Studio 2008 y C # (principalmente).

¿Alguna sugerencia, fuente o idea sobre cómo abordar la situación? ¿Hay algún modelo en el mercado que tenga un problema similar?

Jorge Córdoba
fuente

Respuestas:

9

En realidad, sugeriría que no necesita un modelo de ramificación, sino un enfoque integral completo para lidiar con las restricciones multidimensionales con respecto al sistema sin ramificación. En la práctica, creo que siempre será un problema mantener múltiples sistemas que tienen algunos puntos en común, pero que evolucionarán de manera diferente en las ramas, por lo que es mejor convertir todo en un solo sistema que evolucionará como un todo, pero que consta de diferentes configuraciones. Esto puede parecer demasiado simplista, pero hay una extensa investigación en esta área, con muchas aplicaciones industriales exitosas.

El nombre de este enfoque es Software Product Lines o, a veces, Product Line Engineering . Desde la página de líneas de productos de software de CMU SEI :

Una línea de productos de software (SPL) es un conjunto de sistemas intensivos en software que comparten un conjunto común de características administradas que satisfacen las necesidades específicas de un segmento o misión de mercado en particular y que se desarrollan a partir de un conjunto común de activos centrales de una manera prescrita .

La idea clave es que cada requisito, cada hito, cada característica (un término clave en este dominio) es parte del sistema completo al más alto nivel. Los sistemas reales implementados en varios clientes son esencialmente una colección de características. Sin embargo, cada característica no es solo un componente físico mezclado en el sistema, se define como dependiente o habilitado por otras características (de modo que al elegir una característica, puede incluir automáticamente sus dependencias, etc.)

En lugar de mantener todas estas ramas, terminas manteniendo un sistema junto con un conjunto de configuraciones específicas del cliente.

Puede ser difícil o incluso imposible en la práctica migrar a un enfoque de este tipo con un sistema muy grande, pero incluso entonces será útil investigar los enfoques utilizados en SPL para evaluar qué enfoques utilizados allí pueden ser al menos (parcialmente) integrado en tu trabajo.

Algunos enlaces útiles adicionales:

Deckard
fuente
11

Cuando comencé en mi primer trabajo, trabajé en proyectos similares (pero a menor escala) y enfrentamos los mismos problemas. También comenzamos con los requisitos generales de manejo de soluciones para todos los clientes, pero eso fue posible solo en el mismo punto donde los requisitos se vuelven contradictorios. Hicimos lo que usted sugiere y comenzamos una versión separada para cada cliente. Incluso esto resolvió el problema con los requisitos y la personalización, se convierte en una pesadilla de mantenimiento para resolver errores y cambios globales.

Debido a que el código en la aplicación era solo similar, fusionar los cambios de una versión de cliente a otra era muy complejo y requería volver a probar cada versión por separado (¡no teníamos pruebas automáticas!). A menudo causaba errores de regresión en diferentes versiones. En su escenario, esto puede ser aún peor porque un equipo resolverá el error en su versión y otro equipo tendrá que fusionar ese cambio con la versión que no entienden completamente (éramos un equipo trabajando en todas las versiones).

A menos que tenga un núcleo global compartido, tendrá los mismos problemas. Antes de dejar la empresa descubrimos que nuestro enfoque era incorrecto. Para admitir este escenario de desarrollo, necesitábamos un modelo de datos y núcleo extensible compartido que se pueda configurar desde las capas de aplicaciones personalizables superiores. Este núcleo debe usarse como base para la personalización específica de cada cliente y debe ser mantenido por un equipo separado. Incluirá algunas complicaciones de gestión porque varios gerentes de proyecto necesitarán recursos del mismo equipo, pero es la única forma de hacer que la arquitectura sea coherente, controlar todo el proceso y mantener las versiones sincronizadas.

Ladislav Mrnka
fuente
2

Puede que sea una base, pero creo que lo que está enfrentando con su núcleo de su sistema es el mismo problema que enfrentan todos los que usan componentes y necesitan mantener y soportar diferentes versiones de su software y cada versión diferente requiere un conjunto diferente de versiones de componentes.

Por ejemplo

  • la versión 1.0 requiere Biblioteca A 1.0, Biblioteca B 2.0, Biblioteca C 5.6
  • la versión 2.0 requiere la Biblioteca A 1.0, la Biblioteca B 3.7, la Biblioteca C 5.7
  • la versión 3.0 requiere la Biblioteca A 1.2, la Biblioteca B 3.7, la Biblioteca C 5.8

La forma en que resolvimos el problema del componente es tener todas las versiones de las bibliotecas en nuestro sistema de control de versiones (las creamos en la fuente) y hacer que cada proyecto use la versión de biblioteca adecuada cambiando su ruta de búsqueda (¿ruta de referencia?).

En Delphi, esto se hace fácilmente a través del archivo de configuración del proyecto (bajo control de código fuente) si no necesita las bibliotecas en el momento del diseño, de lo contrario, todavía es factible, pero se vuelve un poco más difícil ya que necesita cambiar el IDE de Delphi para usar la versión correcta también (los archivos de registro (.reg) bajo control de versiones pueden venir al rescate aquí).

Una solución para su sistema central podría ser tratarlo como una biblioteca para la que mantiene diferentes versiones. Lo que en esencia significa que debe configurar diferentes ramas para cada versión. La aplicación de un cliente puede utilizar la "versión" adecuada de su sistema central haciendo referencia a la carpeta de sucursal del sistema central adecuado.

Donde las dependencias para su sistema central se parecerían al ejemplo anterior, las dependencias para sus aplicaciones cliente "simplemente" tienen una referencia adicional: la versión de su sistema central.

Una ventaja adicional con la aplicación de cliente múltiple aquí es que puede elegir cuándo comenzar a usar una versión específica de su sistema central y que no se ve afectado por los cambios en el sistema central que aún no está listo para usar para una aplicación de cliente específica.

Marjan Venema
fuente