Wartość a obiekty jednostki (projektowanie oparte na domenie)

92

Właśnie zacząłem czytać DDD. Nie jestem w stanie w pełni pojąć koncepcji obiektów typu jednostka vs wartość. Czy ktoś może wyjaśnić problemy (łatwość utrzymania, wydajność itp.), Z którymi może się spotkać system, gdy obiekt wartości jest projektowany jako obiekt typu Entity? Przykład byłby świetny ...

shA.t
źródło
3
Tutaj napisałem pełną (IMO) listę różnic między nimi: enterprisecraftsmanship.com/2016/01/11/...
Vladimir

Odpowiedzi:

109

Sprowadzona do podstawowego rozróżnienia, tożsamość ma znaczenie dla bytów, ale nie ma znaczenia dla przedmiotów wartościowych. Na przykład czyjeś imię jest obiektem wartości. Jednostka Customer może składać się z nazwy klienta (obiekt wartości), List <Order> OrderHistory (lista jednostek) i być może domyślnego adresu (zwykle jest to obiekt wartości). Jednostka klienta miałaby identyfikator, a każde zamówienie miałoby identyfikator, ale nie powinno mieć nazwy; ogólnie rzecz biorąc, w ramach modelu obiektowego tożsamość adresu prawdopodobnie nie ma znaczenia.

Obiekty wartości mogą być zwykle reprezentowane jako obiekty niezmienne; zmiana jednej właściwości obiektu wartości zasadniczo niszczy stary obiekt i tworzy nowy, ponieważ nie jesteś tak zainteresowany tożsamością, jak treścią. Prawidłowo, metoda wystąpienia Equals w Name zwróciłaby wartość „true”, o ile właściwości obiektu są identyczne z właściwościami innej instancji.

Jednak zmiana niektórych atrybutów jednostki, takiej jak Klient, nie niszczy klienta; jednostka klienta jest zazwyczaj zmienna. Tożsamość pozostaje taka sama (przynajmniej po utrwaleniu obiektu).

Prawdopodobnie tworzysz wartościowe obiekty, nie zdając sobie z tego sprawy; za każdym razem, gdy reprezentujesz jakiś aspekt Encji, tworząc szczegółową klasę, masz obiekt wartości. Na przykład klasa IPAddress, która ma pewne ograniczenia dotyczące prawidłowych wartości, ale składa się z prostszych typów danych, byłaby obiektem wartości. EmailAddress może być ciągiem znaków lub obiektem wartości z własnym zestawem zachowań.

Jest całkiem możliwe, że nawet elementy, które mają tożsamość w bazie danych, nie mają tożsamości w modelu obiektów. Ale najprostszy przypadek to połączenie pewnych atrybutów, które razem mają sens. Prawdopodobnie nie chcesz mieć Customer.FirstName, Customer.LastName, Customer.MiddleInitial i Customer.Title, kiedy możesz skomponować je razem jako Customer.Name; prawdopodobnie będzie to wiele pól w twojej bazie danych, zanim zaczniesz myśleć o trwałości, ale twój model obiektowy to nie obchodzi.

JasonTrue
źródło
Gdzie pasują niewspółdzielone zmienne obiekty? Jeśli w całym wszechświecie istnieje tylko jedno odniesienie do obiektu, tożsamość obiektu będzie nieistotna, nawet jeśli jest zmienna. Z mojego punktu widzenia rzecz jest bytem, ​​jeśli istnieje odniesienie, którego można by użyć do obserwacji aspektu stanu, który mógłby się zmienić bez użycia tego odniesienia do jego zmiany . Jeśli jakaś rzecz nie łączy się ze światem zewnętrznym i albo jest niezmienna, albo istnieje tylko jedno odniesienie do niej w dowolnym miejscu we wszechświecie, to powyższy scenariusz nie może wystąpić i jest wartością.
supercat
Coś takiego jak an int[1]może być niewspółdzieloną zmienną wartością, niezmienną wartością współdzieloną (jeśli żadna z rzeczy, które zawierają odniesienia, nigdy do niej nie zapisze) lub bytem (jeśli istnieją dwa lub więcej odniesień, a jeden z nich może zostać użyty do zapisu wartości, które można odczytać za pomocą drugiego). Niestety, nie znam żadnego wsparcia językowego w Javie lub .NET, aby zapobiec przypadkowemu przekształceniu się obiektów klas, które hermetyzują zmienne wartości, w encje.
supercat
@supercat, jeśli masz na myśli brak bezpośredniego, prostego wsparcia, zgodziłbym się, ale robię to, aby wyeliminować publiczny dostęp do konstruktorów, używać tylko statycznych fabryk do tworzenia nowych instancji i ograniczać cały dostęp do stanu przez właściwości tylko do odczytu (bez ustawiania) .
Charles Bretana
40

Każdy obiekt zdefiniowany zbiorczo przez wszystkie atrybuty it jest obiektem wartości. Jeśli którykolwiek z atrybutów ulegnie zmianie, masz nową instancję obiektu wartości. Dlatego obiekty wartości są definiowane jako niezmienne.

Jeśli obiekt nie jest w pełni zdefiniowany przez wszystkie jego atrybuty, wówczas istnieje podzbiór atrybutów, które składają się na tożsamość obiektu. Pozostałe atrybuty mogą ulec zmianie bez ponownego definiowania obiektu. Tego rodzaju obiekt nie może być zdefiniowany jako niezmienny.

Prostszym sposobem rozróżnienia jest myślenie o obiektach wartości jako danych statycznych, które nigdy się nie zmienią, a encjach jako danych, które ewoluują w aplikacji.

Richard Dorman
źródło
7

Typy wartości:

  • Typy wartości nie istnieją samodzielnie, zależy od typów jednostek.
  • Obiekt typu wartości należy do obiektu typu jednostki.
  • Okres istnienia wystąpienia typu wartości jest ograniczony przez okres istnienia wystąpienia jednostki będącej właścicielem.
  • Trzy typy wartości: podstawowe (pierwotne typy danych), złożone (adres) i kolekcjonerskie (mapa, lista, tablice)

Podmioty:

  • Typy jednostek mogą istnieć samodzielnie (tożsamość)
  • Jednostka ma swój własny cykl życia. Może istnieć niezależnie od innych podmiotów.
  • Na przykład: osoba, organizacja, uczelnia, komórka, dom itp. Każdy obiekt ma swoją własną tożsamość
Premraj
źródło
Nie dotyczy DDD :(
HydTechie
6

Nie wiem, czy poniższe informacje są poprawne, ale powiedziałbym, że w przypadku obiektu Adres chcemy użyć go jako obiektu wartości zamiast jednostki, ponieważ zmiany w encji byłyby odzwierciedlone na wszystkich połączonych obiektach ( na przykład osoba).

Weźmy ten przypadek: mieszkasz w swoim domu z innymi osobami. Gdybyśmy użyli Entity jako adresu, argumentowałbym, że istniałby jeden unikatowy adres, do którego prowadzą wszystkie obiekty Person. Jeśli jedna osoba się wyprowadzi, chcesz zaktualizować jej adres. Jeśli zaktualizowałbyś właściwości jednostki adresowej, wszystkie osoby miałyby inny adres. W przypadku obiektu wartości nie moglibyśmy edytować adresu (ponieważ jest on niezmienny) i bylibyśmy zmuszeni podać nowy adres dla tej osoby.

Czy to brzmi dobrze? Muszę powiedzieć, że po przeczytaniu książki DDD nadal byłem / jestem zdezorientowany tą różnicą.

Idąc o krok dalej, jak można to modelować w bazie danych? Czy wszystkie właściwości obiektu Address miałyby być kolumnami w tabeli Person, czy też utworzyłbyś oddzielną tabelę Address, która również miałaby unikalny identyfikator? W tym drugim przypadku ludzie mieszkający w tym samym domu mieliby różne wystąpienia obiektu Adres, ale te obiekty byłyby takie same, z wyjątkiem ich właściwości ID.

Christophe Herreman
źródło
1
„Weź ten przypadek: mieszkasz w swoim domu z kilkoma innymi osobami. Gdybyśmy użyli nazwy Entity jako adresu, argumentowałbym, że istniałby jeden unikalny adres, do którego odnoszą się wszystkie obiekty Person”. Myślę, że każda z tych osób ma swój własny adres, ale tak się składa, że ​​są sobie równi (to tak, jakby każda z nich mogła mieć banknot 5-dolarowy, ale to nie znaczy, że to ten sam banknot)
Prokurors
„ale to nie znaczy, że jest to ten sam banknot” - wydaje mi się, że zależy to od tego, czy przypisać banknotowi dodatkowe właściwości (np. datę emisji, fizyczne położenie w przestrzeni itp.); inaczej byłyby takie same. Wydaje mi się, że to samo dotyczy oprogramowania: adres jest taki sam lub nie, w zależności od właściwości, które musimy / chcemy wziąć pod uwagę.
adrhc
4

adres może być jednostką lub obiektem wartości, który zależy od procesu zajętości. obiekt adresu może być obiektem w aplikacji kurierskiej, ale adres może być obiektem wartości w innej aplikacji. w sprawach tożsamości aplikacji kurierskich dla obiektu adresowego

Dharmesz
źródło
2

Zapytałem o to w innym wątku i myślę, że nadal jestem zdezorientowany. Mogę mylić kwestie wydajności z modelowaniem danych. W naszej aplikacji Katalogowanie Klient nie zmienia się, dopóki nie musi. Brzmi to głupio - ale „odczyty” danych klientów znacznie przewyższają liczbę „zapisów”, a ponieważ wiele żądań internetowych trafia do „aktywnego zestawu” obiektów, nie chcę ciągle ładować klientów. Więc podążałem niezmienną drogą dla obiektu klienta - załaduj go, buforuj i obsługuj to samo dla 99% (wielowątkowych) żądań, które chcą zobaczyć klienta. Następnie, gdy klient coś zmieni, poproś „redaktora” o utworzenie nowego klienta i unieważnienie starego.

Obawiam się, że jeśli wiele wątków widzi ten sam obiekt klienta i jest on zmienny, to gdy jeden wątek zaczyna się zmieniać, następuje chaos w innych.

Moje problemy są następujące: 1) jest to rozsądne i 2) jak najlepiej to zrobić bez powielania dużej ilości kodu o właściwościach.

n8wrl
źródło
1

3 rozróżnienie między EntitiesaValue Objects

  • Identyfikator a równość strukturalna: jednostki mają identyfikator, jednostki są takie same, jeśli mają ten sam identyfikator. Obiekty wartości poza ręką mają równość strukturalną. Uważamy, że dwa obiekty wartości są równe, gdy wszystkie pola są takie same. Obiekty wartości nie mogą mieć identyfikatora.

  • Mutowalność a niezmienność: obiekty wartości są niezmiennymi strukturami danych, podczas gdy jednostki zmieniają się w trakcie swojego życia.

  • Długość życia: obiekty wartości powinny należeć do jednostek

Ramin Farajpour
źródło
1

W bardzo prostym zdaniu mogę powiedzieć, że mamy trzy rodzaje równości:

  • Równość identyfikatorów : klasa ma wpisany identyfikator i dwa obiekty są porównywane z ich wartością pola id.
  • Równość odwołań : jeśli odwołanie do dwóch obiektów ma ten sam adres w pamięci.
  • Równość strukturalna : dwa obiekty są równe, jeśli wszystkie ich elementy są dopasowane.

Równość identyfikatorów odnosi się tylko do Encji, a równość strukturalna odnosi się tylko do Obiektu Wartości. W rzeczywistości obiekty wartości nie mają identyfikatora i możemy ich używać zamiennie. również obiekty wartości muszą być niezmienne, a jednostki mogą być modyfikowalne, a obiekty wartości nie będą miały żadnej tabeli w bazie danych.

Alireza Rahmani Khalili
źródło