Estou trabalhando em um grande projeto de software altamente personalizado para vários clientes em todo o mundo. Isso significa que talvez tenhamos 80% de código comum entre os vários clientes, mas também muitos códigos que precisam ser alterados de um cliente para outro. No passado, fizemos nosso desenvolvimento em repositórios separados (SVN) e, quando um novo projeto foi iniciado (temos poucos, mas grandes clientes), criamos outro repositório com base em qualquer projeto passado que possua a melhor base de código para nossas necessidades. Isso funcionou no passado, mas tivemos vários problemas:
- Os erros corrigidos em um repositório não são corrigidos em outros repositórios. Isso pode ser um problema de organização, mas acho difícil corrigir e corrigir um bug em 5 repositórios diferentes, tendo em mente que a equipe que mantém esse repositório pode estar em outra parte do mundo e não temos seu ambiente de teste , nem conhece sua programação ou quais requisitos eles têm (um "bug" em um país pode ser um "recurso" em outro).
- Os recursos e aprimoramentos feitos para um projeto, que também podem ser úteis para outro projeto, são perdidos ou, se usados em outro projeto, muitas vezes causam grandes dores de cabeça, mesclando-os de uma base de código para outra (já que os dois ramos podem ter sido desenvolvidos independentemente por um ano )
- As refatorações e aprimoramentos de código feitos em uma ramificação de desenvolvimento são perdidos ou causam mais danos do que benefícios, se você precisar mesclar todas essas alterações entre as ramificações.
Agora estamos discutindo como resolver esses problemas e, até agora, surgiram as seguintes idéias sobre como resolver isso:
Mantenha o desenvolvimento em ramificações separadas, mas organize-se melhor com um repositório central onde as correções gerais de erros são mescladas e com todos os projetos que mesclam as alterações desse repositório central em seus próprios, regularmente (por exemplo, diariamente). Isso requer muita disciplina e muito esforço para se fundir entre os ramos. Portanto, não estou convencido de que funcione e que possamos manter essa disciplina, especialmente quando a pressão do tempo se aproxima.
Abandone as ramificações de desenvolvimento separadas e tenha um repositório de código central onde todo o nosso código vive e faça nossa personalização com módulos e opções de configuração conectáveis. Já estamos usando contêineres de injeção de dependência para resolver dependências em nosso código e seguimos o padrão MVVM na maioria de nosso código para separar de maneira limpa a lógica comercial da nossa interface do usuário.
A segunda abordagem parece ser mais elegante, mas temos muitos problemas não resolvidos nessa abordagem. Por exemplo: como lidar com alterações / adições no seu modelo / banco de dados. Estamos usando o .NET com Entity Framework para ter entidades fortemente tipadas. Não vejo como podemos lidar com propriedades que são necessárias para um cliente, mas inúteis para outro cliente sem sobrecarregar nosso modelo de dados. Estamos pensando em resolver isso no banco de dados usando tabelas de satélite (com tabelas separadas em que nossas colunas extras para uma entidade específica vivem com um mapeamento 1: 1 para a entidade original), mas esse é apenas o banco de dados. Como você lida com isso no código? Nosso modelo de dados reside em uma biblioteca central que não poderíamos estender para cada cliente usando essa abordagem.
Tenho certeza de que não somos a única equipe que está lutando com esse problema e estou chocado ao encontrar tão pouco material sobre o assunto.
Então, minhas perguntas são as seguintes:
- Que experiência você tem com software altamente personalizado, qual abordagem você escolheu e como funcionou para você?
- Que abordagem você recomenda e por quê? Existe uma abordagem melhor?
- Existem bons livros ou artigos sobre o assunto que você pode recomendar?
- Você tem recomendações específicas para o nosso ambiente técnico (.NET, Entity Framework, WPF, DI)?
Editar:
Obrigado por todas as sugestões. A maioria das idéias corresponde às que já tínhamos em nossa equipe, mas é realmente útil ver a experiência que você teve com elas e dicas para implementá-las melhor.
Ainda não tenho certeza de que caminho seguiremos e não estou tomando a decisão (sozinho), mas transmitirei isso na minha equipe e tenho certeza de que será útil.
No momento, o teor parece ser um único repositório usando vários módulos específicos do cliente. Não tenho certeza de que nossa arquitetura esteja de acordo com isso ou quanto temos que investir para ajustá-la; portanto, algumas coisas podem viver em repositórios separados por um tempo, mas acho que é a única solução de longo prazo que funcionará.
Então, obrigado novamente por todas as respostas!