Przykład
Biznes decyduje się by konkretni użytkownicy mieli naliczani rabat do robionego zamówienia. W tym wpisie nie będę się skupiał na naliczaniu samego rabatu, tylko na to komu ma on zostać przyznany. Poniżej znajduje się najprostsza implementacja tego zadania:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | namespace App\Context\Application; final class OrderService { // ... public function createOrder( //... User $user ): void { // ... if (in_array( $user ->id(), [101,102])) { // give a discount } // ... } } |
Jak widać rabat dotyczy tylko użytkowników z ID 101 & 102.❌ Serwis Aplikacyjny ma teraz wiedzę o konkretnych ID z bazy MySQL, które nie powinny wychodzić poza Warstwę Infrastruktury. Można by utworzyć dodatkową klasę, która hermetyzowała by identyfikatory, ale tak czy inaczej musiałaby się znaleźć w Warstwie Aplikacji (lub co gorsza Domeny). Najprostrzym rozwiązaniem będzie wprowadzenie wyspecjalizowanego Repozytorium składającego się na interfejs:
1 2 3 4 5 6 | namespace App\Context\Application\Repository; interface UserDiscountRepository { public function discountAllowed(int $userId ): bool; } |
Oraz jego implementacji InMemory:
1 2 3 4 5 6 7 8 9 10 11 | namespace App\Context\Infrastructure\Repository; use App\Context\Application\Repository\UserDiscountRepository; final class UserDiscountInMemoryRepository implements UserDiscountRepository { public function discountAllowed(int $userId ): bool { return in_array( $userId , [101,102]); } } |
Wystarczy dodać zależność w postaci UserDiscountRepository do Serwisu Aplikacyjnego. W przypadku gdy będziemy rozwijać funkcjonalność, a użytkownicy z naliczanym rabatem będą dodawani do systemu dynamicznie - implementacja OrderService nie powinna ulec zmianie.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | namespace App\Context\Application; use App\Context\Application\Repository\UserDiscountRepository; final class OrderService { public function __construct( private UserDiscountRepository $userDiscountRepository ) {} // ... public function createOrder( //... User $user ): void { // ... if ( $this ->userDiscountRepository->discountAllowed( $user ->id())) { // give a discount } // ... } } |
Brak komentarzy:
Prześlij komentarz