我可以在控制器工厂内读取GET的输入吗?

时间:2015-12-02 22:34:05

标签: php oop dependency-injection zend-framework2 factory-pattern

这个问题没有明确关于ZF2,但我经常从ZF2那里得到问题。也就是说,大多数ZF2示例我都在Controller Action中看到过程输入。

示例:

class YourController extends AbstractActionController
{

    public function doStuffAction()
    {
        // ZF2's way to get input from $_GET variable
        $product =  $this->getEvent()->getRouteMatch()->getParam('product');

        // Process    
        $processor = (new ProcessorFactory())->getProcessor($product);
        $output = $processor->processInput($data);
    }
}

现在,我喜欢Processor注入我的Controller。不像我上面那样在控制器内部创建它。但由于Processor取决于知道$product,而$_GET仅来自Processor,因此我没有看到任何其他方式。

如果我想将$product注入Controller,我必须移动将$_GET变量填充到Controller之外的行。

如何在不破坏OOP,ZF2设计模式的情况下这样做?同样,我认为与Controller有关的任何事情都要在ControllerFactory内完成,而不是在`else if (choice == 3) { if (Ptr->left != NULL) { system("CLS"); current = Ptr->left; std::cout << "Moved to the left item..." << std::endl; system("PAUSE"); } else { system("CLS"); std::cout << "Cannot move left any further..." << std::endl; system("PAUSE"); } }` 内。除非我能打破这种模式吗?

1 个答案:

答案 0 :(得分:1)

如果您只想应用依赖性倒置原则。应用 SOLID首字母缩略词的D,只需要进行一些更改。

class YourController
{

    /**
     * @var ProcessorFactory
     */
    protected $processorFactory;

    public function __construct(ProcessorFactory $processorFactory)
    {
        $this->processorFactory = $processorFactory;
    }

    public function doStuffAction()
    {
        $product =  $this->getEvent()->getRouteMatch()->getParam('product');
        $processor = $this->processorFactory->getProcessor($product);
    }
}

您可以通过键入 I 接口来改善(SOL I D)

class YourController
{

    /**
     * @var ProcessorFactoryInterface
     */
    protected $processorFactory;

    public function __construct(ProcessorFactoryInterface $processorFactory)
    {
        $this->processorFactory = $processorFactory;
    }

    public function doStuffAction()
    {
        $product =  $this->getEvent()->getRouteMatch()->getParam('product');
        $processor = $this->processorFactory->getProcessor($product);
    }
}

现在,如果您不希望您的Controller负责启动创建过程( S OLID),您可以将其拆分一些。

class YourController
{

    /**
     * @var ProcessorInterface
     */
    protected $processor;

    public function __construct(ProcessorInterface $processor)
    {
        $this->processor = $processor;
    }

    public function doStuffAction()
    {
        $processor = $this->processor;
    }
}

class ControllerFactory
{
    /**
     * @var ProcessorFactory
     */
    protected $processorFactory;

    public function  __construct(ProcessorFactory $processorFactory)
    {
        $this->processorFactory = $processorFactory;
    }

    public function create()
    {
        return new YourController($this->processorFactory->getProcessor());
    }
}

class ProcessorFactory
{
    /**
     * @var RouteMatch
     */
    protected $routeMatch;

    public function __construct(RouteMatch $routeMatch)
    {
        $this->routeMatch = $routeMatch;
    }

    public function getProcessor()
    {
        $processor = $this->createProcessor();
        // do stuff
        return $processor;
    }

    protected function createProcessor()
    {
        $product =  $this->routeMatch->getParam('product');

        // create processor

        return $processor;
    }
}

以下代码可以为您提供控制器。

$controllerFactory = new ControllerFactory(new ProcessorFactory(new RouteMatch()));
$yourController = $controllerFactory->create();

现在上面的代码是更通用的代码,不适用于ZF2。然后,一个好的举动将涉及ZF2的服务管理员。

class YourController extends AbstractActionController
{

    /**
     * @var ProcessorInterface
     */
    protected $processor;

    public function __construct(ProcessorInterface $processor)
    {
        $this->processor = $processor;
    }

    public function doStuffAction()
    {
        $processor = $this->processor;
    }
}


class YourControllerFactory implements FactoryInterface
{

    public function createService(ServiceLocatorInterface $controllers)
    {
        $services = $controllers->getServiceLocator();
        $processorFactory = $services->get('ProcessorFactory');
        return new YourController($processorFactory->getProcessor());
    }
}

class ProcessorFactory
{
    /**
     * @var RouteMatch
     */
    protected $routeMatch;

    public function __construct(RouteMatch $routeMatch)
    {
        $this->routeMatch = $routeMatch;
    }

    public function getProcessor()
    {
        $processor = $this->createProcessor();
        // do stuff
        return $processor;
    }

    protected function createProcessor()
    {
        $product =  $this->routeMatch->getParam('product');

        // create processor

        return $processor;
    }
}

class ProcessorFactoryFactory implements FactoryInterface
{

    public function createService(ServiceLocatorInterface $services)
    {
        return new ProcessorFactory($services->get('RouteMatch'));
    }
}

以上服务/控制器及其工厂应使用其ServiceManager / ControllerManager注册

$config = [
    'controllers' = [
        'factories' [
             'YourController' => 'YourControllerFactory',
        ],
    ],
    'service_manager' = [
        'factories' [
             'ProcessorFactory' => 'ProcessorFactoryFactory',
        ],
    ],
];

当请求被调度到YourController时,ControllerManager返回一个注入了Processor的YourController实例。它获得的处理器取决于请求(RouteMatch中的参数)。