使用事件管理的多服务层和存储库模式

时间:2017-04-14 12:35:29

标签: service repository

我知道这可能是重新启动服务层和存储库模式的另一个主题,但是"我仍然没有找到我正在寻找的东西" (U2 docet ......)

我正在使用包含十几个服务和存储库的复杂应用程序;举个例子的模式可能是这样的:

Controller
$return = $this->getUserService()->findAll();

class UserService
public function findAll()
return $this->getUserRepository()->findAll();

class UserRepository
/**
* 
* @return Collection of UserModel
*/
public function findAll(){
$sql = "SELECT * FROM `user` ";        
return $this->fetchAll($sql);
}

因此,对于数据库中的每个表,都有以下实体:

{Entity}Service
{Entity}Repository
{Entity}Model

在控制器中,我有一组UserModel对象,通过服务层从存储库层返回。

一切听起来不错,直到我们使用一张桌子;如果你必须使用多个服务/存储库,你通常如何工作?

1)问题编号1

我想在手术后发送电子邮件并增加统计数据;我可以在控制器中做到这一点,但可能在服务层可能更好,因为 在服务层,你应该添加你的业务逻辑。

所以我可以写:

Controller
    $this->getUserService()->doSomething($params);

class UserService
    public function doSomething($params);

    $ok = $this->getUserRepository()->do($params);
    $this->getMailService()->sendEmail($params);
    $this->getStatsService()->updateStats($params);

    return true;

通过这种方式,我必须添加许多服务访问单个服务;这样对吗? 如果所有这三个操作都严格关联,这是正确的方法,因为您可以在没有问题的情况下将服务方法移动到其他地方(API上下文,Web上下文),并且所有操作都将完好无损。 问题是您必须在UserService中注入服务,例如使用服务容器。 你怎么看?如果你必须一起执行许多操作,你如何继续?你改用控制器吗?

2)问题2

我有一个从此模式中获取的UserModel集合(Controller> Service> Repository> Service> Controller) 让我有一个具有依赖关系的UserModel,例如用户编写的帖子列表,我希望能够以懒惰的方式加载帖子列表。

我怎样才能达到这个目的? 我的用户存储库只从数据库返回用户表中的行,我不想添加连接,因为我不想在每个请求时加载帖子。 另一个问题是Post Models属于另一个Service>存储库(PostService和PostRepository)

我使用事件来解决这个问题;基本上,每个对依赖项对象的请求都会触发一个事件。

class UserModel
    protected $posts = null;

    public function setPosts($posts)
    $this->posts = $posts;

    public function getPosts()
        if(is_null($this->posts))
            $this->loadPosts();
        return $this->posts;

    protected function loadPost()
        Event::trigger(Event::LOAD_POST,['targetModel' => $this]);

Controller

    $users = $this->getUserService()->findAll();
    foreach($users as $user){
        $posts = $user->getPosts();
    }
    ...


$eventEmitter->on(Event::LOAD_POST, function(Event $e) {
    $targetModel = $e->getData('targetModel');
    if (!method_exists($targetModel, 'setPosts')) {
        return false;
    }
    $posts = $e->getContainer()
    ->get('post-service')
    ->findByUserId($targetModel->getUserId());
    $targetModel->setPosts($posts);
    return true;
});

基本上,当我询问模型的帖子列表并且相关的模型属性为NULL(不为空,但为NULL)时,我触发一个事件,传递对象我在。 触发器调用在应用程序引导期间注册的函数,该函数调用正确的服务并调用targetModel setter来加载对象。

通过这种方式,我解决了很多问题;我可以分开服务,避免在其他服务中提供太多服务。 我也可以重用这段代码;让我有很多带$ post的实体,我可以用属性,setter和getter创建一个PostTrait,并在所有实体中使用它 必须管理一个帖子列表。

您对此解决方案有何看法?如果有另一种方式以懒惰的方式从不同的存储库加载对象,而不混合存储库,请告诉我!

提前致谢!

0 个答案:

没有答案