IgorPI
@IgorPI

Как отделить абстракцию от реализации?

Поделитесь опытом отделения абстракции от реализации в symfony.

Идея следующая:
Мы хотим реализовать несколько реализаций для одного и того же действия.

Например:
/**
     * @Route(
     *     path="/bridge/call/{variant}",
     *     methods={"GET"}
     * )
     * @param string              $variant
     * @param AbstractionExecutor $abstractionExecutor
     *
     * @return Response
     */
    public function call(
        string              $variant,
        AbstractionExecutor $abstractionExecutor
    ): Response
    {
        if ($variant === 'b') {
            $abstractionExecutor->setImplementation(new ConcreteImplementationB());
        } else {
            $abstractionExecutor->setImplementation(new ConcreteImplementationA());
        }

        return new Response($abstractionExecutor->exec());
    }


Используется паттерн "Мост"
Взял пример здесь

Что хотелось бы узнать.
-----------------------------------------------------------------------------
- Структура хранения классов.
- Инициализация в зависимости от установленных правил.

Какие есть нюансы?
Кто решал похожую задачу?
  • Вопрос задан
  • 194 просмотра
Решения вопроса 1
BoShurik
@BoShurik Куратор тега Symfony
Symfony developer
interface ExecutorInterface
{
    public function exec(): string;
}

class ConcreteImplementationA implements ExecutorInterface
{
    public function exec(): string
    {
        return 'A';
    }
}

class ConcreteImplementationB implements ExecutorInterface
{
    public function exec(): string
    {
        return 'B';
    }
}

class VariantExecutor
{
    public function __construct(private ServiceLocator $locator)
    {
    }

    public function exec(string $variant): string
    {
        return $this->locator->get($variant)->exec();
    }
}

class Controller
{
    public function call(VariantExecutor $executor, string $variant): Response
    {
        return new Response($executor->exec($variant));
    }
}

#services.yaml
app.executor.locator:
    class: Symfony\Component\DependencyInjection\ServiceLocator
    arguments:
        -
            a: App\ConcreteImplementationA
            b: App\ConcreteImplementationB
    tags:
        - { name: container.service_locator }
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы