Introducing 

Prezi AI.

Your new presentation assistant.

Refine, enhance, and tailor your content, source relevant images, and edit visuals quicker than ever before.

Loading…
Transcript

Technologie

Najlepsze praktyki

Metodyki

Software

Craftsmanship

Jeżeli ktoś rozróżnia naukę (poznanie) i zabawę, to nie zrozumiał żadnego z tych pojęć.

http://code.google.com/p/ddd-cqrs-sample/

Jeżeli robisz coś i zaczyna być to skomplikowane, to robisz to źle.

Easy != Simple

Model wymaga opieki...

Ubiquitous Language

Sławomir Sobótka

Sfery wiedzy i aktywności,

obszarach tematycznych, w których użytkownik aplikuje oprogramowanie

ukierunkowane, skupione na pewnych aspektach (wybory priorytetów)

Projektowanie, modelowanie

Moduł Sprzedaży

Moduł CRM

Moduł Kadr

slawomir.sobotka@bottega.com.pl

Architektura aplikacji DDD

Prezentacja

Logika Aplikacji

Serwis aplikacyjny

Serwis aplikacyjny - C.D.

Serwisy aplikacyjne

Alternatywa: Command+CommandHandler w architekturze Command query Responsibility Segregation

@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);

..}

}

  • cienka warstwa
  • orkiestracja obiektów biznesowych
  • technikalia: transakcje, bezpieczeństwo,...

@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)

..}

}

Servis Biznesowy (Building Block)

<<Aggregate>>

Order

Invoice

<<Service>>

BookKeeper

<<Specification>>

<<Policy>>

TaxCalculator

OrderCriteria

<<Factory>>

InvoiceFactory

Wspólny model

Wspólny język

O sobie

Logika Biznesowa

(model domeny)

Aggregate

Aggregate - C.D.

Domain Model

Building Blocks

Aggregate

Entity

Value Object

Factory

Serwis Biznesowy

Value Object

BigDecimal/int value;

Currency curency;

Timestamp currencyRateDate;

  • technicznie: graf encji
  • enkapsulacja
  • jednostka logiki biznesowej (jednostka spójności)
  • rich, not anemic
  • odpowiedzialność charakterystyczna dla danego bytu
  • wrapper dla typów prostych
  • zwiększenie ekspresji modelu biznesowego
  • uwypuklenie koncepcji biz.
  • koniec z utilsami:)

if (p1 == null) ...

if (p1 > 1) ...

//chwileczkę... 80% to 0.8 czy 80?

Probability p1 = Probability.fromPercent(80.0);

...

Probability probability = p1.and(p2);

Double probability = p1 * p2;

  • Ukrywa złożoność tworzenia Agregatu
  • Zapewnia poprawny stan
  • Enkapsuluje logikę biznesową związaną z wyborem Polityki

Serwis (biznesowy)

Specification

Policy

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

..}

}

  • modelowanie logiki wyboru Encji/Agregatów spełniających kryteria biznesowe
  • technicznie: drzewo warunków połączonych operatorami logicznymi
  • 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

@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()));

..}

}

@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);

..}

}

Saga

Zdarzenie (wydarzenie) biznesowe

"Make explicit what is implicit"

  • Listener kilku zdarzeń
  • Modeluje proces wymagający zajścia kilku wydarzeń
  • Persystentny stan
  • IoC na poziomie logiki biz.
  • komunikacja pomiędzy Bounded Context

"Make explicit what is implicit"

Factory

Repository

  • 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

Bardziej odpowiedni poziom abstrakcji

"Make explicit what is implicit"

Wydarzenie biznesowe

(fakt, który nieodwracalnie miał miejscje)

Supple Design

Polityka

public interface RebatePolicy{

..public Money calculateRebate(...);

}

public class OrderItem{

..RebatePolicy rebatePolicy;

..public Money calculateCost(){

//logika biznesowa

Money rebate = rebatePolicy.calculateRebate(...);

//nieco więcej logiki

..}

}

VipRebate

WinterRebate

"Make explicit what is implicit"

Queue

Można zastanowić się nad tym, które z DODATKOWYCH obliczeń muszą być wykonane natychmiast...

Saga

Listener

Integracja z innymi Bounded Context

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();

..}

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

........}

....}

}

"Make explicit what is implicit"

Moduł CRM i Moduł Sprzedaży to dwa różne Bounded Context!

  • różne modele
  • zwykle inny Ekspert Domenowy
  • Java EE
  • Inżynieria oprogramowania

Infrastruktura

(dostęp do danych, servisy techniczne)

Trener i doradca

Community

Twórca oprogramowania – całościowe podejście

  • prezes Stowarzyszenia Software Engineering Professionals Polska
  • blogger, autor
  • członek rady programowej JDD i 4Developers

http://art-of-software.blogspot.com/

http://ssepp.pl

Architektury

Wzorce

Do czego służy model?

nieustanne zbieranie wiedzy

  • o regułach
  • zachowaniu

wspólne rozumienie

  • żargon
  • słownictwo

Model w ujęciu DDD

Baza danych nie jest modelem!!!

  • Serce systemu - największa wartość
  • Daje przewagę (nad konkurencją)
  • Powód tworzenia projektu
  • Modelowanie jest największym wyzwaniem w projekcie

Nowy

język

Standardy projektowe

SOA

Krucha struktura

Mała podatność na zmiany

Wszechobecny Spaghetti-monster

Tendencja do wzrostu entropii

(czyżby drugie prawo termodynamiki?)

Nowa

specyfiakcja

platformy,

servera

"What Drives our Design?"

XML

Kolejny framework webowy

Problemy z modelem domeny

  • nieimplementowalny
  • upada najszybciej

Model czysto analityczny

Złożoność

  • po prostu dodajemy (gdzieś) ficzery
  • myląca, nieadekwatna dokumentacja

Brak Modelu lub Model jedynie na początku

Niespójny żargon

Esencjonalna

Przypadkowa

  • wymaga translacji
  • translacja prowadzi do błędów i niezrozumienia
  • "głuchy telefon"
  • 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:)

"Welcome to the Real World Neo"

Ewolucja Modelu

W projekcie brakuje czasu/pieniędzy na rzetelne modelowanie...

Core

Domain

?

Procesy ewolucyjne są ślepe. Czasem osiągają lokalne maksimum, z którego nie mogą się już wydostać.

Richard Dawkins

Supporting Domain

Generic

Domain

Jak zacząć z DDD?

Czy DDD aplikuje się w moim kontekście?

Architektura

Command-query

Responsibility Segregation

Certified Procedural Programmer?

Warunki konieczne

  • Rozwiązanie problemów persystencji
  • Wydajność
  • Skalowanie
  • 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

Learn more about creating dynamic, engaging presentations with Prezi