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: 

 

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:


namespace App\Context\Application\Repository;

interface UserDiscountRepository 
{
	public function discountAllowed(int $userId): bool;
}


Oraz jego implementacji InMemory:


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.

 

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