Doctrine2 最佳实践,实体应该使用服务吗? [英] Doctrine2 Best Practice, Should Entities use Services?

查看:12
本文介绍了Doctrine2 最佳实践,实体应该使用服务吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

不久前我问了一个类似的问题:使用数据映射器模式,实体(域对象)应该知道映射器吗? 然而,它是通用的,我真的很感兴趣如何用Doctrine2 具体.

I asked a similar question a while back: Using the Data Mapper Pattern, Should the Entities (Domain Objects) know about the Mapper? However, it was generic and I'm really interested in how to accomplish a few things with Doctrine2 specifically.

这是一个简单的示例模型:每个 Thing 都可以从 User 获得 VoteUser 可以投不止一个 Vote 但只有最后一个 Vote 算数.因为其他数据(Msssage等)与Vote相关,所以当第二个Vote放置时,原Vote> 不能只是更新,它需要被替换.

Here's a simple example model: Each Thing can have a Vote from a User, a User may cast more than one Vote but only the last Vote counts. Because other data (Msssage, etc) is related to the Vote, when the second Vote is placed the original Vote can't just be updated, it needs to be replaced.

目前Thing有这个功能:

public function addVote($vote)
{
  $vote->entity = $this;
}

并且Vote负责建立关系:

public function setThing(Model_Thing $thing)
{
  $this->thing = $thing;
  $thing->votes[] = $this;
} 

在我看来,确保 User 只计算最后一个 VoteThing 应该确保的,并且 不是某个服务层.

It seems to me that ensuring a User only has the last Vote counted is something the Thing should ensure, and not some service layer.

为了将其保留在模型中,新的 Thing 函数:

So to keep that in the Model, the new Thing function:

public function addVote($vote)
{
  foreach($this->votes as $v){
    if($v->user === $vote->user){
      //remove vote
    }
  }
  $vote->entity = $this;
}

那么如何从域模型中删除 Vote ? 我应该放松 Vote::setThing() 以接受 Vote代码>NULL?我是否应该涉及Thing 可以用来移除投票的某种服务层?一旦投票开始累积,foreach 将会变慢 - 是否应该使用服务层来允许 Thing 搜索 Vote 而无需必须加载整个集合?

So how do I remove the Vote from within the Domain Model? Should I relax Vote::setThing() to accept a NULL? Should I involve some kind of service layer that Thing can use to remove the vote? Once the votes start accumulating, that foreach is going to be slow - should a service layer be used to allow Thing to search for a Vote without having to load the entire collection?

我绝对倾向于使用轻型服务层;但是,是否有更好的方法来使用 Doctrine2 处理此类事情,还是我正朝着正确的方向前进?

I'm definitely leaning toward using a light service layer; however, is there a better way to handle this type of thing with Doctrine2, or am I heading in the right direction?

推荐答案

我投票给服务层.我经常努力尝试在实体本身上添加尽可能多的逻辑,只是让自己感到沮丧.如果无法访问 EntityManager,您根本无法执行查询逻辑,并且当您只需要几条记录(这是超级与 DQL 提供的所有优势相比,这是蹩脚的).

I vote for the service layer. I've often struggled with trying to add as much logic on the Entity itself, and simply frustrated myself. Without access to the EntityManager, you're simply not able to perform query logic, and you'll find yourself using a lot of O(n) operations or lazy-loading entire relationship sets when you only need a few records (which is super lame when compared to all the advantages DQL offers).

如果您需要一些帮助来克服贫血领域模型始终是反模式的想法,请参阅 此演示文稿 Matthew Weier O'Phinney 或此问题一>.

If you need some assistance getting over the idea that the Anemic Domain Model is always an anti-pattern, see this presentation by Matthew Weier O'Phinney or this question.

虽然我可能会误解这些术语,但我并不完全相信实体必须是域模型中唯一允许的对象.我很容易认为实体对象及其服务的总和构成了模型.我认为当您最终编写一个几乎不关注关注点分离的服务层时,就会出现反模式.

And while I could be misinterpreting the terminology, I'm not completely convinced that Entities have to be the only objects allowed in your Domain Model. I would easily consider that the sum of Entity objects and their Services constitutes the Model. I think the anti-pattern arises when you end up writing a service layer that pays little to no attention to separation of concerns.

我经常想到让我的所有实体对象将一些方法代理到服务层:

I've often flirted with the idea of having all my entity objects proxy some methods to the service layer:

public function addVote($vote)
{
   $this->_service->addVoteToThing($vote, $thing);
}

然而,由于 Doctrine 没有任何关于对象水合的回调事件系统,我还没有找到一种优雅的方法来注入服务对象.

However, since Doctrine does not have any kind callback event system on object hydration, I haven't found an elegant way to inject the service object.

这篇关于Doctrine2 最佳实践,实体应该使用服务吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆