Muito cuidado
A ramificação de recursos é uma opção, mas acho que é um pouco pesada. Além disso, facilita modificações profundas, o que pode levar a uma bifurcação total da sua aplicação, se não for mantida sob controle. Idealmente, você deseja aumentar o máximo possível as personalizações na tentativa de manter sua base de códigos principal o mais comum e genérica possível.
Aqui está como eu faria isso, embora não saiba se é aplicável à sua base de código sem grandes modificações e redimensionamentos. Eu tinha um projeto semelhante em que a funcionalidade básica era a mesma, mas cada cliente exigia um conjunto muito específico de recursos. Criei um conjunto de módulos e contêineres que monto por meio da configuração (à la IoC).
então, para cada cliente, criei um projeto que basicamente contém as configurações e o script de construção para criar uma instalação totalmente configurada para o site. Ocasionalmente, coloco também alguns componentes personalizados para esse cliente. Mas isso é raro e, sempre que possível, tento torná-lo de uma forma mais genérica e pressioná-lo para que outros projetos possam usá-los.
O resultado final é que eu tenho o nível de personalização necessário, scripts de instalação personalizados para que, quando eu chegue ao site do cliente, não pareço mexer no sistema o tempo todo e, como um bônus MUITO significativo adicional, recebo para poder criar testes de regressão conectados diretamente à compilação. Dessa forma, sempre que recebo um bug específico do cliente, posso escrever um teste que afirme o sistema à medida que ele é implantado e, portanto, possa fazer TDD mesmo nesse nível.
então, resumindo:
- Sistema fortemente modularizado com uma estrutura de projeto plana.
- Crie um projeto para cada perfil de configuração (cliente, embora mais de um possa compartilhar um perfil)
- Monte os conjuntos de funcionalidades necessárias como um produto diferente e trate-o como tal.
Se feito corretamente, a montagem do produto deve conter todos os arquivos de configuração, exceto alguns.
Depois de usar isso por um tempo, acabei criando meta-pacotes que montam os sistemas mais utilizados ou essenciais como uma unidade principal e usam esse meta-pacote para montagens de clientes. Depois de alguns anos, acabei tendo uma grande caixa de ferramentas que pude montar muito rapidamente para criar soluções para os clientes. Atualmente, estou analisando o Spring Roo e ver se não consigo avançar um pouco mais com a idéia, esperando que um dia eu possa criar um primeiro rascunho do sistema diretamente com o cliente em nossa primeira entrevista ... Acho que você poderia chamá-lo de Orientado pelo Usuário Desenvolvimento ;-).
Espero que isso tenha ajudado
#ifdef
para você?