2012-10-11 11 views
6

Sto tentando di modellare i prodotti con una serie di attributi completi. Di solito un negozio online usa una descrizione testuale per elencare gli attributi di un prodotto specifico. Tuttavia, questa soluzione non è ottimale.Alternative a una gerarchia di ereditarietà profonda?

Per esempio, i seguenti collegamenti mostrano le incongruenze di attributi all'interno di un testo descrittivo per lo stesso prodotto, ma con diversi produttori:

Pertanto, ho optato per una gerarchia ereditaria come segue:

Product>Component>GraphicsCard>NvidiaGraphicsCard

La ragione di questo è perché voglio il controllo a grana fine nel corso degli attributi di ogni Product. Ciò mi consente di includere attributi specifici per dire un NvidiaGraphicsCard che non sono applicabili a uno ATiGraphicsCard.

Si noti che, oltre all'aggiunta di ulteriori campi alle sottoclassi, l'ereditarietà mi consente di utilizzare il polimorfismo in termini di avere un OrderItem in possesso di un riferimento a un Product. Questo è un motivo per cui ho escluso la composizione.

C'è un problema ad avere una gerarchia di ereditarietà così profonda, e in tal caso ci sono soluzioni o forse schemi per gestire questo problema?

risposta

8

Le gerarchie di ereditarietà profonda sono problematiche nel contesto di DDD e ORM per alcuni motivi. Un problema sorge quando si tenta di definire l'identità di un'entità. A Product deve essere paragonabile ad altri prodotti basati sull'identità, indipendentemente da quale sottoclasse viene confrontata. Questa funzionalità può essere fornita nella classe Product, ma occorre fare attenzione per garantire che anche le sottoclassi possano essere confrontate e che ci siano alcuni trucchi. Ad esempio, NHibernate genererà un proxy per le classi, in modo che il tipo di runtime effettivo dell'oggetto non sia NvidiaGraphicsCard ma un proxy che ne erediti. Mentre un'istanza transitoria di NvidiaGraphicsCard non sarà un proxy. Ciò significa che non puoi confrontarli in base al tipo.

Un'altra difficoltà è nella configurazione dei mapping ORM per supportare l'ereditarietà. Mentre la maggior parte degli ORM lo consente, il mapping risultante e gli SQL generati sono spesso complessi. Memorizza tutte le sottoclassi in un'unica tabella? In più tabelle con chiavi esterne a una tabella di prodotto comune? Nel primo si finisce con un tavolo enorme. In quest'ultimo caso le tue query ne risentiranno poiché tutte le tabelle della sottoclasse dovranno essere unite. C'è solo troppa discrepanza tra il modello relazionale e il modello dell'oggetto. Evento se si utilizza un database di documenti, è preferibile favorire la composizione sull'ereditarietà.

Invece, vorrei andare per avere una singola classe Product, che può essere composta da descrittori specifici del prodotto, o un dizionario di attributi. Questo sarebbe un OrderItem per fare riferimento a un Product senza conoscere il tipo di prodotto specifico - non c'è bisogno di polimorfismo. Ciò renderebbe anche più semplice la concessione di nuovi tipi di prodotti, senza la necessità di creare una nuova sottoclasse.

1

È un esempio di eredità scolastica, un buon esempio. Non vedo nulla di sbagliato in tale modello, tranne che persistere nel database relazionale sarà difficile.

D'altra parte, a volte un gruppo di proprietà è pertinente solo a un sottoinsieme di elementi che non possono essere espressi tramite ereditarietà singola. Per esempio. PowerConsumption che descrive la quantità di energia fornita per le esigenze del prodotto non è rilevante per mouse e chiavette USB. Anche il peso non è molto importante per alcuni componenti. Ciò significa che potresti studiare le lingue che hanno tratti, come Scala, per rendere i tuoi modelli più asciutti possibile.

Si noti che non vi è alcuna penalità di prestazioni dell'ereditarietà profonda: una catena di ereditarietà più lunga non significa chiamate di metodo virtuali più lente (beh, non si useranno molto le chiamate virtuali poiché si tratta solo di contenitori di dati).

0

Ti consiglierei di guardare il motivo Decoratore. In questo modo avrai tutto ciò di cui hai bisogno e meno di un miliardo di classi.