Czy niezmienne obiekty i DDD idą w parze?

18

Rozważ system, który używa DDD (a także: każdy system, który używa ORM). Realistycznym celem każdego systemu, w prawie każdym przypadku użycia, będzie manipulowanie tymi obiektami domeny. W przeciwnym razie nie będzie prawdziwego efektu ani celu.

Modyfikacja niezmiennego obiektu spowoduje, że wygeneruje on nowy rekord po utrwaleniu obiektu, co spowoduje ogromne wzdęcie w źródle danych (chyba że usuniesz poprzednie rekordy po modyfikacji).

Widzę korzyści płynące z używania niezmiennych obiektów, ale w tym sensie nigdy nie widzę użytecznego przypadku użycia niezmiennych obiektów. Czy to źle?

Steven Evers
źródło

Odpowiedzi:

16

Obliczenia z użyciem niezmiennych obiektów (jak w programowaniu funkcjonalnym) niekoniecznie oznaczają utrwalenie każdego generowanego obiektu!

Steven A. Lowe
źródło
Nie widzę jednak przypadku, w którym ten scenariusz wykorzystuje niezmienne obiekty - więc byłyby tam bez konkretnego celu. Czy się mylę?
Steven Evers
1
myślałem, że niezmienne obiekty będą przydatne do obliczeń pośrednich (w równoległych wątkach)
Steven A. Lowe
11

Czy niezmienne w domenie oznacza, że ​​musi być niezmienne w bazie danych? Weźmy na przykład następujące założenie, że klient ma zawsze jeden adres:

customer.address = new Address('My Castle', 'Kings street');
customer_repo.save(customer);

teraz uruchamiany jest następujący kod SQL, biorąc pod uwagę, że identyfikator klienta to 1:

INSERT INTO addresses (customer_id, name, street)
VALUES (1, 'My Castle', 'Kings street');

teraz w adresie wprowadzono następującą zmianę:

customer.address = new Address('Pauper palace', 'Outlands');
customer_repo.save(customer);

i warstwa trwałości, będąc bardzo sprytnym, uruchamia następującą sql:

UPDATE addresses SET name='Pauper palance', street='Outlands'
WHERE customer_id = 1;

W ten sposób można uniknąć narzutu oddzielnej instrukcji DELETE AND INSERT. Myślę też, że niektóre RDBMS mają INSERT REPLACE lub coś takiego. MySql ma WYMIANA .

andho
źródło
+1 Zgadzam się z tobą na ogólnej zasadzie: nie rozumiem, dlaczego niezmienne obiekty domeny muszą koniecznie oznaczać niezmienne wiersze DB.
Andres F.,
W powyższym przypadku, gdybyśmy kiedykolwiek musieli zmienić atrybut miasta klasy adresu dla danego klienta, jak byśmy sobie z tym poradzili? Ponadto zakładamy, że klient może mieć wiele adresów, aby była relacją jeden do wielu między klientem a adresami
Sudarshan
1
@Sudarshan jest to po prostu sposób na uczynienie „obiektu niezmiennej wartości”, niezupełnie niezmiennym w bazie danych. Ze względu na wydajność. Każda sytuacja wymaga szczególnego traktowania. W tej chwili wolę pozyskiwanie zdarzeń w mojej Domenie, ale jestem niejako uzależniony.
andho
@Sudarshan, aby konkretnie odpowiedzieć na twoje pytanie, wystarczy uruchomić zapytanie o aktualizację, które aktualizuje wiersz do nowej wartości. Jeśli jest jeden do wielu, adresy będą miały jakiś identyfikator w katalogu głównym agregacji klienta, który zostanie użyty do jednoznacznej identyfikacji w bazie danych. Następnie ten identyfikator i identyfikator_użytkownika zostaną wykorzystane do zaktualizowania tego wiersza w tabeli „adres”.
andho,
@andho „jest to tylko sposób na uczynienie„ obiektu o niezmiennej wartości ”, nie do końca niezmiennym w bazie danych.” to naprawdę sprawiło, że mój dzień był wdzięczny
Sudarshan
6

W DDD obiekty niezmienne prawie zrównują się z obiektami wartości. Te obiekty nie są bytami, nie mają tożsamości. Dlatego zawsze zachowuję obiekty wartości jako kolumny encji, w których są zawarte (w N / Hibernacji możesz do tego użyć Komponentów). Nie mają własnego stołu.

guillaume31
źródło
4

Zależy to od sposobu odwzorowania niezmiennego obiektu w bazie danych. Jeśli jest to tylko składnik taki jak DateTime (z biblioteki Joda Time), wówczas zmiana wartości spowoduje aktualizację, a nie wstawienie. Jeśli jednak niezmienna jest bardziej złożona i wymaga wiersza w tabeli, masz problem z wzdęciem.

Przypuszczam, że choć jest to słaby argument, można w ten sposób wdrożyć ścieżkę audytu. Każda zmiana w niezmiennym może być śledzona przez wkładki. Istnieje jednak wiele lepszych sposobów na to.

Podsumowując, posiadanie niezmiennych obiektów domenowych (zamiast tylko ich składników) wydaje się trochę niezgodne z trwałością.

Gary Rowe
źródło
Ani trochę. Składniki są bardzo przydatne, ponieważ pozwalają na składanie obiektów domeny inaczej niż te same dane podstawowe. Problemy związane są z wymuszaniem niezmienności. Osobiście traktowałbym obiekty domeny jako zmienne (z wyjątkiem pól klucza podstawowego) i upraszczałbym to.
Gary Rowe,
„Podsumowując, posiadanie niezmiennych obiektów domenowych (zamiast tylko ich składników) wydaje się być trochę niezgodne z uporem”. Twoim zdaniem, gdzie powinniśmy mieć obiekty wartości, które nie powinny być modelowane jako komponenty (terminologia hibernacji)? --- Przepraszam, że źle wpisałem swój ostatni komentarz i dlatego go usunąłem.
Sudarshan
Unikaj komponentów, gdy pojedynczy byt jest w pełni reprezentowany przez wiersz i żadne dane nie są udostępniane przez inny obiekt domeny.
Gary Rowe
4

To zależy od domeny. DDD nie określa, że ​​paradygmat programowania jest zorientowany obiektowo. Paradygmat obiektowy jest jednak dobrze dostosowany do typowej aplikacji, którą należy utrwalić w bazie danych.

DDD po ​​prostu stwierdza, że ​​należy zbudować oprogramowanie w oparciu o model domeny reprezentujący faktyczny problem, który oprogramowanie próbuje rozwiązać. Jeśli ten problem miałby na przykład charakter matematyczny, wówczas wdrożenie warstwy domeny przy użyciu programowania funkcjonalnego i niezmiennych struktur danych miałoby sens.

Z drugiej strony, jeśli problem dotyczy bardziej typowej aplikacji korporacyjnej i używasz niezmiennych struktur obiektów dla wszystkich obiektów domeny, to argumentowałbym, że nie postępujesz zgodnie z DDD. Mogę wymyślić co najmniej dwa argumenty:

  • Twoje wdrożenie nie reprezentuje modelu domeny z domeną problemową. Domena problemowa w tym przypadku składa się z podmiotów, które muszą zmodyfikować stan. I nie tak to zaimplementowałeś.

  • Nie masz wszechobecnego języka. Język i pojęcia w modelu domeny nie są zgodne z tym, czego używają eksperci w dziedzinie.

Uwaga: DDD w stosownych przypadkach używa niezmiennych obiektów, są one po prostu nazywane obiektami wartości.

Nie twierdzę więc, że nie można utworzyć aplikacji bazy danych przy użyciu czysto funkcjonalnych struktur danych i nie twierdzę, że nie powinieneś. Po prostu nie sądzę, że można to nazwać DDD, w zależności od rodzaju aplikacji

Pete
źródło
Peter, świetna odpowiedź. Czy mógłbyś rzucić okiem na moje pytanie tutaj stackoverflow.com/questions/13783666/... i pomóc mi zrozumieć mój problem. Myślę, że niezmienne obiekty wartości są świetne dla oprogramowania niezwiązanego z przedsiębiorstwem. Moim zdaniem większość obiektów aplikacji korporacyjnych jest zmienna. Wyobraź sobie, że masz niezmienny, głęboko zagnieżdżony obiekt wartości ... ContactInfo-> PhysicalLocation-> Adres, a chcesz zaktualizować kod pocztowy ... tworzenie wykresu całego obiektu wydaje mi się antychrystem, a nie tylko wzorem. co myślisz?
Pepito Fernandez,
3

Jeśli używasz ORM, takiego jak Hibernacja / NHibernate, możesz ustawić opcję kaskady, aby automatycznie usuwać osierocone obiekty. Jeśli dana osoba ma obiekt wartości Adres, po zmianie adresu nowy zostanie zapisany, a stary usunięty, ponieważ jest teraz osierocony.

Mike Rowley
źródło
0

Obiekty wartości są prawie zawsze niezmienne w DDD, a wzorzec wagi prostej może być użyty do utrzymania duplikacji tego obiektu wartości w pamięci, podobnie jak .NET robi z łańcuchami. Głównym kompromisem jest pamięć z jednej strony, a z drugiej - wydajność tworzenia. W przypadku wzoru flyweight należy wykonać porównanie oparte na wartości, aby ustalić, czy jakikolwiek nowy lub odtworzony obiekt wartości znajduje się już w pamięci podręcznej flyweight, ale wszelkie inne porównania po tym punkcie można zasadniczo bezpiecznie wykonać przez odniesienie, ponieważ wymuszone jest pojedyncze wystąpienie. Niezależnie od tego, czy używana jest waga muchowa, czy nie, obiekty wartości stają się niezmienne, ponieważ mają tylko wewnętrzną tożsamość, a zatem zmiana ich wartości zmieniłaby ich tożsamość.

jpierson
źródło
-1

Istnieje inny sposób użycia niezmiennych obiektów ...

Zamiast zapisywać wartości 5.0, 6.0, 7.0, 8.0 i kopiować cały rekord za każdym razem, możesz zamiast tego zapisać coś takiego: 5.0, +1.0, +1.0, +1.0, a następnie poprawnie zbudować zależności, aby odtworzyć sekwencję 5.0 , 6.0, 7.0, 8.0. W ten sposób małe modyfikacje zajmują tylko niewielką ilość pamięci ...

tp1
źródło