2009-12-26 21 views
13

C'è un modo per evitare dipendenze circolari, diversi miscelazione moduli, in una disposizione simile (è un'applicazione scacchi)come evitare dipendenze circolari qui

descrizione lunga:

  • C'è il modulo Gui che importa un modulo ChessWidget;
  • ChessWidget semplicemente avvolge il modulo ChessWorld e importa CellButton;
  • Il modulo CellButton importa il modulo Cell;
  • Il modulo ChessWorld importa Board (per rappresentarlo) e Players (per avvisare e recuperare le loro mosse);
  • Il modulo Board importa il modulo Piece;
  • Il modulo Piece importa modulo Player;

E qui è il problema:

Il modulo Player ha bisogno di conoscere altri giocatori e il consiglio, l'importazione in tal modo ChessWorld!

Breve descrizione:

Il modulo World ha bisogno di sapere sul modulo Player (anche indirettamente da Board/Piece) e Player bisogno di conoscere World.

L'aiuto è molto apprezzato.

PS: Non è perché non posso usare le dipendenze circolari, ma perché sono malvagie.

risposta

14

Seguire la Dependency inversion principle: introdurre un'interfaccia, che ChessWorld attrezzi, e su cui Player dipende - e/o uno che Player implementa e su cui Piece dipende (uno o entrambi possono essere appropriati a seconda dettagli sulla natura del dipendenza). Questo spesso va insieme a Dependency Injection e, se il dipendente ha bisogno di istanziare dinamicamente un numero di istanza dei depenati, con Factory DP.

+0

IMHO, questo non risolve la dipendenza circolare. È ancora lì, ma gestito da un contenitore DI e liberamente accoppiato tramite interfacce. – Cohen

+7

Le dipendenze hanno una direzione, ad es. A-> B-> C-> A è circolare, ma se inverti una qualsiasi delle frecce non è più un cerchio. –

0

Sto per mettere la mia mano qui e dire ... IMHO potresti averlo sovrascritto.

Perché un pezzo deve avere conoscenza del lettore? Un pezzo negli scacchi è o nero o bianco, indipendentemente da chi lo sta controllando (giocando).

Si parla di "modulo lettore" e "modulo pezzo" - perché sono moduli separati? Perché non sono solo classi di dati (oggetti di dominio) insieme nello stesso modulo?

Se ho analizzato troppo questo o non ho capito come hai costruito il tuo gioco, allora ignori assolutamente quello che ho detto. OTOH forse ho letto le cose giusto?

+0

è perché è un sistema di varianti di scacchi, quindi può essere 2 schede 7 giocatori e regole werid – zaphnat

+0

Ahh ok, questo spiegherebbe :) – slugster

2

Considerare ciò di cui ogni oggetto ha realmente bisogno, e non quello di cui ha appena bisogno al momento.

Un pezzo probabilmente non ha bisogno di sapere di un giocatore - ciò di cui ha bisogno di sapere è qualcosa a cui è possibile inviare aggiornamenti.

Quindi, per tale esempio, creare un'interfaccia che rappresenti un "PieceMessageListener" o alcuni di essi, e farlo implementare. Ora, entrambe le concrezioni dipendono da un'astrazione (andare alla regola di "le concrezioni dovrebbero dipendere dalle astrazioni, le astrazioni non dovrebbero dipendere dalle concrezioni").

5

Penso che l'odore di una dipendenza circolare mostri di più un problema di architettura/progettazione, che non dovrebbe essere risolto da DI, late bounding, loose coupling, o qualsiasi altra forma di un ulteriore livello di astrazione. Anche se sono tutti meccanismi molto buoni, ma non risolvono il problema sottostante.

breve: penso che il ChessWorld detiene troppe responsabilità. Se li dividi, probabilmente scoprirai che le dipendenze sono le responsabilità più adatte in un modulo separato.

Spiegazione lunga: proverò a dare un esempio di come lo rifatterò, anche se è difficile perché in realtà non è il dominio del problema completo.

NOTA: non ho familiarità con Java, quindi potrei fraintendere le implicazioni dell'importazione e del wrap.

Ma mi pare di capire le dipendenze sembrano un po 'come questo:

Gui <- ChessWidget <- ChessWorld <- CellButton <- Cell 
           <- Board <- Piece <- Player 
           <- Players <- ChessWorld 

IMHO il problema è che ChessWorld contiene troppe responsabilità differenti. Mantenere la lista dei giocatori è probabilmente meglio in un modulo separato come PlayerList, RegisteredUsers o OnlineUser o qualcosa di simile. Dopo che il refactoring delle tue dipendenze cambierebbe come segue:

Gui <- ChessWidget <- ChessWorld <- CellButton <- Cell 
            <- Board <- Piece <- Player 
            <- Playerlist <- Player 

PlayerList è probabilmente qualcosa che dovresti avere nel modulo giocatore. Ora Chessworld dipende dal modulo giocatore e non dall'altra direzione.

Non sono sicuro che si adatti perfettamente alle tue intenzioni, ma sono molto interessato a discuterne, quindi per favore commenta.

+0

il problema è, comunque, quel giocatore deve sapere di bordo e anche di altri giocatori. Ho usato una soluzione alternativa per separare il pezzo e il modulo del giocatore, usando "chiavi" o ID e poi facendo un'interfaccia WorldInfo che World implementa e Player importa. In questo modo, importando Board, non imponi il pezzo. – zaphnat

Problemi correlati