¿Cómo puedo administrar eficientemente el código de nuestro producto para múltiples clientes con personalizaciones separadas para cada cliente?

Acabo de comenzar un nuevo trabajo en una compañía basada en productos que permite personalizaciones de clientes. Trabajo en el producto A.

El producto A se vende al cliente 1 y al cliente 2, por ejemplo. Entonces cada cliente solicita sus propias personalizaciones. Estas personalizaciones deben mantenerse separadas de las características principales de la transmisión. Sin embargo, las nuevas características de flujo principal se deben include en cada una de las copys de los clientes mientras se reservan sus propias personalizaciones.

Los clientes pueden solicitar personalizaciones desde nombres simples de campos o agregar / eliminar grillas o columnas de informes hasta agregar / eliminar páginas enteras o modules.

Recién comenzamos a usar SVN para administrar nuestro código C # .net.

Mi pregunta es: de la experiencia de cualquiera, cuál es la mejor manera de administrar el código para todos estos requisitos mientras se networkinguce el esfuerzo duplicado:

  1. Principales características del producto para todos los clientes.
  2. Separe la personalización de cada cliente y consérvela para el cliente a lo largo de toda la vida útil del producto del cliente.

La ramificación puede resolver parte del problema, sin embargo, las características principales no se includeán en las versiones de los clientes.

Espero que esta pregunta sea lo suficientemente clara, y explica tu sugerencia lo más clara posible, tal vez con ejemplos. Gracias

Puedes utilizar

  • El layout modular (núcleo + set de modules) y el producto final para el cliente será combinación (set intercambiable) de unidades , fácil de administrar con elementos externos en el repository (cada personalización produce una nueva horquilla de la unidad ascendente): es una mezcla de "twigs de proveedores" + exterioridad
  • Código unificado de Monolite, la personalización de cada cliente recostackda en algunas configuraciones (que usted crea automáticamente en la etapa de lanzamiento | compilation) y los cambios (basados ​​en esta configuration) se aplican al código común solo en el lado del cliente
  • Mezcla de methods previos: mantener los cambios de cada cliente en una sucursal por separado, sincronizar las twigs con el desarrollo de la línea principal (manera ficticia, requerir una fuerte política de fusión y precisión, puede requerir mucho trabajo en integración refactoring merge / google "Merge Hell", "Big Bang Merge "/ – pero trabaje sin interrupciones en la etapa de soporte de cambios en el medio del ciclo de vida)

Personalmente, prefiero la Forma 1: en este caso sé cada segundo, qué producto tiene cada cliente (y no lo he reconstruido a partir del historial de logging) y cómo evolucionó este producto durante todo el ciclo de vida.

En mi compañía tenemos la misma situación. Nuestra solución:

  • En SvN tenemos estructura

    tronco – twigs principales de la versión del producto – versiones reales de los clientes y futura twig de las nuevas versiones principales

    • cliente 1 (v1, v2, etc.)
    • cliente 2 (v1, v2, etc.)
    • versión principal branches tags – versión para la versión principal del producto y tags de cliente

Cuando desarrollamos el producto principal, nos comprometemos con el tronco (o las twigs futuras). Cuando el cliente solicita una nueva funcionalidad, desarrollamos esto en la twig de la versión del cliente. Después del lanzamiento, creamos la label del cliente (en las tags). Si la funcionalidad del cliente es buena y decidimos includela en la versión principal, fusionamos sus cambios en el enlace troncal. Otro aspecto: si la funcionalidad principal de la troncal se debe include en la versión de clientes, se fusionó con las sucursales de los clientes.

Tenemos aproximadamente 6 versiones diferentes de clientes. En realidad hacemos la fusión manualmente, pero pronto queremos hacer lotes para que este process sea automático

Yo recomendaría no mantener una sucursal siempre divergente por cliente. Hará que cualquier cambio sea doloroso, ya que es probable que exista una sucursal de cliente que genere conflictos de fusión.

A partir de los ejemplos que da, parece más una simple cuestión de permitir más configuration. Puede permitir que los nombres de campos, columnas, páginas y modules se configuren a través de algún tipo de interfaz de administrador, y almacenar la configuration para el final del cliente. O bien, si desea conservar el control total y no desea build dicha interfaz de usuario, almacene la configuration para cada cliente en su extremo y actualícela en su nombre.