一个控制器和许多服务的设计模式

时间:2017-02-15 15:19:45

标签: php design-patterns model-view-controller solid-principles

我目前在MVC中面临以下问题的正确设计模式存在问题:

我有以下课程:

GroupController   
GroupService 
GroupUserController  
GroupUserService   
LogService

(一个组可能有很多用户)

对于每个控制器,我有CRUD,这对于具有特定角色的用户是可用的 其中一项功能是记录的用户可以创建组(GroupService)。如果他这样做,那么必须将他自动分配给用户组(GroupUserService)。我还需要将信息记录到LogService何时以及如何(通过CRUD或仅通过特定角色可用的方法)用户创建的组。

目前我有这样的事情:

// GroupController.php
// Create new group
public function setAction()
{
    //code...

    if ($this->getRequest()->isPost()) {
        $data = $this->request->getPost()->toArray();
        $form->setData($data);

        if ($form->isValid()) {
            $data = $form->getData();
            $result = $groupService->save($data, $data['id']);

            // Add user to that group
            if ($result) {
                $groupUserData = [
                    'group' => $result->getId(),
                    'user' => $user->getId()
                ];
                $result2 = $groupUserService->save($groupUserData); // <---- service which shouldn't be here?

                if ($result2) {
                    // Some other action let's say with another service
                }

                $logData = [
                    'msg' => 'New Group created!',
                    'created_at' => new \DateTime()
                ];
                $logService->save($logData); // <---- this service shouldn't be also here?
            }

            $this->redirect()->toRoute($this->route);
        }
    }

    return $this->viewModel;
}

目前,此操作正在执行许多任务,而不仅仅是一项。这不是违反SOLID原则的吗? 我认为这些服务不应该在这个控制器中。

我应该在这里使用哪些设计模式?责任链?观察?介体吗

我在许多控制器中遇到过这样的问题。我的意思是许多行动需要使用多种服务

2 个答案:

答案 0 :(得分:0)

我认为您可以使用外观模式,其目的是封装/隐藏某些过程的复杂性。

所以你可以创建一个包含一个包含所有动作逻辑的方法的类。并简单地从动作中调用它。

关于您的状态只有一点我认为您可能还需要一个事务来包装您的查询。

答案 1 :(得分:0)

分层架构可能对此有所帮助,尤其是六边形架构: http://alistair.cockburn.us/Hexagonal+architecture

使用它的最佳实用指南我知道是由Vaughn Vernon在下面的书中提供的: https://www.amazon.com/Implementing-Domain-Driven-Design-Vaughn-Vernon/dp/0321834577

总体思路:表示逻辑(请求/表单处理)需要与应用程序逻辑(用例流逻辑)和域逻辑(创建和保存组用户数据)分开