Domain Driven Development

Post on 14-Jul-2015

317 views 0 download

Transcript of Domain Driven Development

Domain Driven Design

!= Anemic Domain Model

Agenda● Dlaczego projektowanie dziedziny jest ważne?● Czym różni się od modelu anemicznego?● OO i OOP oraz SOA zamiast pisania procedur.● Ubiquitous Language.● Bounded Context.● Context Mapping i wzorce integracyjne.● Core Domain.● Architektura warstwowa i wzorce projektowe.● Dependency Injection oraz Aspect Oriented Programming.

Projektowanie dziedziny● Bardzo ważne przy tworzeniu złorzonego

oprogramowania.● Obiektowy model dziedziny, posiada stan i

zachowanie.● Rozwiązanie problemów złożoności.● Modelowanie rozwiązywanego problemu.● Odpowiedzialność we właściwym miejscu.● DRY

Model anemiczny dziedziny● Przerośnięta warstwa usług, zawiera całą logikę

biznesową.● Trudna w utrzymaniu warstwa usług.● Degradacja warstwy dziedziny.● Przeniesienie korzyści na rzecz fasady.● Ograniczenie możliwości testowania modelu.

Programowanie zorientowane obiektowo

● OOP stworzone dla lepszego rozwiązywania problemów.

● Zacierane przez niektóre technologie np. EJB, nie ma obiektów mamy np. encje, beany.

● Wprowadzenie terminu POJO – zwykłe obiekty języka Java.

● Często obsługa logiki sprowadza się do pisania kodu procedur.

Ubiquitous Language● Tworzony w czasie rozmów z klientem.● Wspólny język dla dziedziny, wynika z analizy.● Wspólny język projektu dla projektantów,

programistów zaczerpnięty z żargonu świata rzeczywistego.

Związany kontekst● Każdy model ma swój kontekst.● Integralność modelu.● Jest logiczną ramą rozwijanego modelu.● Pojedyńczy model łatwiej zarządzany przez jeden

zespół.● Każdy związany kontekst powinien mieć nazwę

ze wspolnego języka opisu.

Mapa kontekstu

Mapa kontekstu cd.● Shared Kernel● Customer-Supplier● Conformist● Separate Ways● Open Host Services● Anticorruption Layer

Mapa kontekstu cd.● Shared Kernel oraz Customre-Supplier to

wzorce dajace wysoki stopien interakcji pomiedzy kontekstami.

● Separate Way może być stosowany jeśli chcemy by konteks był odseparowany i rozwijany oddzielnie.

● Open Host Service oraz Anticorruption Layer w przypadku interakcji z zewnetrznymi systemami.

Mapa kontekstu cd. Shared Kernel

Mapa kontekstu cd. Shared Kernel

● Redukuje duplikacje, ale w dalszym ciągu utrzymuje odseparowane konteksty. Wymaga uwagi gdyż różne zespoły modyfikują rdzeń.

● Testy oraz Continuous Integration.

Mapa kontekstu cd. Customer-Supplier

● Jeśli jeden podsystem zalerzy mocno od innego.● Rezultat procesu jest przekazywany do

podsystemu.● Zespoły są mocno zainteresowane wzajemną

relacją tworzonych podsystemów.● Dostawca powinien wspierać klienta.

Mapa kontekstu cd. Conformist

● Podobnie jak w przypadku wzorca Shared Kernel, jednak bez możliwości dokonywania zmian.

● Jeśli używanykomponent ma złorzony interfejs, używane w modelu jako własny.

● Jeśli komponent ma niewielki interfejs, warto zastanowić się nad adapterem do translacji pomiędzy naszym modelem a modelem z którego komponent się wywodzi.

Mapa kontekstu cd. Anticorruption Layer

● Jeśli integracja przez protokół komunikacyjny, lub przez bazę danych.

● Brak informacji o modelu, dostępne są prymitywne dane.

● Istnieje ukryta semantyka danych.● Potrzeba izolacji modelu od systemu

zewnętrznego.

Mapa kontekstu cd. Anticorruption Layer

● Warstwa komunikuje się z zewnętrznym modelem wykorzystując zewnętrzny język.

● Spełnia formę dwu kierunkowego translatora pomiędzy dziedzinami i językami.

● Service jako fasada z zastosowaniem adaptera.

Mapa kontekstu cd. Anticorruption Layer

Mapa kontekstu cd. Separate Ways

● Jeśli jest pewność że można podzielić aplikację na kilka mniejszych niezależnych od siebie aplikacji.

Mapa kontekstu cd. Open Host Service

● Jeśli podsystem ma się integrować z różnymi klientami i trzeba tworzyć warstwę translacji dla każdego.

● Potrzeba utworzenia jednego protokołu komunikacji reprezentującego przeźroczystą grupę usług.

Mapa kontekstu

Core Domain● Po pierwsze wyszukanie i zdefiniowanie głównej

domeny projektu jako najbardziej priorytetowej.● Zaniedbania w tej części mogą stać się

katastrofalne dla systemu.● Podporządkowanie innych części jako wsparcie.

Core Domain cd.Generic Subdomains

● Istotne dla funkcionowania systemu i pełnego wyrażenia modelu.

● Identyfikowanie spójntch poddomen, które jednak nie są motorem działania systemu.

● Osadzanie w osobnych modułach.

Architektura warstwowa.● Interfejs użytkownika - prezentacja i interpretacja poleceń

użytkownika.● Warstwa aplikacji - koordynuje czynności aplikacji. Nie zawiera

logiki bienzsowej ani stanu obiektów biznesowych. Zachowuje stan zadań.

● Warstwa dziedziny – serce aplikacji, zarządza informacją o dziedzinie. Stan obiektów biznesowych. Utrwalanie obiektów w warstwie infrastruktury.

● Warstwa infrastruktury – jest wsparciem dla innych warstw. Dostarcza komunikację między warstwami, implementuje utrwalanie obiektów, zawiera dodatkowe wsparcie dla interfejsu użytkownika.

Wzorce projektowe● Implementacja modelu, też może zawieść.

Wzorce projektowe cd.● Entities● Value Objects● Services● Aggregates● Factories● Repositories

Wzorce projektowe cd.Entities

● Posiadają tożsamość.● Nie zmieniają stanu.● Są to instancje trzymane w pamięci.● Referencja spełnia warunek tożsamości.● Kombinacja unikalnych atrybutów.● Konieczny obiekt w modelu dziedziny.

Wzorce projektowe cd.Value Objects

● Nie posiada tożsamości.● Ważne są atrybuty.● Ułatwia to tworzenie obiektów i zwalnianie.● Powinny być immutable (tworzone przez

konstruktor i niemodyfikowalne).● Mogą być współdzielone, zachowują integralność

danych.● Mogą zawierać inne obiekty VO lub referencje do

Entity.

Wzorce projektowe cd.Services

● Nie wszystkie aspekty domeny mogą być mapowane do obiektów.

● Jeśli akcja nie jest w zasięgu obiektu.● Nie posiada wewnętrznego stanu.● Grupuje funkcionalność dla wielu obiektów.● Interfejsy dostarczające operacje wewnątrz

konceptu dziedziny.● Operacje są bezstanowe.

Wzorce projektowe cd.Aggregates

● Należy do cyklu życia obiektu domeny.● Określa właściwości obiektu i jego granice.● Asocjacje one-to-one, one-to-many, many-to-

many.● Bidirectional ale samochod ma silnik.● Aggregates posiada jednego roota – Entity

(jedyny obiekt widziany z zewnątrz)

Wzorce projektowe cd.Factories

● Tworzą złorzone czasem struktury Encji I Agregatów.

● Proces musi być atomowy tak aby obiekty były we własciwym stanie.

Wzorce projektowe cd.Repositories

● Baza danych jest częscią infrastruktury.● Może przetrzymywać referencje do obiektów.

Wzorce projektowe

Dependency Injection● public class MoneyTransferServiceImpl implements MoneyTransferService {● private final AccountRepository accountRepository;● private final BankingTransactionRepository bankingTransactionRepository;● @Autowired

● public MoneyTransferServiceImpl(AccountRepository accountRepository,● BankingTransactionRepository

● bankingTransactionRepository) {

● this.accountRepository = accountRepository;● this.bankingTransactionRepository = bankingTransactionRepository;● }

● public class HibernateAccountRepository● implements AccountRepository {● private HibernateTemplate hibernateTemplate;● @Autowired

● public HibernateAccountRepository(HibernateTemplate template) {● hibernateTemplate = template;

● }

● }

Dependency Injection● <beans>

● <context:annotation-config/>

● <bean name="moneyTransferService" class="MoneyTransferServiceImpl"/>

● <bean name="accountRepository" class="HibernateAccountRepository"/>

● </beans>

AOP● <bean id="authorization.loggingListener" class="...impl.listener.LoggingListener" />

● <bean id="authorization.ConnectionAdvice" class="...impl.listener.ConnectionAorund">

● <property name="Listeners" >

● <list>

● <ref bean="authorization.loggingListener" />

● </list>

● </property>

● </bean>

● <aop:config>

● <aop:pointcut id="authorization.ConncetionPointcut" expression="execution(* ...impl.helper.TopUpConnection.*Invocation(..))" />

● <aop:aspect id="authorization.ConnectionAspect" ref="authorization.ConnectionAdvice">

● <aop:around method="around" pointcut-ref="authorization.ConncetionPointcut"/>

● </aop:aspect>

● </aop:config>

AOP● public Object around(ProceedingJoinPoint call) throws Throwable {● for(Listener listener : listeners) {● notify(listener, call, null);● }

● Object result = call.proceed();

● for(Listener listener : listeners) {● notify(listener, call, result);

● }

● return result;● }

Literatura● Domain-Driven Design: Tackling Complexity in the

Heart of Software – Eric Evans● Patterns of Enterprise Application Architecture –

Martin Fowler● http://domaindrivendesign.org● http://martinfowler.com