2012-12-15 8 views
7

devo enum CarBrand:Come organizzare correttamente la struttura di due enumerazioni con relazione molti a molti tra loro in termini di architettura e classi dell'applicazione?

public enum CarBrand { 
    BMW, MERCEDES, VOLKSWAGEN, AUDI, FORD, OPEL 
} 

e enum CarBodyType:

public enum CarBodyType { 
    SEDAN, MINIVAN, VAN 
} 

rapporto tra loro è molti a molti. Cioè un marchio automobilistico può avere diverse varianti di tipo di carrozzeria, e un tipo di carrozzeria ha diverse marche.

Come definire un tale modello di relazione entità nel mio codice con queste enumerazioni?

Forse ho bisogno di fare campo in ogni enum come un set parametrizzato da un'altra enumerazione?

public enum CarBrand { 
    BMW, MERCEDES, VOLKSWAGEN, AUDI, FORD, OPEL; 

    private Set<CarBodyType> bodyTypes;   

    public Set<CarBodyType> getBodyTypes() { 
     return bodyTypes; 
    } 

    public void setBodyTypes(Set<CarBodyType> bodyTypes) { 
     this.bodyTypes = bodyTypes; 
    } 
} 

e

public enum CarBodyType { 
    SEDAN, MINIVAN, VAN; 

    private Set<CarBrand> brands; 

    // getter and setter 
} 

questa è una buona soluzione? O sarebbe meglio implementare tali relazioni tramite una terza entità di giunzione? Se sì, quale dovrebbe essere? Come dovrebbe essere progettata questa entità e quali campi dovrebbe contenere?

risposta

4

Non è quasi certamente vero che un tipo di corpo "ha un" marchio. Molto probabilmente non è vero che un marchio "ha un" tipo di corpo. Ciò che è più probabile che si desideri modellare è un insieme separato dell'intersezione dei tipi di corpo ammissibili di ciascun marchio.

Questo è molto probabilmente desidera un Vehicle, che ha un corpo-tipo e un marchio:

public class Vehicle 
{ 
    private CarBrand brand; 
    private CarBodyType body; 
    ... 
} 

e creare Mezzi di ciascuna delle quali modello di una combinazione.

In risposta al commento

Per esempio per quanto riguarda this case? Se Book and Author sono enumerati.

Non penso che l'esempio di libro/autore funzioni per enumerazioni (e forse il tuo uso delle enumerazioni è il cuore del problema). Il numero di libri e autori è a tempo indeterminato; non modellerai né i libri né gli autori usando una enumerazione chiusa. Inoltre, è vero che ogni libro ha uno o più autori, mentre ogni autore è solo un autore nel contesto di aver scritto uno o più libri (altrimenti sono semplicemente una persona che aspira ad essere un autore).

Nella modellazione relazionale di libri e gli autori si avrebbe un tavolo Book, un tavolo e un tavolo Author relazione separata di BookAuthor che era una congiunzione di chiavi esterne alle tabelle Book e Author. Nei termini dell'oggetto cambia la parola "tabella" in "oggetto", anche se in un modello a oggetti probabilmente sostituirai la "tabella" BookAuthor con un set di autori in ogni libro e/o un insieme di libri in ciascun autore.

+0

@Bhesh: Tranne che Minivan e un furgone non sono auto ... ho usato il veicolo per evidenziarlo all'OP. Quello che penso sia sbagliato a quel livello è il suo uso di "Car". –

+0

Grazie! Questa è solo una soluzione? È sempre necessario creare un'entità terza giunzione? O sto semplicemente scegliendo il miglior campione? Ad esempio, che dire di [questo caso] (http://en.wikipedia.org/wiki/Many-to-many_ (data_model))? Se 'Book' e' Author' sono enumerati. La tua soluzione è comune e attuale anche per questo esempio? O è solo per la mia situazione specifica? –

0

Non è consigliabile disporre di dipendenze circolari come questa.

Se è necessario mantenere tale relazione, tenerlo in una classe separata, che evita le circolarità.

0

Quindi la classe CarBrand sembra essere una struttura più complicata di Enum. Può essere ancora un tipo di valore con una sorta di mappa dell'identità all'interno però:

class CarBrand { 

    static Set<CarBrand> AllBrands; //replacement for CarBrand enum 
    static Set<CarBodyType> GetTypes(CarBrand brand) { /* search this.AllBrands here */} 
    static Set<CarBrand> GetBrands(CarBodyType type) { /* search this.AllBrands here */} 

    /*specify types per brand */ 
    Set<CarBodyType> bodyTypes; 
} 

Se si preferisce andare avanti con CarBrand enum, questo può essere fatto anche come una struttura rapporto terza esplicita. Introdurre classe di associazione:

class CarBrandTypePair { 
    CarBrand, CarBodyType, 
} 

e il resto dovrebbe essere la parte statica del CarBrand esempio sopra.

Il primo modo è più estensibile probabilmente: in futuro si aggiungerà lo specifico di un altro marchio. Con il secondo approccio aggiungerebbe associazioni sempre più semplici.

Problemi correlati