这个问题没有明确关于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");
}
}`
内。除非我能打破这种模式吗?
答案 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中的参数)。