Loading presentation...

Present Remotely

Send the link below via email or IM

Copy

Present to your audience

Start remote presentation

  • Invited audience members will follow you as you navigate and present
  • People invited to a presentation do not need a Prezi account
  • This link expires 10 minutes after you close the presentation
  • A maximum of 30 users can follow your presentation
  • Learn more about this feature in our knowledge base article

Do you really want to delete this prezi?

Neither you, nor the coeditors you shared it with will be able to recover it again.

DeleteCancel

Make your likes visible on Facebook?

Connect your Facebook account to Prezi and let your likes appear on your timeline.
You can change this under Settings & Account at any time.

No, thanks

Domain Driven Design - A place for everything and everything in its place

General Idea, Real model, Make explicit what is implicit, All Building Blocks, Events, Sagas, Bounded Context, Domain Distillation, CqRS
by

Sławek Sobótka

on 16 March 2012

Comments (0)

Please log in to add your comment.

Report abuse

Transcript of Domain Driven Design - A place for everything and everything in its place

Trener i doradca


Community



Twórca oprogramowania – całościowe podejście O sobie Java EE
Inżynieria oprogramowania prezes Stowarzyszenia Software Engineering Professionals Polska
blogger, autor
członek rady programowej JDD i 4Developers Technologie Architektury Najlepsze praktyki Wzorce Metodyki Software
Craftsmanship Ewolucja Modelu ? Procesy ewolucyjne są ślepe. Czasem osiągają lokalne maksimum, z którego nie mogą się już wydostać.

Richard Dawkins Architektura aplikacji DDD Jeżeli ktoś rozróżnia naukę (poznanie) i zabawę, to nie zrozumiał żadnego z tych pojęć. Infrastruktura
(dostęp do danych, servisy techniczne) Logika Aplikacji Prezentacja Serwis aplikacyjny @Transactional
@Service
//...
public class OrderService{
..@Autowired
..private OrdersRepository ordersRepository;
..@Autowired
..private PreductsRepository productssRepository;

..public void addProductToOrder(Long orderId, Long productId, int quantity){
....Order order = ordersRepository.load(orderId);
....Product product = productssRepository.load(productId);

....order.addProduct(product, quantity);

....ordersRepository.save(order);
..}
} Jeżeli robisz coś i zaczyna być to skomplikowane, to robisz to źle. Sławomir Sobótka slawomir.sobotka@bottega.com.pl http://art-of-software.blogspot.com/


http://ssepp.pl Naruszenie Bounded Context public class Client extends AggregateRoot {

....public void changeStatus(ClientStatus status){
........this.status = status;
........//wiecej logiki biznesowej

........if (status == VIP){
............//rabat na niezrealizowane zamówienia
........}
....}
} Problemy z modelem domeny Standardy projektowe Tendencja do wzrostu entropii
(czyżby drugie prawo termodynamiki?) Wszechobecny Spaghetti-monster Mała podatność na zmiany Krucha struktura XML Kolejny framework webowy SOA Nowa
specyfiakcja
platformy,
servera Nowy
język Złożoność Esencjonalna Przypadkowa zależy od problemu
wynika z jego natury i jest nieunikniona zależy od rozwiązania
wynika z wybranego podejścia i może być nieograniczona:) Brak Modelu lub Model jedynie na początku po prostu dodajemy (gdzieś) ficzery
myląca, nieadekwatna dokumentacja Niespójny żargon wymaga translacji
translacja prowadzi do błędów i niezrozumienia
"głuchy telefon" Model czysto analityczny nieimplementowalny
upada najszybciej Model w ujęciu DDD Serce systemu - największa wartość
Daje przewagę (nad konkurencją)
Powód tworzenia projektu
Modelowanie jest największym wyzwaniem w projekcie Do czego służy model? Model wymaga opieki... nieustanne zbieranie wiedzy
o regułach
zachowaniu
wspólne rozumienie
żargon
słownictwo Ubiquitous Language Jak zacząć z DDD? Certified Procedural Programmer? Czy DDD aplikuje się w moim kontekście? "Welcome to the Real World Neo" W projekcie brakuje czasu/pieniędzy na rzetelne modelowanie... Core
Domain Supporting Domain Generic
Domain Warunki konieczne Opłacalność przy złożonych, nietrywialnych domenach
Iteracyjny proces - "kruszenie" wiedzy
Dostęp do eksperta domenowego
Skillset teamu: OOD, raczej inteligencja werbalna niż
algorytmiczna Wspólny model
Wspólny język Logika Biznesowa
(model domeny) Serwisy aplikacyjne cienka warstwa
orkiestracja obiektów biznesowych
technikalia: transakcje, bezpieczeństwo,... Domain Model Building Blocks Entity Aggregate Value Object Serwis (biznesowy) Policy rich, not anemic
odpowiedzialność charakterystyczna dla danego bytu technicznie: graf encji
enkapsulacja
jednostka logiki biznesowej (jednostka spójności) wrapper dla typów prostych
zwiększenie ekspresji modelu biznesowego
uwypuklenie koncepcji biz.
koniec z utilsami:) w odróżnieniu od aplikacyjnego
czynność, która nie jest charakterystyczna dla żadnego Agregatu/Encji/VO
uwypuklenie koncepcji biznesowej technicznie: Strategy Design Pattern
uwypuklenie wariacji procesu biznesowego IoC na poziomie logiki biz.
komunikacja pomiędzy Bounded Context Zdarzenie (wydarzenie) biznesowe Factory tworzy złożone agregaty - również część logiki biz.
dba o poprawność - nie istnieją obiekty w niepoprawnym stanie
technicznie: drastycznie zwiększa testability zarządza trwałością Agregatu/Encji
nie zawiera 150 wyszukiwarek (tak jak DAO)
ew. wyszukiwanie biznesowe Repository Alternatywa: Command+CommandHandler w architekturze Command query Responsibility Segregation Specification modelowanie logiki wyboru Encji/Agregatów spełniających kryteria biznesowe
technicznie: drzewo warunków połączonych operatorami logicznymi Listener kilku zdarzeń
Modeluje proces wymagający zajścia kilku wydarzeń
Persystentny stan Saga if (p1 == null) ...
if (p1 > 1) ...
//chwileczkę... 80% to 0.8 czy 80? Double probability = p1 * p2; Probability p1 = Probability.fromPercent(80.0);
...
Probability probability = p1.and(p2); "Make explicit what is implicit" Aggregate @Entity
public class Order extends AggregateRoot{
..@OneToMany
..private List<OrderItem> items;

..@Embeded
..private Money sum;

..private RebatePolicy rebatePolicy;

..//status, createDate, rebatePolicy

..public Order(RebatePolicy rebatePolicy){
....this.rebatePolicy = rebatePolicy;
....sum = new Money(0.0);
....//...
}

..public void add(Product p, int quantity){
....OrderItem oi = orderItemFactory.build(p, quantity, rebatePolicy);
....items.add(oi);
....sum = sum.add(oi.getCost());
}

..//zwracamy niemodyfikowalną listę Value Objects aby ukryć impl
..public List<OrderedProduct> getOrderItems(){
....return repack(items);
..}
} Factory Ukrywa złożoność tworzenia Agregatu
Zapewnia poprawny stan
Enkapsuluje logikę biznesową związaną z wyborem Polityki Polityka public interface RebatePolicy{
..public Money calculateRebate(...);
} Serwis aplikacyjny - C.D. Servis Biznesowy (Building Block) @Service
@Transactional
//..
public class OrderService{
..@Autowired
..private OrdersRepository ordersRepository;
..@Autowired
..private InvoicesRepository invoicesRepository;

..public void submitOrder(Long orderId, Payment payment){
....Order order = ordersRepository.get(orderId);
....order.confirm(payment);

....BookKeeperService bookKeeper = new BookKeeperService();//testability!!!
....Invoice invoice = bookKeeper.generateInvoice(order);

....ordersRepository.save(order);
....invoicesRepository.save(invoice)
..}
} "Make explicit what is implicit" Serwis Biznesowy @Entity
public class Order extends AggregateRoot{

..public void confirm(Payment payment){
....if (status == CONFIRMED)
......throw new InvalidStateException();

....status = CONFIRMED;
....createDate = new Date();

....fireEvent(orderEventsFactory.orderSubmitted(getId()));
..}

} Aggregate - C.D. Supple Design public class BookKeeperService{
..private TaxCalulatorPolicy taxCalculator;

..public BookKeeperService(...){
....//ew. wstrzyknięcie
..}

..public Invoice generateInvoice(Order order){
....//metoda, która nie pasuje do żadnego Agregatu
....//nie jest esencją istnienia Zamówienia
..}
} "Make explicit what is implicit" Listener Integracja z innymi Bounded Context "Make explicit what is implicit" Wydarzenie biznesowe
(fakt, który nieodwracalnie miał miejscje) Queue Można zastanowić się nad tym, które z DODATKOWYCH obliczeń muszą być wykonane natychmiast... Saga "Make explicit what is implicit" public class OrderTrackingSaga extends Saga<OrderTrackingSagaData>{

..@SagaAction
..public void handle(CustomerBilledForOrder event)
....memento.setCustomerHasBeenBilled(true);
....memento.setCustomerId(event.getCustomerId());
....memento.setOrderId(event.getOrderId());

....completeIfPossible();
..}

..@SagaAction
..public void handle(OrderSubmitted event){
....memento.setProductIdsInOrder = event.ProductIdsInOrder;
....memento.setCustomerId(event.getCustomerId());
....memento.setOrderId(event.getOrderId());

....completeIfPossible();
}

..private void completeIfPossible(){
....//if (...)
....//fire event, call cervice/send command
....markAsCompleted();
..} VipRebate WinterRebate Moduł CRM i Moduł Sprzedaży to dwa różne Bounded Context! różne modele
zwykle inny Ekspert Domenowy public class OrderItem{
..RebatePolicy rebatePolicy;

..public Money calculateCost(){
//logika biznesowa
Money rebate = rebatePolicy.calculateRebate(...);
//nieco więcej logiki
..}
} Bardziej odpowiedni poziom abstrakcji Baza danych nie jest modelem!!! "What Drives our Design?" Projektowanie, modelowanie ukierunkowane, skupione na pewnych aspektach (wybory priorytetów) Sfery wiedzy i aktywności,
obszarach tematycznych, w których użytkownik aplikuje oprogramowanie Value Object BigDecimal/int value;
Currency curency;
Timestamp currencyRateDate; http://code.google.com/p/ddd-cqrs-sample/ Easy != Simple <<Aggregate>> Order <<Aggregate>> Invoice <<Service>> BookKeeper <<Policy>> TaxCalculator <<Factory>> InvoiceFactory <<Specification>> OrderCriteria Architektura
Command-query
Responsibility Segregation Rozwiązanie problemów persystencji
Wydajność
Skalowanie Moduł Sprzedaży Moduł CRM Moduł Kadr
Full transcript