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 find
i 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) MyEntity
przekazuje obowiązki A_resp
i B_resp
obiekty a
oraz b
odpowiednio.
Mimo że większość A_resp
i B_resp
praca jest wykonywana przez a
i b
instancje, klienci są nadal obsługiwani A_resp
i B_resp
przez MyEntity
, co oznacza, że z punktu widzenia klienta do tych dwóch obowiązków należą MyEntity
. Tak więc, nie to oznacza MyEntity
również ma A_resp
i B_resp
obowiązki i jako takie narusza SRP ?
b) Nawet jeśli założymy, że A_resp
i B_resp
nie należą do MyEntity
, MyEntity
nadal ma obowiązek AB_resp
koordynowania operacji obiektów a
i b
. Czyli nie MyEntity
narusza 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 Age
właściwość jest leniwie ładowana, możemy nazwać to zachowaniem, nawet jeśli semantycznie Age
jest 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ę Age
do innego obiektu, kontekst nie zostałby utracony, gdybyśmy przenieśli DateOfBirth
własność do innego obiektu, ale zwykle nie przenosimy go.
Jaki jest główny powód przejścia Address
do innego obiektu, ale nie DateOfBirth
? Ponieważ DateOfBirth
jest bardziej nieodłączny od Person
bytu 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 MyEntity
ma też A_resp
i B_resp
obowiązki i dlatego MyEntity
też że AB_resp
nie 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ą Dog
bytu, 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 MyEntity
to obejmuje między innymi:
za. A_resp
+ B_resp
+ AB_resp
( AB_resp
współrzędne obiektów a
i b
)
lub
b. AB_resp
+ delegowanie A_resp
i B_resp
do obiektów ( a
i 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.Address
typu Address
, to czy przenieśliśmy atrybut adresu do powiązanego obiektu VO (który jest typu Address
) czy powiedzielibyśmy, że Customer
nadal 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 Customer
należą tylko do tego konkretnego Customer
, powiedziałbym, że te numery telefonów są powiązane z tożsamością tak samo, jak wtedy, gdy Customer
miał 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 Customer
zbyt wiele zachowań (odkąd prawdopodobnie także w Customer
tych zachowań , które zmodyfikować te dodatkowe atrybuty ), a tym samym naruszając SRP?
dzięki