Doctrine2最佳实践,实体使用服务? [英] Doctrine2 Best Practice, Should Entities use Services?
问题描述
我稍后问过类似的问题:使用数据映射器模式,实体(域对象)是否知道映射器?然而,它是通用的,而且我真的很感兴趣如何完成一些事情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
可以有一个从
,用户
中投票用户
可能会投放多个投票
,但只有最后一个投票
计数。因为其他数据( Msssage
等)与投票
相关,当第二个投票
被放置在原始投票
不能更新,需要更换。
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;
}
和投票
关心设置关系:
public function setThing(Model_Thing $thing)
{
$this->thing = $thing;
$thing->votes[] = $this;
}
在我看来,确保用户
只有最后一个
投票
计数是 Thing
应该确保的东西,而不是某些服务层。
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 :: setThing()
接受 NULL
?我应该涉及某种服务层, Thing
可以用来删除投票吗?一旦投票开始累积,那么 foreach
会慢 - 如果一个服务层被用来允许 Thing
搜索投票
而无需加载整个集合
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,您根本无法执行查询逻辑,当您只需要几个记录(这是超级的)时,您会发现自己使用了大量O(n)操作或延迟加载整个关系集比较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屋!