2012-01-11 4 views
5

Sono un neofita dei moderni compilatori e macchine virtuali Java, quindi sono curioso, quali sono le problematiche tecniche che i grandi progetti Java (più di 5000 classi considerevoli) incontrano, durante la compilazione e durante il runtime, come il nodo gordiano delle dipendenze dei pacchetti cresce?Esistono motivi tecnici per evitare di creare dipendenze di pacchetti altamente aggrovigliati in progetti Java di grandi dimensioni?

In progetti C++ di grandi dimensioni, è possibile entrare nei problemi tecnici (tutti i problemi di manutenibilità a parte) se ci si allontana da un grafico di dipendenza aciclica della libreria (o del pacchetto) in progetti di grandi dimensioni.

Alcuni esempi

  • compilazione possono esaurire la memoria se la maggior parte di una struttura di origine è incluso
  • linking farlo anche se troppi gli archivi degli oggetti vengono inclusi (gli archivi di oggetti in genere in correlazione con i pacchetti in C++ progetti)

Il problema è considerevolmente esacerbato dall'istanziazione di template in linea. Le moderne workstation non sono in grado di compilare e collegare un progetto che estrae la maggior parte di 5000 classi di dimensioni considerevoli in entrambe le fasi della costruzione.

Gli sviluppatori Java che ho chiesto non credono che le limitazioni tecniche siano un motivo per evitare le dipendenze del pacchetto circolare (si applicano altre motivazioni). Ci sono?

+0

Indipendentemente dalle limitazioni tecniche di Java, le dipendenze dei pacchetti ciclici possono portare a un monolite. Evitarli può essere utile. –

+0

@ AndyThomas-Cramer - Che cosa è una "dipendenza del pacchetto" in Java? Non penso che ci sia una cosa del genere (per quanto riguarda il compilatore). –

+0

@TedHopp - vedi la risposta al tuo commento simile qui sotto. –

risposta

4
  1. Il compilatore Java (javac) non compila tutte le classi, allo stesso tempo, ma piuttosto ad una ad una, scoprendo in modo dinamico non compilati o stantio .class file.

  2. Nessun collegamento . Invece tutti i file .class vengono raggruppati insieme in un file jar una volta compilati. Questa è fondamentalmente una compressione ZIP e questo passaggio non è nemmeno richiesto.

  3. Il compilatore Java è moderatamente semplice a causa della semplice sintassi e semantica del linguaggio. Non c'è molta metaprogrammazione, tipo di inferenza, ecc. Il compilatore di Scala, per esempio, è molto più lento perché il linguaggio stesso è molto più complicato.

Detto questo non riesco a trovare limitazioni tecniche di compilazione di progetti grandi e intricati. Ovviamente il tempo di costruzione cresce e una volta che supera i 10 minuti diventa un dolore, ma non è davvero un problema.

Il vero problema con i riferimenti incrociati aggrovigliati e circolari è la manutenibilità del codice sorgente. Principalmente è molto più difficile il codice refactoring. Una volta che il progetto raggiunge determinate dimensioni (5000+ classi è probabilmente circa mezzo milione di LOC) gli sviluppatori cercheranno di dividerlo in pezzi. Estrai librerie, moduli e livelli. Se le dipendenze sono così forti, questo processo è quasi impossibile.

+1

Supponi di avere A.java e B.java, senza file .class. Se la classe A dipende dall'esistenza di B.class per la compilazione e la classe B dipende dall'esistenza di A.class per la compilazione, il compilatore sta per compilarli entrambi allo stesso tempo (poiché i file .class semplicemente non possono essere generati sequenziale). Una strategia per un compilatore sarebbe quella di generare in modo incrementale i file .class: fai abbastanza di A.class per compilare B, quindi torna indietro e finisci A.class. Nel mio libro, li sta ancora compilando insieme. –

+0

Tomasz ne ha in sintesi. Non è un problema del compilatore, è una questione di buona modularità. Non metterei migliaia di linee di codice in un metodo o in migliaia di metodi in una classe. Si modularizza per rendere il codice più facile da capire da parte di uno sviluppatore umano. Per fermarsi a livello di classe non è semplicemente scalabile, hai bisogno di moduli di livello superiore. I barattoli, i bean, i bundle, ecc. Servono a questo scopo, ma quando contengono più di una quantità di classi mentali, è necessario qualcosa in mezzo, e i pacchetti sono ciò che si ha in Java. E una struttura del modulo dovrebbe essere aciclica. –

1

Non c'è davvero alcuna dipendenza da pacchetto in Java. Esistono solo dipendenze di classe (e interfaccia). Quando si importa un pacchetto in Java, si sta solo dicendo al compilatore come risolvere i nomi (quindi non è necessario qualificare completamente ogni classe o nome di importazione statica che si utilizza).

Le dipendenze circolari tra migliaia di classi portano probabilmente un compilatore in ginocchio.

+0

Questa è una dichiarazione molto forte. Esiste davvero una cosa come le dipendenze tra i pacchetti Java e esistono strumenti per visualizzarli. Si potrebbe dire che il compilatore ignora le dipendenze del pacchetto. –

+0

@ AndyThomas-Cramer - Che cos'è una dipendenza tra i pacchetti Java? Cosa lo crea? Che effetto ha? Per quanto riguarda la gerarchia dei pacchetti, non vi è alcun valore semantico per quanto riguarda il linguaggio Java; è strettamente uno strumento di gestione del codice. –

+0

Le dipendenze esistono a più granularità, tra metodi, classi, pacchetti, file jar. Alcuni sono rilevanti per il compilatore e altri no. C'è una differenza tra dire "questa dipendenza non ha alcun effetto in termini di linguaggio/compilatore" e dire "non c'è davvero niente come le dipendenze dei pacchetti". –