Separazione di progetti java

12

Ho un grande progetto java e usiamo Maven per il nostro ciclo di build. Questo progetto è ampiamente utilizzato - in altri progetti, in varie applicazioni, alcuni dei quali sono contenuti in esso e altri che sono altrove ... Per essere onesti, è un po 'un casino (diversi bit aggiunti in momenti diversi per specifici scopi), e mi piacerebbe pulirlo un po '. Inoltre, non è completamente testato (sono stati aggiunti molti bit senza test di unità e integrazione adeguati), e ci sono alcuni test che richiedono molto tempo per essere eseguiti o che non passano effettivamente ... (uh-oh) - così i test sono disattivati nel ciclo di costruzione di Maven (di nuovo, uh-oh).

Sto pensando di separare questo grande progetto in progetti specifici più piccoli, in modo che il sottoprogetto "finale" (o diversi sottoprogetti) raccolga i vari sottoprogetti di cui avrebbe bisogno.

Il mio modo di pensare è il seguente:

  • se separo il grande progetto in vari sottoprogetti, questo rende chiaro quale sia la responsabilità di ciascun progetto.
  • separando in sottoprogetti, posso quindi ripulire individualmente i test di ciascun sottoprogetto e attivare il test per quel sottoprogetto nel ciclo di costruzione di maven.

Sono leggermente preoccupato per l'impatto che questo potrebbe avere sul tempo di costruzione.

  • Imporre una struttura al progetto di grandi dimensioni (ad esempio in sottoprogetti più piccoli) rallenterebbe il compilatore?

Inoltre, ho una leggera preoccupazione sull'impatto che questo potrebbe avere nel tempo di editing degli IDE (principalmente utilizziamo Intellij). Intellij sembra costruire ogni progetto a sua volta attraverso l'albero delle dipendenze - cioè se C dipende da B dipende da A, e io cambio A, non proverò a costruire B a meno che A non compili, e così via. Probabilmente è vantaggioso, ma ho scoperto che se, ad esempio, cambio un'interfaccia in A ampiamente utilizzata in B e C, ci vuole del tempo per correggere tutti gli errori da quella modifica ...

Un'altra domanda è come usare le classi di fabbrica. Alcuni aspetti del progetto dipendono da vasi esterni. Occasionalmente (per fortuna non spesso) questi sono aggiornati, e dobbiamo migrare. Tendiamo a gestirlo utilizzando una classe Factory che punta alle versioni corrette del codice esterno (quindi non è necessario modificare tutte le implementazioni in tutto il codice base).

Al momento questo è tutto nel grande progetto, ma sto pensando che passando a progetti, potrei sviluppare un nuovo progetto per l'implementazione di un nuovo codice esterno, assicurarmi che il sottoprogetto sia completamente funzionale e testato, e quindi passare le dipendenze / classe factory nel progetto utente. Tuttavia, questo è reso più complicato dall'uso esteso delle interfacce in tutto il grande progetto. Ad esempio

  • sottoprogetto A - contiene interfacce
  • progetto secondario B - dipende da A per interfacce e vecchio jar esterno
  • sotto-progetto C - dipende da B (e quindi A e vecchio jar esterno) e contiene una classe Factory che utilizza le implementazioni di interfacce di B

Se ho bisogno di cambiare il barattolo esterno di B, posso:

  • crea il sottoprogetto B_ii - di nuovo dipende da A, e ora il nuovo jar esterno
  • una volta completamente funzionante, posso aggiungere la dipendenza di C a B_ii e cambiare la classe Factory per usare le nuove implementazioni di interfacce.
  • quando tutto funziona, posso rimuovere la dipendenza di C dall'originale B e, se lo desideri, rimuovere il sottoprogetto B.

  • È un modo sensato di fare questo?

Quindi, in generale, le mie domande sono:

  • Qualcuno ha qualche esperienza di rottura di grandi progetti? Ci sono suggerimenti / trucchi che vorresti condividere?
  • Che impatto ha avuto sul tuo sviluppo e i tempi di costruzione?
  • Che consiglio potresti offrire per strutturare una tale rottura di un simile progetto?
posta amaidment 12.10.2012 - 12:27
fonte

2 risposte

10

Prenderò un rapido primo taglio a questo (ottimo Q BTW!):

Would imposing a structure on the large project (i.e. into smaller sub-projects) slow the compiler down?

Non abbastanza per quello che conta, il sovraccarico è in realtà nelle invocazioni di Maven.

Also, I have a slight concern on what impact this might have editing time in IDEs (we principally use Intellij). Intellij seems to build each project in turn through the dependency tree - i.e. if C depends on B depends on A, and I change A, it won't try to build B unless A compiles, and so on. Arguably that's advantageous, but I have found that if - for example, I change an interface in A that is widely used in B and C, it takes some time to fix all the errors from that change...

IDE diversi hanno i loro punti di forza diversi per quanto riguarda i binding Maven e la gestione delle dipendenze. Lo stato attuale del gioco sembra essere che principalmente funziona solo sugli ultimi Eclipse, Netbeans e IntelliJ - ma dovrai insegnare ai tuoi sviluppatori il doppio errore di emergenza di "Aggiorna i file sorgente dal disco e ricostruisci tutti i relativi progetti di esperti ".

Trovo di doverlo fare sempre meno in questi giorni. Avere un disco SSD fa una grande differenza qui a BTW.

snip factory classes paragraphs

La gestione delle dipendenze è incredibilmente importante, indipendentemente dalla tecnologia utilizzata (Maven / Ivy / qualunque) per aiutarti a implementarla.

Inizierei con l'estendere la segnalazione del plugin di dipendenza Maven e fare il punto su ciò che hai. In generale, si imposta la dipendenza nella gestione delle dipendenze di POM tanto in alto nella catena alimentare quanto più possibile, ma non più in alto. Quindi, se due dei tuoi sottomoduli utilizzano una dipendenza esterna, trasferiscili nel loro POM padre e così via e così via.

L'aggiornamento di JAR esterni dovrebbe sempre essere fatto come un mini-progetto appropriato. Valuta il motivo per cui esegui l'aggiornamento, modifica il codice sorgente per sfruttare tutte le nuove funzionalità / correzioni di bug, ecc. Basta eseguire il bump della versione senza questa analisi e il lavoro ti metterà nei guai.

So, in general, my questions are:

Does anyone have any experience of breaking up large projects? Are there any >tips/tricks that you would be willing to share?

  • Interfacce e iniezione di dipendenza sono tuoi amici.
  • Il libro di Michael Feather su che tratta efficacemente il codice legacy è assolutamente da leggere.
  • I test di integrazione sono tuoi amici
  • Suddividere i progetti secondari in foo-api (solo interfacce!) e foo-core e avere moduli dipende solo da foo-api aiuta molto e impone la separazione
  • I moduli Jboss e / o OSGi possono aiutare a rafforzare la separazione pulita

What impact did this have on your development and build times?

Impatto molto minore sui tempi di sviluppo e di costruzione: un enorme aumento di tempo per la nostra pipeline di fornitura continua complessiva.

What advice could you offer on structuring such a break-up of such a project?

Fai le piccole cose giuste e le cose grandi tendono a cadere in modo pulito dopo. Quindi dividi le cose un po 'alla volta - non effettuare una ristrutturazione completa dell'intero lotto a meno che tu non abbia un'alta percentuale di copertura con i tuoi test di integrazione.

Scrivi test di integrazione prima della divisione: dovresti ottenere più o meno gli stessi risultati dopo la divisione.

Disegna i diagrammi della modularità che hai ora e dove vuoi arrivare. Progetta i passaggi intermedi.

Non arrenderti: alcuni rasoi Yak ora gettano le basi per essere in grado di "costruire e rifattorizzare rapidamente senza paura" Plug vergognoso - > da Ben e I Sviluppatore Java ben fondato .

Buona fortuna!

    
risposta data 12.10.2012 - 13:47
fonte
0

La mia opinione su questo è solo separata quando necessario. Tuttavia, questo solleva la seguente domanda: Come faccio a determinare se è necessario?

  • Quando l'artefatto è diverso (ad esempio, non costruire l'EAR, WAR, JAR, jar di integrazione-testing nello stesso progetto).
  • Quando durante la separazione ti accorgi che alcuni codici devono esistere in più di un artefattore, li rifatti in uno nuovo.
  • Quando qualche altro progetto al di fuori del tuo team vuole usare qualcosa che hai nel tuo progetto.

Uno dei motivi è che gli sviluppatori devono gestire più progetti e cercare di capire oltre a quale pacchetto Java è il progetto a cui dovrebbe appartenere. Sono stato in progetti in cui è diventato davvero anemico e aveva un progetto che aveva solo quattro classi che implementavano una funzionalità solo perché questa è la direzione architettonica. Questo era anche prima che Maven fosse popolare, quindi i percorsi di classe e ciò che non è necessario impostare su entrambi gli script IDE e Ant.

L'altro motivo è che avresti più parti mobili da gestire in termini di scavo dei file e probabilmente avrai degli spaghetti dipendenti prima che tu lo sappia.

Il refactoring è anche più semplice all'interno di un progetto piuttosto che in tutti i progetti.

Se il tempo di costruzione è un problema, fornisci un hardware migliore.

    
risposta data 29.04.2017 - 16:18
fonte

Leggi altre domande sui tag