控制器清洁。模型中的教义
Controller Cleaning. Doctrine in Model
我想让我的控制器变瘦,并将业务逻辑与其他操作分开。例如我有一个动作:
public function indexAction()
{
$languages = $this ->getEntityManager()
->getRepository('\ApanelLanguage\Entity\LanguageCommon')
->getLanguagesList();
$viewModel = new ViewModel(['languages' => $languages]);
return $viewModel;
}
但我想获得这样的操作:
public function indexAction()
{
$model = $new LanguageModel();
$model->getLanguagesList();
return $viewModel;
}
可以吗?我必须在 Language/Model/LanguageModel 中包含什么?
谢谢
从控制器中删除业务逻辑对于代码重用和可维护性来说是个好主意;但是我建议不要将逻辑移到您的模型中。更好的解决方案是向您的应用程序添加 服务层 。
什么是服务层? Martin Fowler describes it as the following:
[A service layer] defines an application's boundary with a layer of services that establishes a set of available operations and coordinates the application's response in each operation.
这实际上意味着我们在您的控制器和模型之间添加了一个 class。
这种方法的最大优势在于,如果您需要更新应用程序的业务逻辑,则无需更新控制器。控制器也变得不知道任何特定代码,因此可以在其他不相关的项目中重复使用。
这个'service'可以有一个简单的API,例如:
interface ServiceInterface
{
public function setObjectManager($objectManager);
public function setRepository($respository);
public function find($id);
public function fetchRow($criteria);
public function fetchAll($criteria);
public function insert($object);
public function update($object);
public function delete($object);
}
然后你可以为你的新'LanguageService'实现这个接口。
class LanguageService implements ServiceInterface
{
// ... all methods from interface
public function getLanguageList()
{
return $this->repository->getLanguagesList();
}
}
最后更新您的控制器以使用新服务
class FooController extends AbstractActionController
{
protected $languageService;
public function __construct(ServiceInterface $languageService)
{
$this->languageService = $languageService;
}
public function indexAction()
{
$languages = $this->languageService->getLanguageList();
$viewModel = new ViewModel(['languages' => $languages]);
return $viewModel;
}
public function insertAction()
{
$request = $this->getRequest();
$service = $this->languageService;
$form = $service->getInsertForm();
if ($request->isPost()) {
$form->setData($request->getPost());
if ($form->isValid()) {
// if our form used the DoctrineObjectHydrator
// we will get a entity back populated with the
// form data
$language = $service->insert($form->getData());
if ($language instanceof Entity\Language) {
// success
} else {
// failure
}
}
}
//
}
}
我想让我的控制器变瘦,并将业务逻辑与其他操作分开。例如我有一个动作:
public function indexAction()
{
$languages = $this ->getEntityManager()
->getRepository('\ApanelLanguage\Entity\LanguageCommon')
->getLanguagesList();
$viewModel = new ViewModel(['languages' => $languages]);
return $viewModel;
}
但我想获得这样的操作:
public function indexAction()
{
$model = $new LanguageModel();
$model->getLanguagesList();
return $viewModel;
}
可以吗?我必须在 Language/Model/LanguageModel 中包含什么? 谢谢
从控制器中删除业务逻辑对于代码重用和可维护性来说是个好主意;但是我建议不要将逻辑移到您的模型中。更好的解决方案是向您的应用程序添加 服务层 。
什么是服务层? Martin Fowler describes it as the following:
[A service layer] defines an application's boundary with a layer of services that establishes a set of available operations and coordinates the application's response in each operation.
这实际上意味着我们在您的控制器和模型之间添加了一个 class。
这种方法的最大优势在于,如果您需要更新应用程序的业务逻辑,则无需更新控制器。控制器也变得不知道任何特定代码,因此可以在其他不相关的项目中重复使用。
这个'service'可以有一个简单的API,例如:
interface ServiceInterface
{
public function setObjectManager($objectManager);
public function setRepository($respository);
public function find($id);
public function fetchRow($criteria);
public function fetchAll($criteria);
public function insert($object);
public function update($object);
public function delete($object);
}
然后你可以为你的新'LanguageService'实现这个接口。
class LanguageService implements ServiceInterface
{
// ... all methods from interface
public function getLanguageList()
{
return $this->repository->getLanguagesList();
}
}
最后更新您的控制器以使用新服务
class FooController extends AbstractActionController
{
protected $languageService;
public function __construct(ServiceInterface $languageService)
{
$this->languageService = $languageService;
}
public function indexAction()
{
$languages = $this->languageService->getLanguageList();
$viewModel = new ViewModel(['languages' => $languages]);
return $viewModel;
}
public function insertAction()
{
$request = $this->getRequest();
$service = $this->languageService;
$form = $service->getInsertForm();
if ($request->isPost()) {
$form->setData($request->getPost());
if ($form->isValid()) {
// if our form used the DoctrineObjectHydrator
// we will get a entity back populated with the
// form data
$language = $service->insert($form->getData());
if ($language instanceof Entity\Language) {
// success
} else {
// failure
}
}
}
//
}
}