Muy cuidadosamente
La función de ramificación es una opción, pero creo que es algo pesada. También hace que las modificaciones profundas sean fáciles, lo que puede conducir a una bifurcación de su aplicación si no se mantiene bajo control. Idealmente, desea aumentar al máximo las personalizaciones en un intento de mantener su base de código central tan común y genérica como sea posible.
Así es como lo haría, aunque no sé si es aplicable a su base de código sin grandes modificaciones y refactorizaciones. Tuve un proyecto similar donde la funcionalidad básica era la misma pero cada cliente requería un conjunto muy específico de características. Creé un conjunto de módulos y contenedores que luego ensamblo a través de la configuración (a la IoC).
luego, para cada cliente, creé un proyecto que básicamente contiene las configuraciones y el script de compilación para crear una instalación totalmente configurada para su sitio. De vez en cuando coloco allí también algunos componentes personalizados para este cliente. Pero esto es raro y, siempre que sea posible, trato de hacerlo en una forma más genérica y lo empujo hacia abajo para que otros proyectos puedan usarlos.
El resultado final es que obtuve el nivel de personalización que necesitaba, obtuve secuencias de comandos de instalación personalizadas para que cuando llegue al sitio del cliente no parezca que esté modificando el sistema todo el tiempo y, como una ventaja adicional MUY significativa, obtengo para poder crear pruebas de regresión conectadas directamente a la compilación. De esta manera, cada vez que recibo un error específico del cliente, puedo escribir una prueba que reafirmará el sistema a medida que se implementa y, por lo tanto, puede hacer TDD incluso a ese nivel.
en resumen:
- Sistema altamente modularizado con una estructura de proyecto plana.
- Cree un proyecto para cada perfil de configuración (cliente, aunque más de uno puede compartir un perfil)
- Reúna los conjuntos de funciones requeridos como un producto diferente y trátelo como tal.
Si se realiza correctamente, el ensamblaje de su producto debe contener todos menos algunos archivos de configuración.
Después de usar esto por un tiempo, terminé creando metapaquetes que ensamblan los sistemas más utilizados o esenciales como una unidad central y utilizo este metapaquete para ensambles de clientes. Después de unos años terminé teniendo una gran caja de herramientas que pude armar muy rápidamente para crear soluciones para el cliente. Actualmente estoy investigando Spring Roo y veo si no puedo impulsar la idea un poco más, esperando que algún día pueda crear un primer borrador del sistema con el cliente en nuestra primera entrevista ... Supongo que podría llamarlo User Driven Desarrollo ;-).
Espero que esto haya ayudado
#ifdef
Funciona para ti?