niedziela, 7 listopada 2021

ID w instrukcjach warunkowych

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