我知道这可能是重新启动服务层和存储库模式的另一个主题,但是"我仍然没有找到我正在寻找的东西" (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,并在所有实体中使用它 必须管理一个帖子列表。
您对此解决方案有何看法?如果有另一种方式以懒惰的方式从不同的存储库加载对象,而不混合存储库,请告诉我!
提前致谢!