Come risolvere le dipendenze dei pacchetti circolari


11

Sto refactoring di una base di codice di grandi dimensioni in cui la maggior parte delle classi si trova in un unico pacchetto. Per una migliore modularità, sto creando pacchetti secondari per ciascuna funzionalità.

Ricordo di aver appreso da qualche parte che un grafico di dipendenza del pacchetto non dovrebbe avere loop, ma non so come risolvere il seguente problema: Figureè nel pacchetto figure, Layoutè nel pacchetto layout, Layoutrichiede la figura per eseguire il layout, quindi il pacchetto layoutdipende dal pacchetto figure. D'altra parte, a Figurepuò contenere Figureal suo interno altre s, che ne hanno le proprie Layout, il che rende il pacchetto figuredipendente dal pacchetto layout.

Ho pensato ad alcune soluzioni, come la creazione di Containerun'interfaccia che Figureimplementa e la mette nel Layoutpacchetto. È una buona soluzione? Altre possibilità?

Grazie


Si tratta di moduli (ad esempio diversi vasetti) non possono avere dipendenze circolari. I pacchetti POSSONO e spesso HANNO dipendenze circolari, purché appartengano allo stesso modulo.
Loro,

@lorus Quindi questo non è un problema di progettazione?
vainolo,

2
No non lo è. I pacchetti sono normalmente solo spazi dei nomi, che possono cambiare solo quando utilizzati per qualcos'altro, ad esempio per cambiare la visibilità dei loro contenuti nell'ambiente OSGi. Non preoccuparti altrimenti.
Loro,

1
Nota che molte autorità condannano le dipendenze cicliche, e talvolta con una buona ragione, ma prima di fare un cieco refactoring, dovresti assicurarti che uno di questi motivi si applichi effettivamente a te. Se la struttura del pacchetto non ti dà problemi e non puoi, in buona coscienza, capire perché, in futuro, non cambierebbe qualcosa di così fondamentale solo per soddisfare i valori architettonici astratti.
Kilian Foth,

Risposte:


9

Dovresti pensare a Inversion of Control

Fondamentalmente definisci un'interfaccia per la tua Layoutche si trova da qualche parte vicino alla tua classe Layout in un proprio pacchetto in modo da avere un pacchetto di implementazione e un pacchetto di interfaccia pubblica - per esempio chiamalo Layoutable(non so se sia l'inglese corretto). Ora - Layout non implementerà quell'interfaccia ma la Figureclasse. Allo stesso modo, creeresti un'interfaccia per Figure, Drawablead esempio.

Così

my.public.package.Layoutable
my.implementation.package.Layout
my.public.package.Drawable
my.implementation.package.Figure

Ora - Figura implementa Layoutable e quindi può essere utilizzata da Layout e (non sono ancora sicuro se è quello che volevi) - Layout implementa Drawable e può essere disegnata in una Figura. Il punto è che la classe che espone alcuni servizi lo rende disponibile tramite un'interfaccia (qui: Layout e Layoutable) - la classe che vuole usare quel servizio deve implementare l'interfaccia.

Quindi avresti qualcosa come un oggetto creatore che unisce entrambi. Quindi il creatore avrebbe una dipendenza Layoutda così come da Figure, ma Layoute Figurese stessi sarebbero indipendenti.

Questa è l'idea approssimativa.

Un'eccellente fonte di soluzioni a questi problemi è il libro Java Application Architecture di Kirk Knoernschild.


Non è la stessa Containerdell'interfaccia suggerita nella domanda?
Vaughandroid,

Sì - e no - non li metterei entrambi nello stesso pacchetto come ho affermato. E non c'era molta teoria dietro. E in questo caso non è sufficiente farlo da un lato, dovrai farlo da entrambi i lati. Tutto a posto?
michael_s,

Oops, mi sono perso un po 'nella domanda originale Containersull'andare nello stesso pacchetto di Layout. Non funzionerebbe, mentre la tua soluzione lo farebbe.
Vaughandroid,

ah - ok - mi è sembrato che mi mancasse la parte con il Container anche se mentre stavo hackerando - avrei dovuto chiamarlo Container;)
michael_s

0

Non sono troppo chiaro su cosa Figuresia, ma forse dovrebbe essere nello stesso pacchetto di Layout?

La Containersoluzione di interfaccia proposta non funzionerebbe, a meno che non si inserisse l' Containerinterfaccia in un terzo pacchetto, si avrebbe comunque una dipendenza circolare tra i due pacchetti. Vedi la risposta di michael_s per qualcosa che avrebbe funzionato.

Un'altra cosa, come altri hanno già detto, probabilmente non sarà mai un problema. In futuro incontrerai problemi solo se Figuree Layoutvuoi essere in moduli separati . Puoi affrontarlo se e quando diventa necessario, ma dato che le due classi sembrano abbastanza strettamente correlate, ciò sembra altamente improbabile.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.