Witaj na Zine.net online Zaloguj się | Rejestracja | Pomoc

Simon says...

Szymon Pobiega o architekturze i inżynierii oprogramowania
DTO vs CQS
Dzisiejsza notka jest wolnym tłumaczeniem jednej z poprzednich, którą opublikowałem in English. Ilość informacji na ten temat w polskim internecie jest tak znikoma, iż wydaje mi się, że każda notka jest ważna.

Pomijając historię, jak udało mi się dość do moich wniosków, chciałbym zaprezentować rzetelne porównanie podejść DTO oraz CQS w kontekście udostępniania informacji na potrzeby interfejsu użytkownika.

DTO


Wzorzec DTO polega na zdefiniowaniu, dla każdego obiektu Modelu Domeny, obiektu Data Transfer, który posiada wszystkie dane obiektu Modelu, ale nie posiada zachowania. Jest to kontener na dane, który może być przekazywany między warstwami.

[Edit]
Jak słusznie zauważył Wojciech Gebczyk, powyższa definicja to jedna z form wzorca DTO. Inna, zupełnie legalną, formą jest jeden  (lub dwa: input oraz output) obiekt DTO dla każdej operacji udostępnianej przez fasadę modelu. Poniższe rozważanie nie dotyczy obiektów DTO przeznaczonych do przenoszenia argumentów wejściowych operacji, a jedynie tych, które służą do transportu wyników zapytań.
[/Edit]

DTO są zwykle tworzone za pomocą wzorca DTO assembler, czyli specjalizowanej klasy, która przepisuje dane z obiektu Modelu do obiektu DT. Assembler może być zastąpiony tzw. object/object mapperem (np. AutoMapper) analogicznie, jak ręcznie napisany DAL może być zastąpiony O/RM-em.

Poniższy rysunek przedstawia schemat interakcji z modelem domeny, eksponowanym za pośrednictwem aplikacji WWW, składający się z dwóch faz: pobranie danych na GUI (pierwsze żądanie) oraz wykonanie operacji biznesowej (drugie żądanie). Wyraźnie widoczne są trzy fazy transformacji danych.


Legenda:
  • Strzałka z pustym grotem - przepływ sterowania
  • Strzałka z pełnym grotem - przepływ danych
  • Bloczek niebieski - transformacja danych
  • Bloczek źółty/pomatańczowy - relacyjna baza danych
  • MD / MDZ / MDK - model domeny / model domeny dla zapytań / model domeny dla komend

CQS


Na temat definiowania CQS w kontekście architektury pisał sporo Greg Young, więc nie będę odkrywał koła na nowo. W naszym kontekście istotą CQS jest wydzielenie dwóch modeli: modelu dla komend oraz modelu dla zapytań. Model dla komend realizuje logikę biznesową. Jest, z grubsza, taki sam, jak ogólny model w wypadku użycia DTO. Obiekty modelu dla komend nie muszą jednak eksponować publicznie swoich danych.

Model dla zapytań zawiera klasy reprezentujące obiekty domeny w kontekście zapytań. Są to, podobnie jak w wypadku DTO, klasy pozbawione zachowania. Różnica polega na tym, że obiekty tych klas nie są one budowane na podstawie obiektów modelu dla komend, ale bezpośrednio na podstawie bazy danych (np. w wykorzystaniem biblioteki OR\M).

Poniższy rysunek przedstawia analogiczny (do tego z DTO) schemat interakcji. Tym razem widoczne są tylko dwie transformacje. Trzecia, ukryta, wykonywana jest na etapie synchronizacji danych.


Porównanie


Oba podejścia wymagają utrzymywania dwóch równoległych zestawów klas opisujących obiekty domeny. Oba również wymagają stworzenia logiki tworzącej obiekty DTO lub obiekty modelu dla zapytań. Ilość kodu wymagana do realizacji obu rozwiązań jest więc porównywalna.

Na tym podobieństwa się kończą. Wszelkie inne kwestie przemawiają na korzyść CQS:
  • CQS lepiej przygotowuje aplikację do skalowania, ponieważ umożliwia przeźroczyste dla kodu rozdzielenie baz danych stojących za modelami i realizację replikacji z bazy transakcyjnej (model dla komend) do bazy raportowej (model dla zapytań)
  • CQS (przy założeniu rozdzielenia baz) pozwala zoptymalizować obie bazy pod kątem operacji na nich wykonywanych (insert/update vs select)
  • CQS daje większą swobodę w tworzeniu GUI, ponieważ obiekty modelu dla zapytań mogą znacznie różnić się od obiektów modelu dla komend.
  • CQS skutkuje o wiele czystszym modelem logiki biznesowej, ponieważ klasy modelu dla komend nie są "zaśmiecone" kodem spełniającym wymagania warstwy prezentacji

Podsumowując, CSQ kosztuje tyle samo, a daje znacznie większe możliwości. Dlaczego miałbym więc wracać do DTO?

Opublikowane 17 września 2009 09:51 przez simon

Powiadamianie o komentarzach

Jeżeli chciałbyś otrzymywać email gdy ta wypowiedź zostanie zaktualizowana, to zarejestruj się tutaj

Subskrybuj komentarze za pomocą RSS

Komentarze:

# re: DTO vs CQS @ 17 września 2009 11:38

Hmm.. W drugim przykładzie nadal masz DTO, więc ostatnie pytanie chyba nie tak zadane :)

dario-g

# re: DTO vs CQS @ 17 września 2009 11:51

Dzięki. Już naprawiłem rysunek:) Tak to jest jak się kopiuje. Jakiś guideline DRY dla Visio by sie przydał;)

simon

# re: DTO vs CQS @ 17 września 2009 15:40

Chciale mzwrocic delikatnie uwage ze DTO nie polega na zdefiniowaniu DLA KAZDEGO obiektu modelu domeny (MD), a mozna powiedziec ze dla wiekszosci atrybutow wiekszosci obiektow MD.

Najbardzoej "dokladna" implementacja ideii jest takie przygotowanie DTO aby przesylany byl minimalny niezbedny zestaw wartosci dla konkretnej wywolywanej akcji.

- zaleta jest optymalnosc kontraktu uslug

- wada jest olbrzymia ilosc powstalych obiektow (prawie 2 x ilosc metod w uslugach)

Drugim koncem skali implemntacji jest wlasnie to co opisales czyli klon warstwy MD.

- zaleta jest prostota modelu DTO - mozna zgenerowac z MD

- wady sam opisales.

Trudno porownywac 2 podejsca gdzie jeden jest skrajnoscia zadko spotykana w realnych scenariuszach (majacych sensowne wykonanie).

Wojciech Gebczyk

# re: DTO vs CQS @ 17 września 2009 15:59

Masz racje z tym, że DTO może (powinno?) być zoptymalizowane pod kątem konkretnej metody. Ja w moim poście miałem na myśli konkretne DTO wykorzystywane dla wyświetlenia danych na GUI. Zaraz zaktualizuje posta zgodnie z Twoją (słuszną) uwagą.

simon

# CQRS is not an option. It is a must-have « Simon says… architecture! @ 16 lutego 2010 08:21

PingBack od http://simon-says-architecture.com/2010/02/16/cqrs-is-not-an-option-it-is-a-must-have/

CQRS is not an option. It is a must-have « Simon says… architecture!

Co o tym myślisz?

(wymagane) 
wymagane 
(wymagane) 

  
Wprowadź kod: (wymagane)