Eu tenho um grande projeto java e usamos o maven para o nosso ciclo de construção. Esse projeto é amplamente utilizado - em outros projetos, em várias aplicações, algumas das quais estão contidas e outras em outros lugares ... Para ser honesto, é um pouco confuso (vários bits são adicionados em momentos diferentes para detalhes específicos). fins) e gostaria de limpá-lo um pouco. Além disso, ele não foi totalmente testado (muitos bits foram adicionados sem testes adequados de unidade e integração), e existem alguns testes que demoram muito tempo para serem executados ou que na verdade não passam ... (uh-oh) - então os testes são desativados no ciclo de construção do maven (novamente, uh-oh).
Estou pensando em separar esse grande projeto em projetos específicos menores, de modo que o subprojeto 'final' (ou vários subprojetos) selecionasse os vários subprojetos de que precisaria.
Meu pensamento é o seguinte:
- se eu separar o grande projeto em vários subprojetos, isso deixa claro qual é a responsabilidade de cada projeto.
- separando-o em subprojetos, posso limpar os testes de cada subprojeto individualmente e ativar os testes para esse subprojeto no ciclo de criação do maven.
Estou um pouco preocupado com o impacto que isso pode ter no tempo de compilação.
- A imposição de uma estrutura no projeto grande (ou seja, em subprojetos menores) atrasaria o compilador?
Além disso, tenho uma ligeira preocupação com o impacto que isso pode ter no tempo de edição nos IDEs (usamos principalmente o Intellij). O Intellij parece construir cada projeto alternadamente através da árvore de dependência - ou seja, se C depende de B depende de A e eu altero A, ele não tentará construir B a menos que A seja compilado, e assim por diante. Provavelmente isso é vantajoso, mas descobri que, por exemplo, se eu mudar uma interface em A que é amplamente usada em B e C, leva algum tempo para corrigir todos os erros dessa alteração ...
Outra questão é como usar as classes de fábrica. Alguns aspectos do projeto dependem de frascos externos. Ocasionalmente (felizmente, não com frequência), elas são atualizadas e precisamos migrar. Nós tendemos a lidar com isso usando uma classe Factory que aponta para as versões corretas do código externo (portanto, não precisamos alterar todas as implementações em toda a base de código).
No momento, tudo isso está no grande projeto, mas estou pensando que, ao mudar para subprojetos, eu poderia desenvolver um novo projeto para a implementação de um novo código externo, garantir que o subprojeto esteja totalmente funcional e testado, e depois alterne as dependências / classe de fábrica no projeto do usuário. No entanto, isso se torna mais complicado pelo uso extensivo de interfaces em todo o grande projeto. Por exemplo
- subprojeto A - contém interfaces
- subprojeto B - depende de A para interfaces e jar externo antigo
- subprojeto C - depende de B (e, portanto, de A e jar externo antigo) e contém uma classe Factory que usa implementações de interfaces de B
Se eu precisar alterar o jar externo de B, posso:
- criar subprojeto B_ii - novamente depende de A, e agora o novo jar externo
- uma vez totalmente funcional, posso adicionar a dependência de C a B_ii e alterar a classe Factory para usar as novas implementações de interfaces.
quando tudo estiver funcionando, posso remover a dependência de C do original B e, se desejar, remover o subprojeto B.
Essa é uma maneira sensata de fazer isso?
Então, em geral, minhas perguntas são:
- Alguém tem alguma experiência em dividir grandes projetos? Existem dicas / truques que você gostaria de compartilhar?
- Que impacto isso teve no seu desenvolvimento e nos tempos de construção?
- Que conselho você poderia oferecer para estruturar essa ruptura de um projeto?
fonte
Respostas:
Vou fazer um primeiro corte rápido nisso (ótimo Q BTW!):
Não o suficiente para importar, a sobrecarga está realmente nas invocações do Maven.
Diferentes IDEs têm seus diferentes pontos fortes em relação às ligações do Maven e ao gerenciamento de dependências. O estado atual do jogo parece ser que ele funciona principalmente nos mais recentes Eclipse, Netbeans e IntelliJ - mas você precisará ensinar aos desenvolvedores o golpe duplo de emergência "Atualizar arquivos de origem do disco e reconstruir todos os projetos relacionados".
Acho que tenho que fazer isso cada vez menos atualmente. Ter uma unidade SSD faz uma enorme diferença aqui BTW.
O gerenciamento de dependências é incrivelmente importante, independentemente de qual tecnologia (Maven / Ivy / qualquer que seja) use para ajudá-lo a implementá-lo.
Eu começaria tirando os extensos relatórios do plug-in de dependência do Maven e analisando o que você tem. De um modo geral, você define a dependência no gerenciamento de dependências do POM o mais alto possível na cadeia alimentar, mas não maior. Portanto, se dois de seus submódulos usarem uma dependência externa, leve-a para o POM pai e assim por diante.
A atualização de JARs externos sempre deve ser feita como um miniprojeto adequado. Avalie por que você está atualizando, altere o código-fonte para tirar proveito de quaisquer novos recursos / correções de bugs, etc. Basta pressionar a versão sem essa análise e o trabalho irá causar problemas.
Impacto muito pequeno nos tempos de desenvolvimento e construção - um enorme ganho de tempo para o nosso pipeline de entrega contínua geral.
Faça as pequenas coisas direito e as grandes coisas tendem a cair de forma limpa depois. Portanto, divida as coisas pouco a pouco - não faça uma reestruturação massiva de todo o lote, a menos que você tenha uma alta porcentagem de cobertura com seus testes de integração.
Escreva testes de integração antes da divisão - você deve obter mais ou menos os mesmos resultados após a divisão.
Desenhe diagramas da modularidade que você tem agora e onde deseja chegar. Crie etapas intermediárias.
Não desista - agora alguns barbeadores Yak constroem as bases para poder "construir e refatorar rapidamente sem medo" Plug Shameless -> de Ben e I, The Well-Grounded Java Developer .
Boa sorte!
fonte
Minha opinião sobre isso é apenas separada quando necessário. No entanto, isso traz a seguinte pergunta: como determino se é necessário?
Um dos motivos é que os desenvolvedores precisam lidar com vários projetos e tentar descobrir além de qual pacote Java é a qual projeto ele deve pertencer. Estive em projetos nos quais isso se tornou realmente anêmico e tinha um projeto que tinha apenas quatro classes implementando uma funcionalidade apenas porque essa é a direção da arquitetura. Isso também aconteceu antes que o Maven fosse popular, de modo que os caminhos da classe e o que não precisam ser configurados nos scripts IDE e Ant.
A outra razão é que você teria mais peças móveis para lidar em termos de encanamento dos arquivos e provavelmente teria espaguete de dependência antes que perceba.
A refatoração também é mais fácil dentro de um projeto do que entre projetos.
Se o tempo de compilação for um problema, forneça um hardware melhor.
fonte