Intro do Domain Driven Design. ( PL )

34
WSTĘP DO DDD Domain Driven Design w świecie PHP Piotr Kacała

Transcript of Intro do Domain Driven Design. ( PL )

WSTĘP DO DDDDomain Driven Design w świecie PHP

Piotr Kacała

O mnie

GOG.comSenior Web Developer

Czym się zajmuję?Utrzymywanie i rozwój kodu,szukanie rozwiązań

GOG.com

Historia Start w 2008 pod skrzydłami CD Projekt - zespół 10 osóbObecnie zatrudnionych jest ponad 70 osób

Obecna pozycja

#1 globalnej dystrybucji klasycznych gier na PC i Mac #2 globalnej dystrybucji gier indie na PC i Mac

Partnerzy 220+ twórców i wydawców gier

Klienci Ponad 2.7 miliona unikalnych wejść miesięcznie z całego świata

Gry Ponad 800 tytułów w kataloguPonad 39 milionów gier na kontach użytkowników

Agenda

1. Teoria chaosu (w kodzie)

2. Wprowadzenie do DDD

3. Design strategiczny

4. Krótko o architekturze

5. Design taktyczny

6. Podsumowanie i wnioski

Teoria chaosu

CZYM OBJAWIA SIĘ ROZKŁAD APLIKACJI?

• Niska podatność kodu na zmiany

• Zbyt mocno powiązane ze sobą komponenty

• Niespójna architektura

Teoria chaosu

JAK PRÓBUJEMY SOBIE PORADZIĆ?

• Przepisanie całości od podstaw

• Nowy framework

• Inny, modny język programowania

Teoria chaosu

SKĄD BIERZE SIĘ CHAOS?

• Nieumiejętność odnalezienia się w modelu biznesowym

• Reguły biznesowe ulegają ciągłym zmianom

Wprowadzenie do DDD

DOMAIN DRIVEN DESIGNZestaw narzędzi do projektowania i ochrony procesów zachodzących w złożonej domenie

DOMENASfera wiedzy, w której obraca się dana organizacja

Wprowadzenie do DDD

DOMAIN DRIVEN DESIGN

DESIGN STRATEGICZNY DESIGN TAKTYCZNY

Design strategiczny

WSZECHOBECNY JĘZYK

• Zbudowanie jednolitego słownika pojęć w domenie

• Używany zarówno przez developerów, jak i ekspertów domenowych

• Pomaga developerom zrozumieć biznes, w którym funkcjonują

• Pomaga ekspertom domenowym spojrzeć na problem oczami developera

• Ciągle udoskonalany

Design strategiczny

WSZECHOBECNY JĘZYK

Klient zamawia produkty i za nie płaci”“

Design strategiczny

OGRANICZONY KONTEKST

• Koncept książki• Znalezienie autorów• Proces pisania i poprawek• Zaprojektowanie layoutu książki i ilustracji• Przełożenie książki na inne języki• Produkcja fizycznych kopii • Format elektronicznych kopii• Marketing• Sprzedaż

Krótko o architekturze

Domena Logika biznesowa

Aplikacja Łączenie warstw, cross-cutting concerns

Prezentacja Kontrolery, widoki, UI

Infrastruktura Wypełnianie kontraktów technicznych

Krótko o architekturze

KOD W WARSTWIE DOMENY

• Baza danych nie istnieje

• Obiekty POPO

• Synergia z TDD

• Spójny, czytelny kod zorientowany na język biznesowy

Design taktyczny

KIM JEST DEVELOPER RAFAŁ?

• Rafał jest senior developerem w dobrze prosperującej firmie

• Rafał pracuje w kilkuosobowym zespole

• Rafał jest ewangelistą OOP i zaczął czytać Fowlera

• Rafał jakiś czas temu odkrył Symfony 2 i Doctrine 2

Design taktyczny

ZADANIE RAFAŁA

• Klient dodaje produkty do zamówienia

• Maksymalna liczba przedmiotów, które klient może zamówić w jednym zamówieniu to 3

• Po zapisaniu zamówienia klient otrzymuje maila z potwierdzeniem

Design taktyczny

// ... $totalCost = 0; $orderLines = []; foreach ($products as $product) { $totalCost += $product->getPrice(); $orderLines[] = new OrderLine($product->getId(), $product->getPrice()); } if (count($product) > 3) { throw new LogicException('Maksymalnie trzy produkty kliencie'); } $order = new Order(); $order->setCustomer($customer); $order->setOrderLines($orderLines); $order->setTotalCost($totalCost); $order->setStatus(OrderStatus::NEW); $em = $this->getDoctrine()->getManager(); $em->persist($order); $em->flush(); $message = new \Swift_Message(); // ...

IMPLEMENTACJA RAFAŁA

Design taktyczny

// ... $totalCost = 0; foreach ($products as $product) { $totalCost += $product->getPrice(); }

OPERACJE NA WARTOŚCIACH

Design taktyczny

VALUE OBJECT

• Określa wartość lub miarę

• Nie posiada identyfikatora

• Niezmienny w obrębie tej samej instancji (immutability)

• Stanowi zamkniętą całość

• Zapewnia walidację w obrębie klasy

• Side-Effect-Free

Design taktyczny

$total = new Money(0, new Currency('PLN')); // or Money::PLN(0);$total = $total->add($product->getPrice());

VALUE OBJECT

Design taktyczny

ENTITY

Posiadają ID Unikalne Cykl życia

Design taktyczny

if (count($product) > 3) { throw new LogicException('Maksymalnie trzy produkty kliencie'); } $order = new Order(); $order->setCustomer($customer); $order->setOrderLines($orderLines); $order->setTotalCost($totalCost); $order->setStatus(OrderStatus::NEW);

AGREGAT

Design taktyczny

class Order extends AggreagateRoot { public function __construct(Customer $customer) { $this->id = Uuid::uuid4(); $this->lines = new ArrayCollection(); $this->totalPrice = Money::PLN(0); $this->customer = $customer; } public function add(Product $product) { if ($this->lines->count() > self::PRODUCT_LIMIT) { throw new DomainException('...'); } $line = new OrderLine($product->id(), $product->price()); $this->lines->add($line); $this->totalPrice = $this->totalPrice->add($product->price()); $this->raise(new ProductWasAddedToCart($this->customer, $product->id()); } }

PRZYKŁAD AGREGATU

Design taktyczny

DEFINICJA AGREGATU

• Graf obiektów

• Jeden punkt wejścia - poprzez Aggregate Root

• Operacje w agregacie są granicami transakcji

• Ochrona reguł biznesowych

• Aggregate Root dostępne z poziomu repozytoriów

• Aggregate Root jest z technicznego punktu widzenia encją

Design taktyczny

AGREGAT ORDERU

ORDER LINE ORDER LINE ORDER LINE

ORDER

Design taktyczny

$em = $this->getDoctrine()->getManager(); $em->persist($order); $em->flush();

REPOZYTORIUM

Design taktyczny

// Domain (!) layer interface OrderRepository { public function orderOfId($orderId); public function save(Order $order); } // Infrastructure layer class OrderDoctrineOrmRepository implements OrderRepository { // ... } class OrderMongoDbRepository implements OrderRepository { // ... }

REPOZYTORIUM

Design taktyczny

EVENTY DOMENOWE

• Wyrażają wydarzenia istotne z punktu widzenia domeny

• Sposób na rozłączność kodu przez wprowadzenie listenerów

Design taktyczny

class Order { public function add(Product $product) { // ... $this->raise(new ProductWasAddedToCart($this->customer, $product->id()); } }

class OrderCreatedMessageSender { public function sendEmail(ProductWasAddedToCart $event) { // ... send email } }

EVENTY DOMENOWE

Podsumowanie

CZY DDD JEST DLA MNIE?

Tak jeśli:

• Twoja aplikacja dotyka złożonych procesów biznesowych

• Twoja aplikacja będzie się rozrastać

• Reguły biznesowe w aplikacji będą ulegać częstym zmianom

Nie jeśli:

• Twoja aplikacja jest w całości data-centryczna (CRUD)

• Jeżeli Twój model jest nieskomplikowany (i nie będzie) - blog, strona o kotkach

Podsumowanie

CO ZYSKUJE BIZNES?

• Organizacja zyskuje użyteczny model własnej domeny

• Kształtowanie definicji i zrozumienia zasad biznesowych

• Określenie wspólnego języka między developerami a ekspertami domenowymi

• Eksperci domenowi aktywnie przyczyniają się rozwoju aplikacji

• Czyste modele o ukierunkowaniu biznesowym

• Jasny podział na granice kontekstu ułatwia późniejszą integrację między teamami

• Ukierunkowanie na ciągły rozwój i dopracowanie modelu

Podsumowanie

CO ZYSKUJE DEVELOPER?

• Projektowanie ukierunkowane na biznes• Prawdziwe OOP• Uporządkowanie architektury• Spójny, czytelny, łatwy w rozwijaniu kod• Dobre wykorzystanie wzorców projektowych• Łatwość w testowaniu• Chronienie zasad biznesowych• Odporność na zmiany• Skupienie się na regułach biznesowych

SZUKAMY WEBDEVÓWWięcej informacji u mnie lub na stronie GOG.com/work

…i zapraszam po darmowego Wiedźmina :)

DZIĘKUJĘ ZA UWAGĘ