Pojedyncza odpowiedzialność (powód zmiany) bytu powinna polegać na jednoznacznej identyfikacji, innymi słowy, jego odpowiedzialność musi być możliwa do odnalezienia.
Książka DDD Erica Evana, str. 93:
najbardziej podstawową odpowiedzialnością jednostek jest ustanowienie ciągłości, aby zachowanie było jasne i przewidywalne. Robią to najlepiej, jeśli są zachowani. Zamiast skupiać się na atrybutach, a nawet na zachowaniu, usuń definicję obiektu Entity do najbardziej nieodłącznych cech, szczególnie tych, które go identyfikują lub są powszechnie używane do jego znalezienia lub dopasowania. Dodaj tylko takie zachowanie, które jest niezbędne do pojęcia i atrybutów wymaganych przez to zachowanie.
Poza tym, spróbuj usunąć zachowanie i atrybuty do innych obiektów powiązanych z istotą Istotą. Poza problemami z tożsamością, Istoty mają tendencję do wypełniania swoich obowiązków poprzez koordynację operacji obiektów, których są właścicielami.
1.
... zredukuj definicję obiektu ENTITY do najbardziej nieodłącznych cech, szczególnie tych, które go identyfikują lub są powszechnie używane do jego znalezienia lub dopasowania. Dodaj tylko takie zachowanie, które jest niezbędne do koncepcji ...
Gdy jednostce zostanie przypisany unikalny identyfikator , jej tożsamość zostanie ustalona, więc zakładam, że taka jednostka nie potrzebuje żadnego zachowania, aby zachować swoją tożsamość lub pomóc w identyfikacji . Dlatego nie rozumiem, do jakiego zachowania autor odnosi się (oprócz findi match operacji ) z „ zachowaniem, które jest niezbędne dla koncepcji ”?
2)
... zredukuj definicję obiektu ENTITY do najbardziej nieodłącznych cech, szczególnie tych, które go identyfikują lub są powszechnie używane do jego znalezienia lub dopasowania. ... Poza tym, spróbuj usunąć zachowanie i atrybuty do innych obiektów powiązanych z podstawową ENTITY.
Więc każde zachowanie, które nie pomaga zidentyfikować bytu, ale nadal charakteryzowalibyśmy to zachowanie jako nieodłączną cechę tego bytu (tj. Szczekanie jest nieodłączne dla psów, latanie jest nieodłączne dla samolotów, składanie jaj jest nieodłączne dla ptaków. .), należy umieścić w innych obiektach związanych z tym bytem (przykład: powinniśmy umieścić zachowanie szczekania w obiekcie powiązanym z bytem)?
3)
Poza tym, spróbuj usunąć zachowanie i atrybuty do innych obiektów powiązanych z podstawową ENTITY.
a) MyEntityprzekazuje obowiązki A_respi B_respobiekty aoraz bodpowiednio.
Mimo że większość A_respi B_resppraca jest wykonywana przez ai binstancje, klienci są nadal obsługiwani A_respi B_respprzez MyEntity, co oznacza, że z punktu widzenia klienta do tych dwóch obowiązków należą MyEntity. Tak więc, nie to oznacza MyEntityrównież ma A_respi B_respobowiązki i jako takie narusza SRP ?
b) Nawet jeśli założymy, że A_respi B_respnie należą do MyEntity, MyEntitynadal ma obowiązek AB_respkoordynowania operacji obiektów ai b. Czyli nie MyEntitynarusza SRP, ponieważ ma przynajmniej dwa obowiązki - jednoznaczna identyfikacja, a także AB_resp?
class MyEntity
{
private A a = ...
private B b = ...
public A GetA()
{ ... }
public B GetB()
{ ... }
/* coordinates operations of objects a and b */
public int AworkB()
{ ... }
}
/* A encapsulates a single responsibility resp_A*/
/* A is value object */
class A
{ ... }
/* B encapsulates a single responsibility resp_B*/
/* B is value object */
class B
{ ... }
AKTUALIZACJA:
1.
Zachowanie w tym kontekście odnosi się do zachowania semantycznego. Na przykład właściwość w klasie (tj. Atrybut w obiekcie domeny), która jest używana do jednoznacznej identyfikacji, ma zachowanie. Chociaż nie jest to bezpośrednio reprezentowane w kodzie. Oczekiwane zachowanie polega na tym, że dla tej właściwości nie będzie żadnych zduplikowanych wartości.
Tak więc w kodzie prawie nigdy nie musielibyśmy faktycznie wdrażać zachowania (tj. Operacji), które w jakiś sposób utrzymywałoby tożsamość jednostki, ponieważ jak wyjaśniono, takie zachowanie istnieje tylko jako koncepcja w modelu domeny (w postaci atrybutu ID encja), ale kiedy tłumaczymy ten atrybut ID na kod, część jego semantyki jest tracona (tj. część, która pośrednio upewnia się, że wartość identyfikatora jest unikalna, zostaje utracona)?
2)
Ponadto właściwość taka jak Wiek nie ma kontekstu poza bytem osobowym i jako taka nie ma sensu przenosić się do innego obiektu ... Jednak informacje te można łatwo przechowywać w osobnym miejscu, w którym unikalny identyfikator, stąd mylące odniesienie do zachowania. Wiek może być leniwie ładowaną wartością.
a) Jeśli Agewłaściwość jest leniwie ładowana, możemy nazwać to zachowaniem, nawet jeśli semantycznie Agejest tylko atrybutem?
3)
Możesz łatwo wykonać operacje specyficzne dla adresu, takie jak sprawdzenie, czy jest to prawidłowy adres. Być może nie wiesz tego w czasie projektowania, ale cała ta koncepcja polega na rozbiciu obiektów na ich najmniejsze części
Chociaż zgadzam się, że stracilibyśmy kontekst, przenosząc się Agedo innego obiektu, kontekst nie zostałby utracony, gdybyśmy przenieśli DateOfBirthwłasność do innego obiektu, ale zwykle nie przenosimy go.
Jaki jest główny powód przejścia Addressdo innego obiektu, ale nie DateOfBirth? Ponieważ DateOfBirthjest bardziej nieodłączny od Personbytu lub ponieważ istnieje mniejsze szanse, że gdzieś w przyszłości będziemy musieli zdefiniować operacje specyficzne dla DateOfBirth?
4. Muszę powiedzieć, że nadal nie wiem, czy MyEntityma też A_respi B_respobowiązki i dlatego MyEntityteż że AB_respnie jest uważana za naruszenie SRP
EULERFX
1)
Zachowania, o których mówi autor, są zachowaniami powiązanymi z bytem. Są to zachowania, które modyfikują stan bytu
a) Jeśli dobrze cię rozumiem, mówisz, że byt powinien zawierać tylko te zachowania, które modyfikują jego atrybuty (tj. jego stan )?
b) A co z zachowaniami , które niekoniecznie modyfikują stan bytu , ale nadal są uważane za nieodłączną cechę tego bytu (przykład: szczekanie byłoby nieodłączną cechą Dogbytu, nawet gdyby nie zmodyfikował Stan psa )? Czy powinniśmy włączyć te zachowania do bytu, czy też należy je przenieść do innych obiektów?
2)
Jeśli chodzi o przenoszenie zachowania na inne obiekty, autor odnosi się konkretnie do obiektów wartości.
Chociaż mój cytat tego nie zawiera, ale autor wspomina w tym samym akapicie, że w niektórych przypadkach zachowania (i atrybuty ) zostaną przeniesione również do innych bytów (chociaż rozumiem korzyści płynące z przeniesienia zachowań na VO)
3) Zakładając, że MyEntity(patrz pytanie 3. w moim oryginalnym poście) nie narusza SRP, czy powiedzielibyśmy, że odpowiedzialność za MyEntityto obejmuje między innymi:
za. A_resp + B_resp + AB_resp ( AB_respwspółrzędne obiektów ai b)
lub
b. AB_resp + delegowanie A_respi B_respdo obiektów ( ai b) powiązanych z MyEntity?
4) Książka DDD Erica Evana, str. 94:
CustomerID to jedyny identyfikator PODMIOTU Klienta (rysunek 5.5), ale numer telefonu i adres byłyby często używane do znalezienia lub dopasowania Klienta. Nazwa nie określa tożsamości osoby, ale często jest używana jako część sposobu jej ustalenia.
W tym przykładzie atrybuty telefonu i adresu zostały przeniesione do klienta, ale w prawdziwym projekcie wybór ten zależałby od tego, w jaki sposób klienci domeny są zazwyczaj dopasowywani lub wyróżniani. Na przykład jeśli klient ma wiele kontaktowych numerów telefonów do różnych celów, to numer telefonu nie jest powiązany z tożsamością i powinien pozostać w kontakcie sprzedaży.
za)
CustomerID to jedyny identyfikator PODMIOTU Klienta (rysunek 5.5), ale numer telefonu i adres byłyby często używane do znalezienia lub dopasowania Klienta. Nazwa nie określa tożsamości osoby, ale często jest używana jako część sposobu jej ustalenia.
Cytat stwierdza, że tylko atrybuty związane z tożsamością powinny pozostać w encji . Zakładam, że autor oznacza, że encja powinna zawierać tylko te atrybuty, które są często używane do znalezienia lub dopasowania tej encji , podczas gdy WSZYSTKIE inne atrybuty powinny zostać przeniesione?
b) Ale w jaki sposób / gdzie należy przenieść inne atrybuty ? Na przykład (tutaj założenie jest takie, że atrybut adresu nie jest używany do znajdowania ani dopasowywania, Customer dlatego chcemy usunąć atrybut adresu z Customer):
jeśli zamiast mieć Customer.Address(typu string) tworzymy właściwość Customer.Addresstypu Address, to czy przenieśliśmy atrybut adresu do powiązanego obiektu VO (który jest typu Address) czy powiedzielibyśmy, że Customernadal zawiera atrybut adresu ?
do)
W tym przykładzie atrybuty telefonu i adresu zostały przeniesione do klienta, ale w prawdziwym projekcie wybór ten zależałby od tego, w jaki sposób klienci domeny są zazwyczaj dopasowywani lub wyróżniani. Na przykład jeśli klient ma wiele kontaktowych numerów telefonów do różnych celów, to numer telefonu nie jest powiązany z tożsamością i powinien pozostać w kontakcie sprzedaży.
Autor nie ma racji tutaj, ponieważ jeśli założymy, że każdy z wielu kontaktowych numerów telefonów, które Customernależą tylko do tego konkretnego Customer, powiedziałbym, że te numery telefonów są powiązane z tożsamością tak samo, jak wtedy, gdy Customermiał tylko jeden numer telefonu ?
5)
Powodem, dla którego autor sugeruje usunięcie jednostki, jest to, że kiedy początkowo tworzy się jednostkę klienta, istnieje tendencja do zapełniania jej dowolnym atrybutem, który można by pomyśleć o powiązaniu z klientem. Jest to podejście skoncentrowane na danych, które pomija zachowania, które ostatecznie prowadzą do anemicznego modelu domeny.
Off topic, ale myślałem, anemiczny model domeny wyników przesuwaniu zachowanie się o jednostkę , a Twój przykład jest zapełnianie się podmiot z wieloma atrybutami , które spowodowałyby Customerzbyt wiele zachowań (odkąd prawdopodobnie także w Customertych zachowań , które zmodyfikować te dodatkowe atrybuty ), a tym samym naruszając SRP?
dzięki