webprogr.ru Новости

RSS

{{toodo.preview}}

...
{{toodo.name}}

{{toodo.preview}}

далее..

{{toodo.preview}}

{{toodo.name}}

{{toodo.preview}}

смотреть..

toodo.name

{{toodo.preview}}

{{toodo.name}}

{{toodo.preview}}

перейти...

{{toodo.preview}}

...
{{toodo.name}}

{{toodo.preview}}

далее..

{{toodo.preview}}

{{toodo.name}}

{{toodo.preview}}

смотреть..

toodo.name

{{toodo.preview}}

{{toodo.name}}

{{toodo.preview}}

перейти...


Последние новости

Лабораторная работа VII. Сервисы, Dependency Injection, autowiring и рефакторинг бизнес-логики

Лабораторная работа 7. Сервисы, Dependency Injection, autowiring и рефакторинг бизнес-логики

Аудиторная работа: 3 ак. ч.
Самостоятельная работа: 4 ак. ч.

Цель: вынести бизнес-правила из контроллеров в тестируемые сервисы.

Symfony построен вокруг Dependency Injection Container; при стандартной конфигурации autowiring позволяет внедрять зависимости по type hint. [19]

Задание

  1. Проанализируйте существующие контроллеры.

  2. Найдите бизнес-логику, которая не должна находиться в контроллере.

  3. Создайте:

src/Service/PricingService.php
src/Service/OrderService.php
src/Service/DashboardService.php
src/Service/OrderNumberGenerator.php

  1. Создайте интерфейс:

DiscountPolicyInterface

  1. Реализуйте минимум три политики:

RegularDiscountPolicy
VolumeDiscountPolicy
VipCustomerDiscountPolicy

  1. Каждая политика должна определять:

подходит ли она к заказу;
какую скидку применяет.

  1. Используйте constructor dependency injection.

  2. Запрещено:

$service = new PricingService(...);

внутри контроллера.

  1. Настройте autowiring.

  2. Одну зависимость настройте явно в:

config/services.yaml

  1. Добавьте параметр:

business.max_discount

  1. Значение:

30

  1. PricingService не должен позволять итоговую скидку выше указанного ограничения.

  2. Создайте enum:

OrderStatus

  1. Реализуйте правила перехода:

NEW -> CONFIRMED
CONFIRMED -> PAID
PAID -> SHIPPED
SHIPPED -> COMPLETED

  1. Реализуйте допустимый переход:

NEW -> CANCELLED
CONFIRMED -> CANCELLED

  1. Запретите:

COMPLETED -> NEW
CANCELLED -> PAID

  1. Переход статуса должен выполняться через OrderService.

  2. Создайте unit tests для каждого допустимого и недопустимого перехода.

  3. Создайте unit tests для каждой политики скидок.

  4. Используйте test doubles там, где это оправданно.

PHPUnit предоставляет механизмы test stubs и mock objects для изоляции тестируемых компонентов. [20]

  1. Выполните:

php bin/console debug:container

  1. Выполните:

php bin/console debug:container PricingService

  1. Сохраните результат:

docs/lab07-container.txt

Обязательный запрос ИИ-агенту рефакторинга

Ты — software architect.

Проанализируй src/Controller.

Найди:
бизнес-логику;
расчеты;
изменение статусов;
прямое использование EntityManager;
дублирующиеся правила.

Предложи рефакторинг в application/domain services.

Ограничения:
контроллер должен принимать HTTP request,
делегировать работу сервису,
формировать HTTP response.

Не создавай God Service.

Обязательный запрос ИИ-ревьюеру

Проверь dependency graph сервисов.

Найди:
циклические зависимости;
service locator anti-pattern;
скрытые зависимости;
создание сервисов через new;
избыточное использование EntityManager;
слишком большие сервисы.

Предложи минимальный рефакторинг.

Самопроверка

php bin/console lint:yaml config
php bin/console debug:container
php bin/phpunit

Критерии приемки

[ ] бизнес-логика вынесена из контроллеров
[ ] используется constructor injection
[ ] работает autowiring
[ ] имеется DiscountPolicyInterface
[ ] имеется минимум три реализации
[ ] реализованы правила статусов
[ ] недопустимые переходы блокируются
[ ] unit tests проходят
[ ] имеется AI log

Dependency injection делает зависимости класса явными и позволяет контейнеру Symfony автоматически создавать и связывать сервисы; constructor injection является штатно поддерживаемым вариантом. [21]

Рейтинг@Mail.ru