控制器清洁。模型中的学说

时间:2015-04-24 10:09:16

标签: doctrine-orm zend-framework2

我想让我的控制器变薄,并将业务逻辑与其他操作分开。例如,我有一个动作:

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中拥有什么? 谢谢

1 个答案:

答案 0 :(得分:4)

从控制器中删除业务逻辑是代码重用和可维护性的好主意;但是我建议不要将逻辑移到你的模型上。更好的解决方案是在您的应用程序中添加服务层

什么是服务层? Martin Fowler describes it as the following

  

[服务层]定义应用程序与一层服务的边界,这些服务建立一组可用操作并协调应用程序在每个操作中的响应。

这实际上意味着我们在控制器和模型之间添加了一个类。

这种方法的最大优点是,如果您需要更新应用程序的业务逻辑,则无需更新控制器。控制器也不会意识到任何特定的代码,因此可以在其他不相关的项目中重复使用。

此“服务”可以有一个简单的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
                }
            }
        }
        //
    }


}