Operacje na encjach niebędących korzeniami

Odpowiedz Nowy wątek
2019-09-05 17:07

Rejestracja: 2 lata temu

Ostatnio: 1 dzień temu

0

Dalej dla nauki piszę tego mojego CRUDa, wykorzystując wzorce z DDD. Postanowiłem, że jak już zacząłem, to już skończę. Pojawił się znowu problem natury filozoficznej. W tej mojej aplikacji klient może oceniać produkty, ale też zmieniać dokonane oceny. I tu pytanie: jak te zmiany zrealizować?
Opcja 1:

// gdzieś w warstwie aplikacji
// metoda SetStars encji ProductRate jest oznaczona jako internal i wywoływana przez AR Product
product.ChangeRate(_identity.GetCurrentUserId(), stars)

Opcja 2:

// gdzieś w warstwie aplikacji
// metoda SetStars jest publiczna
var rate = product.Rates.SingleOrDefault(r => r.CustomerId == _identity.GetCurrentUserId())
if (rate is null)
    // zrób coś
rate.SetStars(stars)
edytowany 1x, ostatnio: nobody01, 2019-09-05 17:08

Pozostało 580 znaków

2019-09-05 19:02

Rejestracja: 6 lat temu

Ostatnio: 10 godzin temu

Lokalizacja: Londyn

2
  1. CRUD i DDD nie powinny iść w parze. Rozumiem, że to dla nauki DDD, więc w sumie OK. Banalny przykład, żeby się uczyć.
  2. Po to masz aggregate root/korzeń, żeby pilnował spójności danych (ang. transactional boundary). Pomaga też, posiadanie metod które mają znaczenie biznesowe. Wtedy wiesz po co ta metoda istnieje. Wzbogaca to czytelność kodu. Także nie, nie możesz użyć drugiego podejścia. Wtedy szlag trafia enkapsulacje. Co nie tylko nie jest "fajne" w DDD ale także w OOP.
  3. Masz dwie biznesowe operacje: Dodanie oceny i Zmiana oceny. Jeśli się da - rozbij je na osobne metody w domenie, a także osobne endpointy w API.

Pozostało 580 znaków

2019-09-05 19:50

Rejestracja: 17 lat temu

Ostatnio: 5 godzin temu

Lokalizacja: Kraków

1

W ogóle bym się zastanowił czy z ocen nie zrobić AR, w teorii zawsze powinniśmy wczytywać całego AR do pamięci razem z jego zależnościami (to jest miejsce w którym lazy loading się przydaje). A więc jeśli nasz produkt ma tysiące ocen, to za każdym razem będziemy musieli je wszystkie załadować. To nie będzie przyjemne ze względu wydajnościowego, a w ddd wydajność również jest ważna jak wiemy z niebieskiej książki, także lepiej zrobić z produktu i z ocen oddzielne AR.

AR powinny być małe, jeśli zawartość jakiegoś AR może być duża i szybko rosnąć, to najlepiej go podzielić.


It's easy to hate code you didn't write, without an understanding of the context in which it was written.
edytowany 2x, ostatnio: neves, 2019-09-05 19:57
Tip: Jak masz AR i używasz Lazy Loadingu, to jest dobry moment żeby się zastanowić czy AR nie jest za duży i nie warto go rozbić. Może być tak, że są niewydzielone bounded contexty. Ozzywiście, może się okazać że wsio OK, albo "nie warto". - AreQrm 2019-09-06 14:12

Pozostało 580 znaków

2019-09-05 19:51

Rejestracja: 2 lata temu

Ostatnio: 1 dzień temu

0

Wybierajac pierwsze podejscie, powinienem oznaczyc metode SetStars encji ProductRate jako internal, zeby nie wypuscic jej z warstwy domeny. Jesli wiec podziele projekt na moduly, to bede musial tez podzielic kazdy z tych modulow na kilka projektow, z ktorych kazdy bedzie odpowiadal logicznie jednej z warstw. Tak?

Pozostało 580 znaków

2019-09-05 20:00

Rejestracja: 2 lata temu

Ostatnio: 1 dzień temu

0

@neves Wydawalo mi sie, ze o tym, czy encja powinna byc korzeniem, mozna zdecydowac, patrzac na to, czy moze byc potrzebna bezposrednio z innych agregatow. Skoro ze wzgledow wydajnosciowych odpowiedz nie zawsze jest tak prosta, tak wiec czym sie kierowac?

Pozostało 580 znaków

2019-09-05 20:24

Rejestracja: 17 lat temu

Ostatnio: 5 godzin temu

Lokalizacja: Kraków

i dostępnością, i tym żeby agregat był mały, i spójnością, i wydajnoscią, i innymi rzeczami też :D, polecam te trzy krótkie artykuły, powinny sporo wyjaśnić:
Effective Aggregate Design Part I
Effective Aggregate Design Part II
Effective Aggregate Design Part III


It's easy to hate code you didn't write, without an understanding of the context in which it was written.
edytowany 1x, ostatnio: neves, 2019-09-05 20:26

Pozostało 580 znaków

2019-09-05 20:49

Rejestracja: 12 lat temu

Ostatnio: 4 godziny temu

0

Produkt może być agregatem, skoro możesz go ocenić. Natomiast jeśli masz agregat Zamówienie, które ma w sobie encje Produkt, to powinny to być „snapshoty” produktów bez ocen. Widać wyraźnie, że masz kontekst Zamówień i Katalogu Produktów. Pomyśl sobie o cyklu życia takiego produktu - najpierw jest on Produktem w jakimś katalogu produktów, a później jest pozycja zamówienie - to 2 różne byty.


IT mikromenadżer
edytowany 4x, ostatnio: Charles_Ray, 2019-09-05 21:22

Pozostało 580 znaków

Odpowiedz

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0