Skip to content

Commit

Permalink
описание README
Browse files Browse the repository at this point in the history
  • Loading branch information
gkarman committed Feb 18, 2024
1 parent 679e291 commit 4eb4652
Showing 1 changed file with 45 additions and 117 deletions.
162 changes: 45 additions & 117 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,133 +1,61 @@
Введение)
Текст домашнего задания

1. У меня на работе проект написан на Laravel
2. Мы используем библиотеку graphql для api

- Для того чтобы мне было понятно, как работать с DDD я поднял чистый laravel, поставил туда Rebing\GraphQL
- Для понимания принципов DDD не отвлекаясь на сложную логику специально упростил задачу.
- Задача: сохранить данные в БД, которые пришли.
Разрабатываем часть интернет-ресторана. Продаёт он фаст-фуд.
1. Фабричный метод будет отвечать за генерацию базового продукта-прототипа: бургер, сэндвич или хот-дог
2. При готовке каждого типа продукта Фабричный метод будет добавлять составляющие к базовому продукту либо по рецепту, либо по пожеланию клиента (салат, лук, перец и т.д.)
3. Цепочка обязанностей подписывается на статус приготовления и отправляет оповещения о том, что изменился статус приготовления продукта.
4. Стратегия будет отвечать за готовку продукта
5. Абстрактная фабрика будет генерировать заказы с сайта, из магазина и через телефон.
6. Все сущности должны по максимуму генерироваться через DI.

<hr>

Вот что получилось
1. Вызов старого и нового кода идет через файл app/config/graphql.php

```
'mutation' => [
'create_order' => CreateOrderMutation::class,
'create_order_old' => OldCreateOrderMutation::class,
],
```
1. У меня на работе проект написан на Laravel
2. Мы используем библиотеку graphql для api

2. Как работает старый код.
- Для того чтобы мне было понятно, как работать с DDD я поднял чистый laravel, поставил туда Rebing\GraphQL

Входная точка App\OldCode\GraphQL\Mutations\OldCreateOrderMutation по сути является контроллером,
но, так как это graphql то мы должны описать
- что к нам придет и какого это типа
- что мы отдаем и какого это типа
- правила валидации для данных
<hr>

## Описание по пунктам ДЗ

За логику отвечает класс CreateOrderService, так же в нем хранятся правила валидации в статическом методе на случай,
если они понадобятся еще где-то
1. класс App\Domains\Order\Domain\Factories\Product\ProductFactory
2. класс App\Domains\Order\Domain\Factories\Product\ProductFactory метод addIngredientsToProduct()
3. классы
- создание цепочки - App\Domains\Order\Domain\Subscribers\SendNotificationsService
- изменения статуса тут App\Domains\Order\Application\CockProductProcessUseCase
- запуск цепочки тут App\Domains\Order\Application\CockProductProcessUseCase ($this->publisher->notify($product);)
- подписание в сервис провайдере App\Infrastructure\Providers\AppServiceProvider

```
class OldCreateOrderMutation extends Mutation
{
protected $attributes = [
'name' => 'create_order_old',
'description' => 'Создание заявки старый код',
];
public function type(): Type
private function registerPublishers(): void
{
return Type::int();
$this->app->bind(PublisherProductChangeStatusInterface::class, function ($app) {
$publisher = new PublisherProductChangeStatus();
$publisher->subscribe(new SendNotificationsService());
});
}
public function args(): array
{
return [
'email' => [
'type' => Type::string(),
'description' => "Обязательный. email",
],
'title' => [
'type' => Type::string(),
'description' => "Обязательный. Заголовок заявки",
],
'description' => [
'type' => Type::string(),
'description' => "Обязательный. Описание заявки",
],
];
}
protected function rules(array $args = []): array
{
return CreateOrderService::rules($args);
}
public function resolve($root, $args, $context, ResolveInfo $info)
{
$service = new CreateOrderService();
return $service->run($args);
}
}
```




```
use App\OldCode\Models\Order;
use Illuminate\Support\Arr;
class CreateOrderService
4. классы
- стратения 1 App\Domains\Order\Domain\Strategies\Cock\FryingPanCockStrategy
- стратения 2 App\Domains\Order\Domain\Strategies\Cock\GrillCockStrategy
- выбор стратегии повесил в сервис провайдер App\Infrastructure\Providers\AppServiceProvider

```
private function registerStrategies(): void
{
public function run (array $args) : int
{
$order = new Order();
$order->email = Arr::get($args, 'email');
$order->title = Arr::get($args, 'title');
$order->description = Arr::get($args, 'description');
$order->save();
return $order->id;
}
public static function rules(array $args = [])
{
return [
'email' => ['required', 'string', 'email'],
'title' => ['required', 'string', 'max:50'],
'description' => ['required', 'string', 'max:255'],
];
}
$this->app->singleton(CockStrategyInterface::class, GrillCockStrategy::class);
}
```

4. Новый код DDD

Входная точка App\Domains\Order\Infrastructure\GraphQL\Mutations\CreateOrderService

1) что я сделал это код фреймворка в папке app перенес в app/Infrastructure
2) создал папку app/Domains в нее будут добавляться модули
3) создал папку app/Domains/Order - модуль для работы с Order
4) в папке app/Domains/Order разложил код на 3 уровня

Далее я сделал DTO для передачи данных из мутации в CreateOrderUseCase,
Создал CreateOrderUseCase, добавил ValueObjects для описания полей сущности, написал интерфейс для взаимодействия
с БД, а реализацию положин на слой инфрастуктуры. Все сделал как на уроке.


5. Что я понял работая с DDD
- Валидация на graphQl работает довольно хорошо. + хорошая обработка ошибок.
- Отвалидированные данные, оборачиваюсят в DTO и отдаются на слой приложения. Тут мы полностью ушли от привязки к graphql.
Это хорошо.
- Возникает не то, что избыточная валидация, ее много не бывает, но довольно тяжело это все писать. Одно и тоже на разных слоях.
Думаю это дань стабильности, но скорость разработки падает довольно сильно.
- Из-за того что в коде используется только 1 сущность, вроде все хорошо, но пока не знаю, что будет если
у order будет много связных данных, например user, company, depots, truck итд. При создании такой сущности приходит около
30 параметров, их нужно будет записывать в DTO потом каждое значение в VO. Нужно смотреть. В уроке не раскрыто это.
```

5. Создал 3 разных запроса api имитирующий создание заказа с разных мест.
- app/Domains/Order/Infrastructure/GraphQL/Mutations/CreateOrder/CreateOrderFromPhoneMutation.php
- app/Domains/Order/Infrastructure/GraphQL/Mutations/CreateOrder/CreateOrderFromShopMutation.php
- app/Domains/Order/Infrastructure/GraphQL/Mutations/CreateOrder/CreateOrderFromSiteMutation.php

- Самое важное, что старый код невозможно нормально тестировать
в App\Domains\Order\Application\CreateOrderUseCase метод run они передают нужную абстрактную фабрику
- App\Domains\Order\Domain\Factories\Order\OrderPhoneFactory
- App\Domains\Order\Domain\Factories\Order\OrderShopFactory
- App\Domains\Order\Domain\Factories\Order\OrderSiteFactory

0 comments on commit 4eb4652

Please sign in to comment.