Co należy do korzenia agregatu

Jest to praktyczne pytanie projektowe oparte na domenie:

Koncepcyjnie, myślę, że mam zagregowane korzenie, dopóki nie zdefiniuję jednego.

Mam podmiot pracowniczy, który pojawił się jako zagregowany korzeń. W biznesie, niektórzy pracownicy mogą mieć zarejestrowane naruszenia związane z pracą:

Pracownik - - - - - * ]}

Ponieważ nie wszyscy pracownicy podlegają temu, myślę, że naruszenia nie będą częścią pracownika / Align = "left" /

Więc kiedy chcę pracować z pracownikami i związanymi z nimi naruszeniami, czy to są dwie oddzielne interakcje repozytorium przez jakiś serwis?

Wreszcie, kiedy dodam naruszenie, czy taka metoda dotyczy podmiotu pracowniczego? Dzięki za pomoc!

Author: jlembke, 2009-05-07

7 answers

Po zrobieniu jeszcze więcej badań, myślę, że mam odpowiedź na moje pytanie.

Paul Stovell miał tę lekko edytowaną odpowiedź na podobne pytanie na DDD messageboard . Zamień "klient" na "pracownik", a "zamówienie" na "naruszenie" i masz pomysł.

Just because Customer reference Order niekoniecznie oznacza spadek porządku w korzeniu klienta. Adresy klientów mogą, ale zamówienia mogą być niezależne (dla przykład, możesz mieć usługę, która przetwarza wszystkie nowe zamówienia bez względu na to, kto klient jest. Muszę iść Klient- > zamówienia nie mają sensu w ten scenariusz).

Z punktu widzenia domeny, można nawet kwestionować ważność tych Referencje (klient ma odniesienie do lista rozkazów). Jak często będziesz faktycznie potrzebne wszystkie zamówienia na klient? W niektórych systemach sprawia, że sens, ale w innych, jeden klient może złożyć wiele zamówień. Szanse są chcesz zamówić dla Klienta między zakres dat, czyli zamówienia dla klienta które nie są jeszcze przetwarzane lub zamówienia które nie zostały opłacone i tak dalej. Scenariusz, w którym będziesz potrzebował wszystkich z nich mogą być stosunkowo rzadkie. Jest jednak znacznie bardziej prawdopodobne, że w przypadku realizacji zamówienia, będziesz chcesz informacji o kliencie. Więc w kod, Order.Customer.Name jest przydatny, ale Customer.Orders[0].LineItem.SKU - prawdopodobnie nie tak przydatne. Oczywiście., to całkowicie zależy od Twojej firmy domena.

Innymi słowy, aktualizacja klienta nie ma nic wspólnego z aktualizacją zamówień. A zamówienia lub naruszenia w moim przypadku mogą być rozpatrywane niezależnie od klientów / pracowników.

Jeśli naruszenia miały linie szczegółowe, wówczas naruszenia i naruszenia będą częścią tego samego agregatu, ponieważ zmiana linii naruszenia prawdopodobnie wpłynie na naruszenie.

Edytuj** Problem w mojej domenie polega na tym, że naruszenia nie mają żadnego zachowania. Są one w zasadzie zapisy zdarzeń, które się wydarzyły. Jeszcze nie wiem, jakie to ma konsekwencje.

 25
Author: jlembke,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-08 20:00:37

Domain-Driven Design: Tackling the Complexity in the Heart of Software ,

Agregat jest zbiorem powiązanych obiektów, które traktujemy jako jednostkę w celu zmiany danych .

Są tu 2 ważne punkty:

  1. obiekty te powinny być traktowane jako "jednostka".
  2. w celu "zmiany danych".

Wierzę w twój scenariusz, pracownik i naruszenie nie są koniecznie jednostki razem, natomiast w przykładzie Order i OrderItem, są one częścią jednej jednostki.

Inną rzeczą, która jest ważna podczas modelowania granic aggregate, jest to, czy masz jakieś niezmienniki w swoim agregacie. Niezmienniki to reguły biznesowe, które powinny obowiązywać w ramach" całego " agregatu. Na przykład, jeśli chodzi o Przykład Order i OrderItem, możesz mieć niezmiennik, który mówi, że całkowity koszt zamówienia powinien być mniejszy niż predefiniowana kwota. W tym w przypadku, gdy chcesz dodać OrderItem do zamówienia, ten niezmiennik powinien być egzekwowany, aby upewnić się, że Twoje zamówienie jest ważne. Jednak w Twoim problemie nie widzę żadnych niezmienników między twoimi bytami: pracownik i naruszenie.

Tak krótka odpowiedź:

Uważam, że każdy pracownik i naruszenie należą do 2 oddzielnych agregatów. Każdy z tych Bytów jest także ich własnym zagregowanym korzeniem. Potrzebujesz więc 2 repozytoriów: EmployeeRepository i ViolationRepository.

Ja również uważam, że powinieneś mieć jednokierunkowy związek od naruszenia do pracownika. W ten sposób każdy obiekt naruszenia wie, do kogo należy. Ale jeśli chcesz uzyskać listę wszystkich naruszeń dla konkretnego pracownika, możesz zapytać ViolationRepository:

var list = repository.FindAllViolationsByEmployee(someEmployee);
 21
Author: Mosh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-06 16:38:31

Mówisz, że masz podmiot pracowniczy i naruszenia, a każde naruszenie nie ma żadnego zachowania. Z tego co mogę przeczytać powyżej, wydaje mi się, że możesz mieć dwa zagregowane korzenie:

  • pracownik
  • EmployeeViolations (nazwij to EmployeeViolationCard lub EmployeeViolationRecords)

EmployeeViolations jest identyfikowany za pomocą tego samego identyfikatora pracowniczego i przechowuje zbiór przedmiotów naruszenia. Zachowanie pracownika i naruszenia są rozdzielone w ten sposób i nie dostajesz naruszenia bez zachowania.

Czy naruszenie jest encją czy obiektem wartości, należy zdecydować na podstawie jego właściwości.

 2
Author: Yuriy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-08 09:53:50

Generalnie zgadzam się z Moshem w tej kwestii. Należy jednak pamiętać o pojęciu transakcji z punktu widzenia biznesu. Tak więc "w celu zmiany danych" Rozumiem "w celu transakcji(transakcji)".

Repozytoria są widokami modelu domeny. W środowisku domenowym te "widoki" naprawdę wspierają lub reprezentują funkcję lub zdolność biznesową - transakcję. Przypadku, pracownik może mieć jedno lub więcej naruszeń, a jeśli tak, są aspekty transakcja(transakcje) w danym momencie. Rozważ swoje przypadki użycia.

Scenariusz: "pracownik popełnia czyn, który jest naruszeniem miejsca pracy."Jest to rodzaj zdarzenia biznesowego (tj. transakcja lub część większej, być może rozproszonej transakcji), które miało miejsce. Obiekt domeny dotkniętej rootem rzeczywiście można zobaczyć z więcej niż jednej perspektywy, dlatego jest to mylące. Ale rzeczą do zapamiętania jest zachowanie, ponieważ odnosi się do transakcji biznesowych, ponieważ chcesz swój biznes procesy, aby modelować świat rzeczywisty tak dokładnie, jak to możliwe. Jeśli chodzi o relacje, podobnie jak w relacyjnej bazie danych, twój konceptualny model domeny powinien już o tym wskazywać( np. asocjacyjność), co często można odczytać w obu kierunkach:

Pracownik naruszenie

Więc w tym przypadku użycia, byłoby sprawiedliwe, aby powiedzieć, że jest to transakcja zajmująca się naruszeniami, i że główny-lub" główny " podmiot-jest Naruszenie. To będzie twój zagregowany korzeń, który odwołasz się do tej konkretnej działalności biznesowej lub procesu biznesowego. Ale nie oznacza to, że dla innej działalności lub procesu nie można mieć korzenia Agregującego pracownika, takiego jak "nowy proces pracownika". Jeśli zachowasz ostrożność, nie powinno być negatywnego wpływu cyklicznych odniesień lub możliwości przechodzenia modelu domeny na wiele sposobów. Ostrzegam jednak, że rządzenie tym powinno być przemyślane i obsługiwane przez część kontrolera Twojej domeny biznesowej lub jakikolwiek jej odpowiednik.

Pomijając: myśląc w kategoriach wzorców (np. MVC), repozytorium jest widokiem, obiekty domeny są modelem, a zatem należy również zastosować jakąś formę wzorca kontrolera. Zazwyczaj kontroler deklaruje konkretną realizację i dostęp do repozytoriów (zbiorów zagregowanych korzeni).

W świecie dostępu do danych...

Używając LINQ-to-SQL jako przykładu, DataContext będzie kontrolerem wyświetlającym Widok klientów i podmiotów zamawiających. Widok jest nieeklaratywnym, zorientowanym na framework typem tabeli (przybliżony odpowiednik repozytorium). Zauważ, że widok zachowuje odniesienie do kontrolera nadrzędnego i często przechodzi przez kontroler, aby kontrolować, jak / kiedy Widok zostanie zmaterializowany. Tak więc Sterownik jest Twoim dostawcą, dbając o mapowanie, tłumaczenie, nawodnienie obiektów itp. Model jest wtedy Twoje dane POCOs. Raczej typowy MVC wzór.

Używając N / Hibernate jako przykładu, ISession będzie kontrolerem odsłaniającym Widok klientów i zleceń poprzez sesję.Enumerable (string query) lub session.Get (object id) lub session.CreateCriteria (typeof(Klient)).List ()

W świecie logiki biznesu...
Customer { /*...*/ }

Employee { /*...*/ }

Repository<T> : IRepository<T>
              , IEnumerable<T>
              //, IQueryable<T>, IQueryProvider //optional

{ /**/ }

BusinessController {
 Repository<Customer>  Customers { get{ /*...*/ }} //aggregate root
 Repository<Order> Orders { get{ /*...*/ }} // aggregate root
}

W skrócie, pozwól procesom biznesowym i transakcjom być przewodnikiem, a twoja Infrastruktura biznesowa naturalnie ewoluuje w miarę wdrażania procesów/działań lub refakturowane. Co więcej, preferuj kompozytowość w porównaniu z tradycyjnym wzornictwem czarnej skrzynki. Kiedy dojdziesz do usług zorientowanych lub cloud computing, będziesz zadowolony, że to zrobiłeś. :)

 1
Author: Timex,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-05-25 01:17:52

Zastanawiałem się, jaki byłby wniosek?

'naruszenia' stają się istotą root. A "naruszenia" byłyby przywoływane przez "pracowniczą" jednostkę root. repozytorium naruszeń ie repozytorium pracowników

Ale jesteś przekonany o tym, że naruszenia są istotą root, ponieważ nie mają żadnego zachowania.

Ale czy "zachowanie" jest kryterium kwalifikującym się jako podmiot root? Nie sądzę.

 0
Author: Sanjay,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-15 13:47:02

Lekko ortogonalne pytanie, aby sprawdzić zrozumienie tutaj, wracając do porządku...Przykład OrderItem, może być moduł analityczny w systemie, który chce spojrzeć na OrderItems bezpośrednio tj. uzyskać wszystkie orderItems dla danego produktu lub wszystkie pozycje zamówienia większe niż jakaś podana wartość itp., czy mając wiele takich przypadków użycia i prowadząc "agregatowy korzeń" do ekstremum, czy moglibyśmy argumentować, że OrderItem jest innym zbiorczym korzeniem samym w sobie ??

 0
Author: redzedi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-22 10:26:31

To zależy. Czy jakakolwiek zmiana/dodanie / usunięcie wioation zmienia jakąkolwiek część pracownika - np. czy przechowujesz liczbę naruszeń lub liczbę naruszeń w ciągu ostatnich 3 lat przeciwko pracownikowi?

 0
Author: Chalky,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-21 08:46:10