在 PHP Symfony 4.4 中编写一个类,使用设计模式 Factory Method

使用激活自动装配的 Symfony 4.4,我想使用设计模式 FactoryMethod 实例化一个类。

实例化的类是具有传递给构造函数的自动装配参数的服务。

如果在工厂方法中实例化的每种类型的类的构造函数都相同,则它会很好地工作。

但是,每个要实例化的服务都必须自动装配一些特定的服务才能工作。

我发现我们可以使用“setter 依赖注入”。描述它的文章:

我试图实现 setter 依赖注入,但里面的代码永远不会执行。

考虑到这些文章,我们应该在调用 __construct 方法后立即使用 PHPDoc“@required”输入设置器(据我了解)。

它不适用于我的代码(见下文)。

我的实现是否正确?

有更好的方法吗?


隔江千里
浏览 91回答 1
1回答

侃侃无极

为了在 Symfony 中使用设计模式工厂方法,请使用服务定位器在控制器外部提供自动装配。将代码重构为以下内容:// Controller/** *@Route("/my_action/{param}") */public function my_action (ThingManagerFactory $thingManagerFactory, $param){    $thingManager = $thingManagerFactory->get($param);    $thingManager->doSomething();}// ThingManagerFactoryuse App\Locator\ThingLocator;class ThingManagerFactory{    private $locator;    public function __construct(ThingLocator $locator)    {        $this->locator = $locator;    }    public function get($param): ThingManagerInterface    {        if($param == 1) {            return $this->locator->get(Thing1Manager::class);        } elseif($param == 2) {            return $this->locator->get(Thing2Manager::class);        }        throw new \InvalidArgumentException("...");    }}// ServiceLocatorInterfaceinterface ServiceLocatorInterface{    public function get(string $id);}// ThingLocatorclass ThingLocator implements ServiceLocatorInterface, ServiceSubscriberInterface{    private $locator;    public function __ construct(ContainerInterface $locator)    {        $this->locator = $locator;    }    public function get(string $id)    {        if (!$this->locator->has($id)) {            throw new \Exception("The entry for the given '$id' identifier was not found.");        }        try {            return $this->locator->get($id);        } catch (ContainerExceptionInterface $e) {            throw new \Exception("Failed to fetch the entry for the given '$id' identifier.");        }    }    public static function getSubscribedServices()    {        return [            Thing1Manager::class,            Thing2Manager::class,        ];    }}// ThingManagerInterfaceinterface ThingManagerInterface{    public function doSomething();}// Thing1Managerclass Thing1Manager implements ThingManagerInterface{    // ...    private $spec1Manager;    public function __construct($firstManager, $secondManager, $thirdManager, $spec1Manager)    {        // ...    }    // This setter is no more needed. This manager can be added to the constructor method.    // **    // * @required    // */    //public function setSpecificManager(Spec1Manager $spec1Manager)    //{        // if not commented, this code would be called thanks to the Service Locator (which is a Symfony Service Container)    //    $this->spec1Manager = $spec1Manager;    //}    public function doSomething()    {        // ...    }}
打开App,查看更多内容
随时随地看视频慕课网APP