我目前正在使用DDD(域驱动设计)来实现新的Zend Framework 2项目。一切正常,但我对应用程序服务有疑问。
我知道应用程序服务位于应用程序层,并且是域逻辑的入口点。例如,他们可以访问域服务或存储库。
我现在想知道将应用程序服务实现为控制器插件是否有意义。在传统的MVC应用程序中,此控制器插件可以处理来自被调用域服务或存储库的结果。根据这些结果,他们可以生成重定向响应或将数据/表单传递给ViewModel。如果这个逻辑封装在插件中,我的控制器只需要调用插件并返回插件的结果。
我对此完全错了吗?或者您是否愿意保持逻辑如何对域服务或控制器中的存储库的结果做出反应?
最诚挚的问候,
拉尔夫
答案 0 :(得分:2)
当然这是主观的,人们对这样的事情有强烈的意见......所以这里是我的:
AbstractActionController
或AbstractRestfulController
。没有以一种明显/可见的方式注入依赖项(如trough contructor方法),因此很难弄清楚控制器类实际上取决于什么
上。此外,因为所有插件(AbstractPlugin
相关)都依赖于控制器实例,从而切换上下文
http到控制台(如用于phpunit测试)可能会出现问题。还测试逻辑
写作/作为控制器插件提供迟早会
升级到包括测试和中的请求/响应对象
这是不必要的复杂性。我再次重申,这只是我的意见。我已经了解到很多模式可能会在一个奇怪的用例下崩溃,但到目前为止,上述几点对我和我的团队都有意义。
答案 1 :(得分:0)
作为我的解决方案的示例,您可以看到控制器操作:
public function showAction()
{
$service = $this->readProductEntityCommand;
$service->setId($this->params()->fromRoute('id'));
try {
$result = $service->execute();
} catch (ProductException $e) {
$this->flashMessenger()->addMessage($e->getMessage());
return $this->redirect()->toRoute('part3/product');
}
return new ViewModel(
array(
'productEntity' => $result->getData(),
)
);
}

以下是作为命令对象构建应用程序服务的示例
class ReadProductEntityCommand implements CommandInterface
{
protected $productRepository;
protected $id;
public function __construct(ProductRepositoryInterface $productRepository)
{
$this->productRepository = $productRepository;
}
public function setId($id)
{
$this->id = $id;
}
public function execute()
{
if (is_null($this->id)) {
throw new ProductIdInvalidException(
'Produkt ID wurde nicht angegeben.'
);
}
try {
$product = $this->productRepository->getProduct(
new ProductIdCriterion(
new ProductId($this->id)
)
);
} catch (\Exception $e) {
throw new ProductNotFoundException(
'Es konnten kein Produkt gelesen werden.'
);
}
if ($product === false) {
throw new ProductNotFoundException('Produkt wurde nicht gefunden.');
}
$result = new Result();
$result->setValid(true);
$result->setData($product);
$result->setMessage('Produkt wurde gelesen.');
return $result;
}
}

也许这有助于将来的某个人。