2012-10-11 18 views
6

Próbuję modelować produkty za pomocą zestawu kompleksowych atrybutów. Zwykle sklep internetowy używałby opisu tekstowego do listy atrybutów konkretnego produktu. Jednak to rozwiązanie nie jest optymalne.Alternatywy dla hierarchii głębokiego dziedziczenia?

Na przykład, poniższe linki pokazują niespójności atrybutów w opisie tekst na ten sam produkt, ale z różnych producentów:

W związku z tym wybrałem hierarchię dziedziczenia w następujący sposób:

Product>Component>GraphicsCard>NvidiaGraphicsCard

Powodem tego jest, ponieważ chcę precyzyjną kontrolę nad atrybutami każdego Product. To pozwala mi uwzględnić atrybuty specyficzne dla np. NvidiaGraphicsCard, które nie mają zastosowania do ATiGraphicsCard.

Należy zauważyć, że dziedziczenie pozwala, oprócz dodawania kolejnych pól do podklas, wykorzystywać polimorfizm pod względem posiadania OrderItem posiadania odniesienia do . To jest powód, dla którego wykluczyłem kompozycję.

Czy istnieje problem z posiadaniem tak głębokiej hierarchii dziedziczenia, a jeśli tak, to czy istnieją jakieś rozwiązania lub wzorce, aby poradzić sobie z tym problemem?

Odpowiedz

8

Hierarchie głębokich dziedzin są problematyczne w kontekście DDD i ORM z kilku powodów. Jeden problem powstaje, gdy próbujesz zdefiniować tożsamość jednostki. Numer Product musi być porównywalny z innymi produktami opartymi na tożsamości, niezależnie od tego, która z podklas jest porównywana. Ta funkcjonalność może być zapewniona w klasie Product, ale należy zachować ostrożność, aby upewnić się, że podklasy mogą być również porównywane i jest kilka kuponów. Na przykład NHibernate wygeneruje proxy dla klas, więc rzeczywisty typ środowiska wykonawczego obiektu nie będzie NvidiaGraphicsCard, ale dziedziczy po nim serwer proxy. O ile przejściowa instancja o numerze NvidiaGraphicsCard nie będzie serwerem proxy. Oznacza to, że nie można ich porównywać na podstawie typu.

Inną trudność stanowi konfigurowanie odwzorowań ORM do obsługi dziedziczenia. Podczas gdy większość ORM pozwala na to, wynikowe mapowanie i generowane zapytania SQL są często złożone. Czy przechowujesz wszystkie podklasy w jednej tabeli? W wielu tabelach z obcymi kluczami do wspólnej tabeli produktów? W tym pierwszym znajduje się ogromny stół. W tym drugim przypadku twoje kwerendy będą cierpieć, ponieważ wszystkie tabele podklasy będą musiały zostać połączone. Występuje zbyt duże niedopasowanie impedancji między modelem relacyjnym a modelem obiektu. Zdarzenie w przypadku korzystania z bazy danych dokumentów najlepiej faworyzować kompozycję ponad dziedziczenie.

Zamiast tego chciałbym wybrać jedną klasę Product, która może składać się z deskryptorów specyficznych dla produktu lub ze słownika atrybutów. Byłoby to OrderItem w odniesieniu do Product bez znajomości konkretnego typu produktu - bez potrzeby polimorfizmu. Ułatwiłoby to również wprowadzanie nowych typów produktów - nie ma potrzeby tworzenia nowej podklasy.

1

To przykład szkolnego przykładu dziedziczenia, dobry przykład. Nie widzę w tym modelu nic złego, z tym, że utrzymywanie go w relacyjnej bazie danych będzie trudne.

Z drugiej strony czasami grupa właściwości ma znaczenie tylko dla podzbioru pozycji, których nie można wyrazić za pomocą pojedynczego dziedziczenia. Na przykład. PowerConsumption opisujące, ile mocy podanej w danym produkcie nie ma znaczenia dla myszy i pamięci USB. Również waga niektórych elementów nie jest tak ważna. Oznacza to, że możesz badać języki posiadające cechy, takie jak Scala, aby Twoje modele były jak najbardziej suche.

Należy zauważyć, że nie ma kary za wydajność głębokiego dziedziczenia - dłuższy łańcuch dziedziczenia nie oznacza wolniejszych wywołań metod wirtualnych (cóż, nie będziesz często używać wywołań wirtualnych, ponieważ są to tylko pojemniki danych).

0

Radziłbym Ci spojrzeć na wzór dekoratora. W ten sposób uzyskasz dowolną finezję, której potrzebujesz i mniej niż miliard klas.