W perspektywie DDD Category
, Product
i Property
są bytami: wszystkie odpowiadają obiektom, które mają własną tożsamość.
Opcja 1: twój oryginalny projekt
Zrobiłeś Category
korzeń jednego agregatu. Z jednej strony ma to sens, ponieważ łączna zapewnia spójność, gdy jej cele zostały zmodyfikowane, i Product
musi mieć Properties
ITS Category
:
Ale z drugiej strony pojedynczy agregat oznacza, że wszystkie jego obiekty są powiązane z katalogiem głównym, który jest ich właścicielem, a wszystkie odniesienia zewnętrzne muszą być dokonywane za pośrednictwem tego agregatu. To daje do zrozumienia ze:
- jeden konkretny
Product
należy do jednego i tylko jednego Category
. Jeśli Category
zostanie usunięty, to i jego Products
.
- określony
Property
należy do jednego i tylko jednego Category
. Innymi słowy, jeśli „ekrany telewizyjne” i „monitory komputerowe” byłyby dwiema kategoriami, „ekrany telewizyjne: rozmiar” i „monitory komputerowe: rozmiar” miałyby dwie różne właściwości.
Drugi punkt nie odpowiada twojej narracji: „ Ale co powinienem zrobić, gdy muszę tylko dodać nowy Property
, który nie należy do żadnej kategorii ”. I nie jest jasne, czy to samo Properties
można zastosować w inny sposób Categories
.
Opcja 2: Nieruchomość poza agregatem
Jeśli Property
istnieje niezależnie od Categories
, musi znajdować się poza agregatem. I to samo, jeśli chcesz dzielić Properties
między Categories
(co ma sens dla wysokości, szerokości, rozmiarów itp.). Wydaje się, że tak właśnie jest.
Konsekwencją jest powiązanie między Property
rzeczami, które należą do agregatu: podczas gdy możesz nawigować z wnętrza agregatu do Property
, nie możesz już przechodzić bezpośrednio od a Property
do odpowiednich wartości. To ograniczenie żeglowności może być pokazane na diagramie UML:
Zauważ, że ten projekt nie przeszkadza ci List<Property>
w Category
tworzeniu semantycznej referencji (np. Java): każda referencja na liście odnosi się do Property
obiektu, który można współdzielić w repozytorium.
Jedynym problemem związanym z tym projektem jest to, że można go zmienić Property
lub usunąć: ponieważ jest on poza agregatem, agregat nie może zadbać o spójność jego niezmienników. Ale to nie jest problem. Jest to konsekwencja zasad DDD i złożoności świata rzeczywistego. Oto cytat Erica Evansa z jego przełomowej książki „ Domain-Driven Design: Tackling Complexity in the Heart of Software ”:
Żadna reguła, która obejmuje AGREGATY , nie będzie zawsze aktualna. Dzięki przetwarzaniu zdarzeń, przetwarzaniu wsadowemu lub innym mechanizmom aktualizacji inne zależności można rozwiązać w określonym czasie. Jednak niezmienniki zastosowane w AGREGANCIE będą egzekwowane po zakończeniu każdej transakcji.
Tak więc, jeśli zmienisz a Property
, będziesz musiał upewnić się, że usługa sprawdza kategorie, które jej dotyczą, są aktualizowane w razie potrzeby.
Opcja 3: kategoria, właściwość i produkt w różnych agregatach
Zastanawiam się tylko, czy założenie, że Product
należy do singla, Category
jest uzasadnione:
- Często widzę sklepy internetowe proponujące jeden
Product
pod kilkoma Categories
. Na przykład „Laptop Marka X Model Y” można znaleźć w kategorii „Laptopy” i kategoria „Komputery”, a „drukarka wielofunkcyjna Z” w kategorii „drukarka”, „skaner” i „faks”.
- Czy nie jest możliwe, że ktoś utworzy
Product
pierwszy, a dopiero później przypisze go do kategorii i wypełni wartości?
- Jeśli chcesz podzielić kategorię, czy naprawdę usunąłbyś jej Produkty, a następnie odtworzyłeś je w nowych kategoriach?
Nie uprości to agregacji, a będziesz mieć jeszcze więcej reguł, które obejmują agregaty. Ale twój system byłby o wiele bardziej odporny na przyszłość.