Назад к задачам
Junior — Senior
19

Реструктуризация кода в системе онлайн‑магазина

Получайте помощь с лайвкодингом в реальном времени с Sobes Copilot
Условие задачи

В проекте онлайн‑магазина присутствуют несколько классов, описывающих товары и их хранилища. Реализованы две основные операции: резервирование товара и пополнение его количества. Требуется переписать код так, чтобы он был готов к дальнейшему расширению и лучше соблюдал принципы инкапсуляции.

namespace MyAwesomeShop;

final readonly class ProductId {}

final class NotEnoughProductInStock extends \Exception {}

interface ProductRepository
{
    public function get(ProductId $productId): Product;
    public function save(Product $product): void;
}

final class Product
{
    public int $quantity = 0;

    public function __construct(
        public readonly ProductId $productId,
        public string $title,
        public string $description = '',
    ) {}
}

final readonly class InventoryService
{
    public function __construct(
        private ProductRepository $repository,
    ) {}

    public function reserve(ProductId $itemId, int $amount): void
    {
        $product = $this->repository->get($itemId);

        if ($product->quantity < $amount) {
            throw new NotEnoughProductInStock();
        }

        $product->quantity -= $amount;

        $this->repository->save($product);
    }

    public function replenish(ProductId $itemId, int $amount): void
    {
        $product = $this->repository->get($itemId);
        $product->quantity += $amount;
        $this->repository->save($product);
    }
}