这个问题并没有明确地与 ZF2 有关,但我经常从 ZF2 中获取 ques 作为我的代码。 也就是说,我在控制器操作中看到的大多数 ZF2 示例都包含流程输入。
例:
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
。 不要像我上面所做的那样在控制器中创建它。 但是由于Processor
依赖于知道$product
,而只是从$_GET
那里得到的,我看不到任何其他方法。
如果我想将Processor
注入控制器,我还必须将填充变量$product
行移到控制器之外。
如何在不严重破坏 OOP、ZF2 设计模式的情况下做到这一点? 就像在,我的印象是,任何与$_GET
有关的事情都应该在Controller
内完成,而不是在ControllerFactory
内完成。 除非我能打破这种模式?
如果您只想应用依赖反转原则。应用 DSLID 首字母缩略词,只需要进行一些更改。
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 nterface (SOL ID( 来改进
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);
}
}
现在,如果你不希望你的控制器负责启动创建过程(SOLID(,你可以再拆分一些。
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'));
}
}
上述服务/控制者及其工厂应向其服务经理/控制者
注册$config = [
'controllers' = [
'factories' [
'YourController' => 'YourControllerFactory',
],
],
'service_manager' = [
'factories' [
'ProcessorFactory' => 'ProcessorFactoryFactory',
],
],
];
当请求被调度到您的控制器时,控制器管理器返回一个注入了处理器的您的控制器实例。它获得哪个处理器取决于请求(RouteMatch 中的一个参数(。