Niedawno sam przeczytałem DDD. Gdy doszedłem do tego działu, byłem mile zaskoczony, gdy odkryłem, że odkryłem tę samą 4-warstwową architekturę, co Evans. Jak wskazał @lonelybug, warstwa domeny powinna być całkowicie odizolowana od reszty systemu. Jednak coś musi tłumaczyć wartości specyficzne dla interfejsu użytkownika (ciągi zapytań, dane POST, sesja itp.) Na obiekty domeny. Tutaj zaczyna się warstwa aplikacji. Jego zadaniem jest tłumaczenie w tę iz powrotem między interfejsem użytkownika, warstwą danych i domeną, skutecznie ukrywając domenę przed resztą systemu.
Widzę teraz wiele aplikacji ASP.NET MVC, w których prawie cała logika znajduje się w kontrolerach. To nieudana próba wdrożenia klasycznej architektury 3-warstwowej. Kontrolery są trudne do testowania jednostkowego, ponieważ mają wiele problemów związanych z interfejsem użytkownika. W rzeczywistości napisanie kontrolera tak, aby nie dotyczył bezpośrednio wartości „kontekstu HTTP”, jest poważnym wyzwaniem samym w sobie. Najlepiej byłoby, gdyby kontroler wykonał tłumaczenie, koordynował pracę i odrzucił odpowiedź.
Może nawet mieć sens przeprowadzanie podstawowej weryfikacji w warstwie aplikacji. Domena może założyć, że wchodzące w nią wartości mają sens (czy jest to prawidłowy identyfikator dla tego klienta i czy ten ciąg reprezentuje datę / godzinę). Jednak walidacja z wykorzystaniem logiki biznesowej (czy mogę zarezerwować bilet lotniczy w przeszłości?) Powinna być zarezerwowana dla warstwy domeny.
Martin Fowler komentuje, jak płaskie są obecnie większość warstw domen . Chociaż większość ludzi nawet nie wie, co to jest warstwa aplikacji, odkrywa, że wiele osób tworzy raczej głupie obiekty domenowe i złożone warstwy aplikacji, które koordynują pracę różnych obiektów domenowych. Jestem tego winny. Ważną rzeczą nie jest budowanie warstwy, ponieważ kazała ci to jakaś książka. Chodzi o to, aby zidentyfikować obowiązki i oddzielić nasz kod na podstawie tych obowiązków. W moim przypadku „warstwa aplikacji” ewoluowała naturalnie, gdy zwiększyłem testy jednostkowe.
W oparciu o wzorce projektowania korporacyjnego Martina Fowlera najczęstsze warstwy to:
Prezentacja - są to widoki, szablony prezentacji, które generują interfejs interakcji dla Twojej aplikacji (korzystam z interakcji w przypadku, gdy dostęp do Twojej aplikacji mają inne systemy za pośrednictwem usług internetowych lub RMI, więc może nie być interfejsem użytkownika). Dotyczy to również kontrolerów, które decydują o sposobie wykonywania akcji i sposobie ich wykonywania.
Domena - tutaj znajdują się reguły biznesowe i logika, zdefiniowane są modele domen itp
Źródło danych - jest to warstwa mapowania danych (ORM) i źródło danych (baza danych, system plików itp.)
Jak narysować granice między trzema warstwami:
Nie umieszczaj logiki specyficznej dla prezentacji w modelach lub obiektach domeny
Nie umieszczaj logiki na swoich stronach i kontrolerach, tj. Logiki do zapisywania obiektów w bazie danych, tworzenia połączeń z bazami danych itp., Które spowodują, że warstwa prezentacji będzie krucha i trudna do przetestowania
Użyj ORM, który umożliwia oddzielenie dostępu do źródła danych i działań od modelu
Postępuj zgodnie z cienkim kontrolerem - paradygmat modelu tłuszczu, kontrolery służą do kontrolowania procesu wykonywania, który go nie realizuje, więcej na http://www.littlehart.net/atthekeyboard/2007/04/27/fat-models-skinny-controllers/ oraz http://weblog.jamisbuck.org/2006/10/18/skinny-controller-fat-model model, widok i kontroler,
źródło
Warstwa domeny modeluje działalność Twojej aplikacji. To powinna być twoja jasna interpretacja jego zasad, dynamiki komponentów i zawiera swój stan w danym momencie.
Warstwa aplikacji „martwi się” o zdefiniowanie zadań, które należy wykonać, aby wykonać określone zadanie aplikacji. Głównie odpowiada za mandat za niezbędne prace w domenie i współdziała z innymi (zewnętrznymi lub nie) usługami.
Na przykład moja aplikacja finansowa ma operację użytkownika służącą do zmiany stanu encji modelowej (encji zdefiniowanej w DDD [89]):
Ale jako proces aplikacji, oprócz wszystkich konsekwencji modelowych tej operacji, muszę wysłać komunikację wewnętrzną do innych użytkowników aplikacji. Ten rodzaj pracy jest „koordynowany” w warstwie aplikacji. Nie chciałbym, aby moja warstwa domeny myślała o kierowaniu usługą przesyłania wiadomości. (i na pewno nie jest to odpowiedzialność warstwy prezentacji). Niezależnie od sposobu, jedno jest pewne: potrzebuję nowej warstwy, ponieważ moja warstwa domeny dotyczy podstawowej działalności, a moja warstwa prezentacji dotyczy interpretacji poleceń użytkownika i prezentacji wyników.
Uwagi:
źródło
Warstwę domeny należy zaprojektować jako warstwę izolacyjną, co oznacza, że żadna zmiana kodu (w warstwie aplikacji, warstwie prezentacji i warstwie infrastruktury) nie powinna mieć wpływu na logikę biznesową i reguły.
Warstwa aplikacji ma być zaprojektowana tak, aby zapewniała pewne funkcje dotyczące interfejsu systemu (aplikacji) (tak jak API lub RESTful). Na przykład użytkownicy mogą zalogować się do systemu, aw tym działaniu aplikacji (logowanie) kody warstwy aplikacji będą kodami klienta dla warstwy domeny (lub warstwy infrastruktury), w której pobiera obiekt domeny użytkownika i stosuje metody tego obiektu w celu zaimplementowania funkcja „logowania”.
Warstwa aplikacji powinna również zostać zaprojektowana jako warstwa izolacyjna, co oznacza, że na zachowanie aplikacji nie powinny mieć wpływu żadne zmiany (w warstwie prezentacji, warstwie domeny i warstwie infrastruktury).
źródło
Modelowanie oparte na domenach polega na oddzieleniu podstawowego modelu domeny i jego istnieniu bez żadnych zależności od innych warstw i innych problemów związanych z aplikacją.
Pozwala to skupić się na samej domenie bez zakłóceń (takich jak koordynacja interfejsu użytkownika i usług trwałości).
źródło
źródło
Głównym powodem tych granic jest rozdzielenie obaw . Kod, który uzyskuje dostęp do magazynu danych, powinien tylko martwić się o dostęp do magazynu danych. Nie powinien ponosić odpowiedzialności za egzekwowanie zasad dotyczących danych. Ponadto interfejs powinien być odpowiedzialny za aktualizowanie kontrolek w interfejsie, uzyskiwanie wartości z danych wejściowych użytkownika i tłumaczenie ich na coś, z czego warstwa domeny może korzystać, i nic więcej. Powinien wywoływać operacje zapewniane przez warstwę domeny, aby wykonywać wszelkie niezbędne działania (np. Zapisać ten plik). Wywoływana usługa internetowa powinna być odpowiedzialna za konwersję z medium transmisyjnego na coś, z czego może korzystać warstwa domeny, a następnie wywołać warstwę domeny (większość narzędzi wykonuje za Ciebie wiele pracy).
Ta separacja, jeśli zostanie poprawnie zaimplementowana, może pozwolić ci na zmianę części twojego kodu bez wpływu na inne. Na przykład być może kolejność sortowania zwróconej kolekcji obiektów wymaga zmiany. Ponieważ wiesz, że warstwa odpowiedzialna za manipulowanie danymi (zwykle warstwa logiki biznesowej) obsługuje te rzeczy, możesz łatwo określić, gdzie należy zmienić kod. Oprócz tego, że nie muszę modyfikować sposobu, w jaki jest pobierany ze magazynu danych lub dowolnej aplikacji korzystającej z domeny (interfejs użytkownika i usługa internetowa z mojego przykładu powyżej).
Ostatecznym celem jest uczynienie twojego kodu tak łatwym w utrzymaniu, jak to możliwe.
Na marginesie, niektóre rzeczy nie mogą być zaszufladkowane w określonej warstwie domeny (np. Rejestrowanie, sprawdzanie poprawności i autoryzacja). Te elementy są powszechnie nazywane problemami przekrojowymi, aw niektórych przypadkach można je traktować jako warstwę, która sama w sobie jest widoczna i może być używana przez wszystkie pozostałe warstwy.
Osobiście uważam, że podejście warstwowe jest przestarzałe, a podejście serwisowe jest lepsze. Nadal masz wyraźną linię narysowaną na piasku, kto co robi, ale to nie zmusza cię do bycia tak hierarchicznym. Na przykład usługa zamówienia zakupu, usługa fakturowania i usługa wysyłki, z perspektywy aplikacji wszystkie te usługi reprezentują Twoją domenę, a odroczenie odpowiedzialności, którą opisałem powyżej, jest nadal aktualne w tym kontekście, właśnie zostało zmienione takie że Twoja domena istnieje w wielu miejscach, dodatkowo wykorzystując koncepcję separacji problemów.
źródło