SlideShare a Scribd company logo
1 of 31
Download to read offline
DDD
Основы доменной модели
Основные понятия
Контекст - ограниченная зона ответственности.
Сущность - модель объекта предметной области.
Сводный корень - сущность, предоставляющая общий
API.
Объект-значение - свойство объектов предметной
области.
Службы - операции характерные для предметной
области.
Знакомьтесь, доменный эксперт.
Доменный эксперт - человек или группа
людей обладающие необходимыми
знаниями и опытом в предметной области.
Hello world!
Система управления складом.
Задачи:
1) Упорядочить прием товаров на склад.
2) Организовать систему заявок на выдачу.
3) Оповещать менеджмент о нехватке
товаров.
Первый взгляд
Как я представляю
склад:
Т
О
В
А
Р
Ы

Склад

М
А
Г
А
З
И
Н

Как Geek&Poke
видят склад:
Единый язык
Система терминов, понятная как IT
специалисту, так и эксперту в предметной
области.
ent?

m
Ship

Goods

?

Ite

Product!
m?
Доменный эксперт говорит что...
“Поставщики привозят на склад контейнеры
с товарами.”

Поставщик

Контейнер
Склад

Поставщик

Контейнер
Доменный эксперт говорит что...
“В каждом контейнере могут быть разные
товары и в разном количестве, кроме того у
каждого товара есть срок годности.”
Контейнер
Товар:
Продукт:
Товар:
- название;
Товар:
- название;
- срок год.;
- название;
- срок год.;
- срок год.

Товар:
- название;
- срок год.

Товар:
Товар:
- название;
- название;
- срок год.;
- срок год.
Доменный эксперт говорит что...
“Когда товар попадает на склад, мы
записываем дату поступления.”
Склад
Товар:
Товар:
- название;
Товар:
- название;
- срок год.;
- название;
- срок год.;
- дата пос.
- срок год.;
- дата пос.
- дата пос.
Промежуточный итог
Контейнер
Пр
Товар
Товар
Товар

Товар

Товар
Товар
Склад

Контейнер
Пр
Товар
Товар
Товар

Товар
Товар
Товар
Товар

Товар
Товар

Да, да… очень
похоже на то, что у
нас происходит.
Пишим код ..! Product
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.

class Product
{
public function __construct(Name $name, DateTime $expirationDate
)
{
$this->name = $name;
$this->expirationDate = $exipationDate
;
}
public function accept(DateTime $deliveryDate)
{
$this->deliveryDate = $deliveryDate;
return $this;
}
public function isExpired()
{
return $this->expirationDate > new DateTime();
}
}
Пишим код ..! Container
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.

class Container
{
private $products;
public function __construct(array $products)
{
Assertion
::allIsInstanceOf
($products, 'Product');
$this->products = $products;
}
public function getProducts()
{
return $this->products;
}
}
Пишим код ..! Supplier
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.

class Supplier
{
public function sendProducts(Warehouse $receiver, array $products)
{
$this->sendContainer($receiver, new Container($products));
}
public function sendContainer
(Warehouse $receiver, Container $container)
{
$receiver->acceptContainer
($container);
}
}
Пишим код ..! Warehouse
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.

class Warehouse
{
private $products;
public function acceptContainer
(Container $container)
{
$now = new DateTime();
$products = $container->getProducts();
foreach ($products as $product) {
$name = $product->getName();
$this->products[$name][] = $product->accept($now);
}
}
}
Доменный эксперт говорит что...
“Кажется мы забыли упомянуть что у нас
два склада, и еще один строится рядом с
кольцевой.”
Склад
- номер
- адрес
- статус

Склад
- номер
- адрес
- статус

Склад
- номер
- адрес
- статус
Рефакторим ..! Warehouse.
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.

class Warehouse implements Entity
{
private $id;
private $address;
private $status;
public function __construct(WarehouseId $id, Address $address, Status $status = null)
{
$this->id = $id;
$this->address = $address;
$this->status = $status ?: new Status(Status::CLOSED);
}
public function acceptContainer
(Container $container)
{
if ($this->status->isClosed()) {
throw new Exception("Warehouse closed"
);
}
...
}
Объекты-значения
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.

class Status
{
const CLOSED = 0;
const OPENED = 1;

1) Равенство объектов-значений
основано на равенстве их полей.

private $value;
public function __construct($value)
{
$this->value = $value;
}

3) Строковое представление
объектов-значений должно быть
однозначно.

public function isClosed()
{
return self::CLOSED === $this->value;
}
}

2) Объекты-значения неизменны.

4) Объекты значения могут хранить
не только примитивы, но и другие
объекты и даже сущности.
Сущности
1) Равенство сущностей основано
на равенстве их идентификаторов.
Кстати, неплохо было бы
знать какой именно
поставщик нам привез эти
помидоры.

2) Основная единица бизнеслогики.
3) Имена сущностей и их методы
должны иметь смысл в контексте
единого языка.
Рефакторим ..! Supplier
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.

class Supplier implements Entity
{
private $id;
public function __construct(SupplierId $id)
{
$this->id = $id;
}
public function getId()
{
return $this->id;
}
public function sendProducts(Warehouse $receiver, array $products)
{
$this->sendContainer(new Container($products, $this
));
}
...
Система управления складом
1) Упорядочить прием товаров на склад.
2) Организовать систему заявок на выдачу.
3) Оповещать менеджмент о нехватке
товаров.
Доменный эксперт говорит что...
“Магазины подают заявки на получение
товаров со склада.”

Заявка
Магазин
Склад

Заявка
Доменный эксперт говорит что...
“В заявке указаны требуемые наименования
товаров и их количество.”
Заявка
- номер;
- товар => кол-во.;
- товар => кол-во.;
- товар => кол-во.;
- товар => кол-во.;
- ...

Ну и, естественно, мы не
отгружаем товары с
истекшим сроком годности.
Их надо сразу списывать.
Доменный эксперт говорит что...
“Если на складе достаточно товаров, то
заявке одобряется и машина с товарами
отправляется в магазин.”
Заявка
Магазин
Склад

Машина
Пишим код ..! Receipt
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.

class Receipt implements Entity
{
public function __construct(ReceiptId $id, Shop $receiver)
{
$this->id = $id;
$this->receiver = $receiver;
}
public function addRequire(Name $name, $count)
{
Assertion
::integer($count);
Assertion
::greater($count, 0);
$this->requires[$name] = $count;
}
public function getList()
{
return $this->requires;
}
}
Пишим код ..! Shop
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.

class Shop implements Entity
{
private $id;
private $address;
public function __construct(ShopId $id, Address $address)
{
$this->id = $id;
$this->address = $address;
}
public function createReceipt
(array $products)
{
$receipt = new Receipt(new ReceiptId(new DateTime), $this);
foreach ($products as $name => $count) {
$receipt->addRequire(new Name($name), $count);
}
return $receipt;
}
}
Пишим код ..! Warehouse
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.

class Warehouse implements Entity
{
public function resolveReceipt
(Receipt $receipt)
{
$toSend = [];
foreach ($receipt->getList() as $name => $count) {
$available = $this->getAvailable($name);
if ($count > count($available)) {
throw new AvailableException
($name, $available, $count);
}
$needed = array_slice($available, 0, $count);
$toSend = array_merge($toSend, $needed);
$this->writeOff($needed, new Reason('Resolved for receipt №'
.$receipt->getId()));
}
$receipt->resolve(new DateTime());
return new Car($toSend);
}
}
Сводный корень

А как изменять статус
заявки?

Сущность Warehouse производит
все бизнес-операции с сущностью
Receipt и отвечает за изменение ее
статуса: одобрено или отложено.
В данном случае сущность
Warehouse является сводным
корнем.
В различных контекстах возможны
разные сводные корни, например
Receipt может быть сводным
корнем для Product.
Контекст
В данном примере мы имеем два
распределенных контекста: поставщиксклад и склад-магазин.
Поставщик

Контейнер

Заявка
Магазин
Склад

Поставщик

Контейнер

Машина
Система управления складом
1) Упорядочить прием товаров на склад.
2) Организовать систему заявок на выдачу.
3) Оповещать менеджмент о нехватке
товаров.
Доменный эксперт говорит что...
“Знаете, мы понятия не имеем, что нужно
знать менеджерам и как они работают с
нашим складом. Давайте поговорим об этом
завтра с Аланом.”
Код домена и задание от Алана можно
посмотреть на GitHub.
Вопросы?
Антон Шабовта
E-mail: zloyusr@gmail.com
Facebook: https://www.facebook.com/zloyusr
VK: http://vk.com/shabouta

More Related Content

Similar to Основы доменной модели

Расширенное кеширование Doctrine2 (Ильяс Салихов, Intaro)
Расширенное кеширование Doctrine2 (Ильяс Салихов, Intaro)Расширенное кеширование Doctrine2 (Ильяс Салихов, Intaro)
Расширенное кеширование Doctrine2 (Ильяс Салихов, Intaro)Symfoniacs
 
Расширенное кеширование в Doctrine2
Расширенное кеширование в Doctrine2Расширенное кеширование в Doctrine2
Расширенное кеширование в Doctrine2Ilyas Salikhov
 
DevConf 2012 - Yii, его разработка и Yii2
DevConf 2012 - Yii, его разработка и Yii2DevConf 2012 - Yii, его разработка и Yii2
DevConf 2012 - Yii, его разработка и Yii2Alexander Makarov
 
Database (Lecture 14 – database)
Database (Lecture 14 – database)Database (Lecture 14 – database)
Database (Lecture 14 – database)Noveo
 
Yii 2. Что нового?
Yii 2. Что нового?Yii 2. Что нового?
Yii 2. Что нового?yiiconf
 
YiiConf 2012 - Alexander Makarov - Yii2, что нового
YiiConf 2012 - Alexander Makarov - Yii2, что новогоYiiConf 2012 - Alexander Makarov - Yii2, что нового
YiiConf 2012 - Alexander Makarov - Yii2, что новогоAlexander Makarov
 
Что нового в Android O (Grodno HTP)
Что нового в Android O (Grodno HTP)Что нового в Android O (Grodno HTP)
Что нового в Android O (Grodno HTP)Kirill Rozov
 
Top 10 problems supporting Magento customers
Top 10 problems supporting Magento customersTop 10 problems supporting Magento customers
Top 10 problems supporting Magento customersaheadWorks
 
PHP Tricks
PHP TricksPHP Tricks
PHP TricksBlackFan
 
DevPoint 2016: Признаки плохого кода и как с ним бороться в PHP проектах - Па...
DevPoint 2016: Признаки плохого кода и как с ним бороться в PHP проектах - Па...DevPoint 2016: Признаки плохого кода и как с ним бороться в PHP проектах - Па...
DevPoint 2016: Признаки плохого кода и как с ним бороться в PHP проектах - Па...DevPoint Kyiv
 
Чуть сложнее чем Singleton: аннотации, IOC, АОП
Чуть сложнее чем Singleton: аннотации, IOC, АОПЧуть сложнее чем Singleton: аннотации, IOC, АОП
Чуть сложнее чем Singleton: аннотации, IOC, АОПKirill Chebunin
 
Коротко о React.js
Коротко о React.jsКоротко о React.js
Коротко о React.jsMad Devs
 
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 1)
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 1)ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 1)
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 1)ZFConf Conference
 
ZFConf 2011: Разделение труда: Организация многозадачной, распределенной сист...
ZFConf 2011: Разделение труда: Организация многозадачной, распределенной сист...ZFConf 2011: Разделение труда: Организация многозадачной, распределенной сист...
ZFConf 2011: Разделение труда: Организация многозадачной, распределенной сист...ZFConf Conference
 
Easy authcache 2 кэширование для pro. Родионов Игорь
Easy authcache 2   кэширование для pro. Родионов ИгорьEasy authcache 2   кэширование для pro. Родионов Игорь
Easy authcache 2 кэширование для pro. Родионов ИгорьPVasili
 
WebCamp: Developer Day: Parse'им бэкенд - Аким Халилов
WebCamp: Developer Day: Parse'им бэкенд - Аким ХалиловWebCamp: Developer Day: Parse'им бэкенд - Аким Халилов
WebCamp: Developer Day: Parse'им бэкенд - Аким ХалиловGeeksLab Odessa
 
Yii development
Yii developmentYii development
Yii developmentMageCloud
 
Инструментируй это
Инструментируй этоИнструментируй это
Инструментируй этоRoman Dvornov
 

Similar to Основы доменной модели (20)

UWDC 2013, Yii2
UWDC 2013, Yii2UWDC 2013, Yii2
UWDC 2013, Yii2
 
Расширенное кеширование Doctrine2 (Ильяс Салихов, Intaro)
Расширенное кеширование Doctrine2 (Ильяс Салихов, Intaro)Расширенное кеширование Doctrine2 (Ильяс Салихов, Intaro)
Расширенное кеширование Doctrine2 (Ильяс Салихов, Intaro)
 
Расширенное кеширование в Doctrine2
Расширенное кеширование в Doctrine2Расширенное кеширование в Doctrine2
Расширенное кеширование в Doctrine2
 
DevConf 2012 - Yii, его разработка и Yii2
DevConf 2012 - Yii, его разработка и Yii2DevConf 2012 - Yii, его разработка и Yii2
DevConf 2012 - Yii, его разработка и Yii2
 
Database (Lecture 14 – database)
Database (Lecture 14 – database)Database (Lecture 14 – database)
Database (Lecture 14 – database)
 
Yii 2. Что нового?
Yii 2. Что нового?Yii 2. Что нового?
Yii 2. Что нового?
 
YiiConf 2012 - Alexander Makarov - Yii2, что нового
YiiConf 2012 - Alexander Makarov - Yii2, что новогоYiiConf 2012 - Alexander Makarov - Yii2, что нового
YiiConf 2012 - Alexander Makarov - Yii2, что нового
 
Что нового в Android O (Grodno HTP)
Что нового в Android O (Grodno HTP)Что нового в Android O (Grodno HTP)
Что нового в Android O (Grodno HTP)
 
Top 10 problems supporting Magento customers
Top 10 problems supporting Magento customersTop 10 problems supporting Magento customers
Top 10 problems supporting Magento customers
 
PHP Tricks
PHP TricksPHP Tricks
PHP Tricks
 
DevPoint 2016: Признаки плохого кода и как с ним бороться в PHP проектах - Па...
DevPoint 2016: Признаки плохого кода и как с ним бороться в PHP проектах - Па...DevPoint 2016: Признаки плохого кода и как с ним бороться в PHP проектах - Па...
DevPoint 2016: Признаки плохого кода и как с ним бороться в PHP проектах - Па...
 
Чуть сложнее чем Singleton: аннотации, IOC, АОП
Чуть сложнее чем Singleton: аннотации, IOC, АОПЧуть сложнее чем Singleton: аннотации, IOC, АОП
Чуть сложнее чем Singleton: аннотации, IOC, АОП
 
Коротко о React.js
Коротко о React.jsКоротко о React.js
Коротко о React.js
 
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 1)
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 1)ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 1)
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 1)
 
Deep Dive in Magento DI
Deep Dive in Magento DIDeep Dive in Magento DI
Deep Dive in Magento DI
 
ZFConf 2011: Разделение труда: Организация многозадачной, распределенной сист...
ZFConf 2011: Разделение труда: Организация многозадачной, распределенной сист...ZFConf 2011: Разделение труда: Организация многозадачной, распределенной сист...
ZFConf 2011: Разделение труда: Организация многозадачной, распределенной сист...
 
Easy authcache 2 кэширование для pro. Родионов Игорь
Easy authcache 2   кэширование для pro. Родионов ИгорьEasy authcache 2   кэширование для pro. Родионов Игорь
Easy authcache 2 кэширование для pro. Родионов Игорь
 
WebCamp: Developer Day: Parse'им бэкенд - Аким Халилов
WebCamp: Developer Day: Parse'им бэкенд - Аким ХалиловWebCamp: Developer Day: Parse'им бэкенд - Аким Халилов
WebCamp: Developer Day: Parse'им бэкенд - Аким Халилов
 
Yii development
Yii developmentYii development
Yii development
 
Инструментируй это
Инструментируй этоИнструментируй это
Инструментируй это
 

Основы доменной модели

  • 2. Основные понятия Контекст - ограниченная зона ответственности. Сущность - модель объекта предметной области. Сводный корень - сущность, предоставляющая общий API. Объект-значение - свойство объектов предметной области. Службы - операции характерные для предметной области.
  • 3. Знакомьтесь, доменный эксперт. Доменный эксперт - человек или группа людей обладающие необходимыми знаниями и опытом в предметной области.
  • 4. Hello world! Система управления складом. Задачи: 1) Упорядочить прием товаров на склад. 2) Организовать систему заявок на выдачу. 3) Оповещать менеджмент о нехватке товаров.
  • 5. Первый взгляд Как я представляю склад: Т О В А Р Ы Склад М А Г А З И Н Как Geek&Poke видят склад:
  • 6. Единый язык Система терминов, понятная как IT специалисту, так и эксперту в предметной области. ent? m Ship Goods ? Ite Product! m?
  • 7. Доменный эксперт говорит что... “Поставщики привозят на склад контейнеры с товарами.” Поставщик Контейнер Склад Поставщик Контейнер
  • 8. Доменный эксперт говорит что... “В каждом контейнере могут быть разные товары и в разном количестве, кроме того у каждого товара есть срок годности.” Контейнер Товар: Продукт: Товар: - название; Товар: - название; - срок год.; - название; - срок год.; - срок год. Товар: - название; - срок год. Товар: Товар: - название; - название; - срок год.; - срок год.
  • 9. Доменный эксперт говорит что... “Когда товар попадает на склад, мы записываем дату поступления.” Склад Товар: Товар: - название; Товар: - название; - срок год.; - название; - срок год.; - дата пос. - срок год.; - дата пос. - дата пос.
  • 11. Пишим код ..! Product 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. class Product { public function __construct(Name $name, DateTime $expirationDate ) { $this->name = $name; $this->expirationDate = $exipationDate ; } public function accept(DateTime $deliveryDate) { $this->deliveryDate = $deliveryDate; return $this; } public function isExpired() { return $this->expirationDate > new DateTime(); } }
  • 12. Пишим код ..! Container 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. class Container { private $products; public function __construct(array $products) { Assertion ::allIsInstanceOf ($products, 'Product'); $this->products = $products; } public function getProducts() { return $this->products; } }
  • 13. Пишим код ..! Supplier 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. class Supplier { public function sendProducts(Warehouse $receiver, array $products) { $this->sendContainer($receiver, new Container($products)); } public function sendContainer (Warehouse $receiver, Container $container) { $receiver->acceptContainer ($container); } }
  • 14. Пишим код ..! Warehouse 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. class Warehouse { private $products; public function acceptContainer (Container $container) { $now = new DateTime(); $products = $container->getProducts(); foreach ($products as $product) { $name = $product->getName(); $this->products[$name][] = $product->accept($now); } } }
  • 15. Доменный эксперт говорит что... “Кажется мы забыли упомянуть что у нас два склада, и еще один строится рядом с кольцевой.” Склад - номер - адрес - статус Склад - номер - адрес - статус Склад - номер - адрес - статус
  • 16. Рефакторим ..! Warehouse. 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. class Warehouse implements Entity { private $id; private $address; private $status; public function __construct(WarehouseId $id, Address $address, Status $status = null) { $this->id = $id; $this->address = $address; $this->status = $status ?: new Status(Status::CLOSED); } public function acceptContainer (Container $container) { if ($this->status->isClosed()) { throw new Exception("Warehouse closed" ); } ... }
  • 17. Объекты-значения 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. class Status { const CLOSED = 0; const OPENED = 1; 1) Равенство объектов-значений основано на равенстве их полей. private $value; public function __construct($value) { $this->value = $value; } 3) Строковое представление объектов-значений должно быть однозначно. public function isClosed() { return self::CLOSED === $this->value; } } 2) Объекты-значения неизменны. 4) Объекты значения могут хранить не только примитивы, но и другие объекты и даже сущности.
  • 18. Сущности 1) Равенство сущностей основано на равенстве их идентификаторов. Кстати, неплохо было бы знать какой именно поставщик нам привез эти помидоры. 2) Основная единица бизнеслогики. 3) Имена сущностей и их методы должны иметь смысл в контексте единого языка.
  • 19. Рефакторим ..! Supplier 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. class Supplier implements Entity { private $id; public function __construct(SupplierId $id) { $this->id = $id; } public function getId() { return $this->id; } public function sendProducts(Warehouse $receiver, array $products) { $this->sendContainer(new Container($products, $this )); } ...
  • 20. Система управления складом 1) Упорядочить прием товаров на склад. 2) Организовать систему заявок на выдачу. 3) Оповещать менеджмент о нехватке товаров.
  • 21. Доменный эксперт говорит что... “Магазины подают заявки на получение товаров со склада.” Заявка Магазин Склад Заявка
  • 22. Доменный эксперт говорит что... “В заявке указаны требуемые наименования товаров и их количество.” Заявка - номер; - товар => кол-во.; - товар => кол-во.; - товар => кол-во.; - товар => кол-во.; - ... Ну и, естественно, мы не отгружаем товары с истекшим сроком годности. Их надо сразу списывать.
  • 23. Доменный эксперт говорит что... “Если на складе достаточно товаров, то заявке одобряется и машина с товарами отправляется в магазин.” Заявка Магазин Склад Машина
  • 24. Пишим код ..! Receipt 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. class Receipt implements Entity { public function __construct(ReceiptId $id, Shop $receiver) { $this->id = $id; $this->receiver = $receiver; } public function addRequire(Name $name, $count) { Assertion ::integer($count); Assertion ::greater($count, 0); $this->requires[$name] = $count; } public function getList() { return $this->requires; } }
  • 25. Пишим код ..! Shop 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. class Shop implements Entity { private $id; private $address; public function __construct(ShopId $id, Address $address) { $this->id = $id; $this->address = $address; } public function createReceipt (array $products) { $receipt = new Receipt(new ReceiptId(new DateTime), $this); foreach ($products as $name => $count) { $receipt->addRequire(new Name($name), $count); } return $receipt; } }
  • 26. Пишим код ..! Warehouse 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. class Warehouse implements Entity { public function resolveReceipt (Receipt $receipt) { $toSend = []; foreach ($receipt->getList() as $name => $count) { $available = $this->getAvailable($name); if ($count > count($available)) { throw new AvailableException ($name, $available, $count); } $needed = array_slice($available, 0, $count); $toSend = array_merge($toSend, $needed); $this->writeOff($needed, new Reason('Resolved for receipt №' .$receipt->getId())); } $receipt->resolve(new DateTime()); return new Car($toSend); } }
  • 27. Сводный корень А как изменять статус заявки? Сущность Warehouse производит все бизнес-операции с сущностью Receipt и отвечает за изменение ее статуса: одобрено или отложено. В данном случае сущность Warehouse является сводным корнем. В различных контекстах возможны разные сводные корни, например Receipt может быть сводным корнем для Product.
  • 28. Контекст В данном примере мы имеем два распределенных контекста: поставщиксклад и склад-магазин. Поставщик Контейнер Заявка Магазин Склад Поставщик Контейнер Машина
  • 29. Система управления складом 1) Упорядочить прием товаров на склад. 2) Организовать систему заявок на выдачу. 3) Оповещать менеджмент о нехватке товаров.
  • 30. Доменный эксперт говорит что... “Знаете, мы понятия не имеем, что нужно знать менеджерам и как они работают с нашим складом. Давайте поговорим об этом завтра с Аланом.” Код домена и задание от Алана можно посмотреть на GitHub.
  • 31. Вопросы? Антон Шабовта E-mail: zloyusr@gmail.com Facebook: https://www.facebook.com/zloyusr VK: http://vk.com/shabouta