I
I
Igor2021-07-16 11:45:55
symfony
Igor, 2021-07-16 11:45:55

How to separate abstraction from implementation?

Share your experience of separating abstraction from implementation in symfony.

The idea is the following:
We want to implement multiple implementations for the same action.

For example:

/**
     * @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());
    }


The "Bridge" pattern is used
I took an example here

What I would like to know.
-------------------------------------------------- ----------------------------
- Class storage structure.
- Initialization depending on the established rules.

What are the nuances?
Who solved a similar problem?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
B
BoShurik, 2021-07-16
@IgorPI

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 }

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question