datamapper – Doctrine2最佳实践,实体应该使用服务吗?
我回答了一个类似的问题:
Using the Data Mapper Pattern,Should the Entities (Domain Objects) know about the Mapper?然而,它是通用的,我真的很感兴趣如何用Doctrine2专门完成一些事情.
这是一个简单的示例模型:每个Thing可以有一个来自用户的投票,用户可以投出多个投票,但只有最后一个投票计数.因为其他数据(Msssage等)与投票相关,所以当放置第二个投票时,原始投票不能仅仅被更新,它需要被替换. 目前Thing有这个功能: public function addVote($vote) { $vote->entity = $this; } 投票负责建立关系: public function setThing(Model_Thing $thing) { $this->thing = $thing; $thing->votes[] = $this; } 在我看来,确保用户只有最后一次投票是Thing应该确保的,not some service layer. 所以为了在模型中保留新的Thing函数: 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搜索投票而不必加载整个集合? 我绝对倾向于使用轻型服务层;但是,有没有更好的方法来处理Doctrine2这类事情,或者我是朝着正确的方向前进? 解决方法
我投票支持服务层.我经常努力尝试在实体本身添加尽可能多的逻辑,并且只是让自己感到沮丧.无法访问EntityManager,您根本无法执行查询逻辑,当您只需要几条记录时,您会发现自己使用了大量的O(n)操作或延迟加载整个关系集(这是超级的与DQL提供的所有优势相比,它是蹩脚的.
如果你需要一些帮助来克服贫血领域模型总是反模式的想法,请参阅Matthew Weier O’Phinney或this question的this presentation. 虽然我可能会误解术语,但我并不完全相信实体必须是域模型中允许的唯一对象.我很容易认为实体对象及其服务的总和构成了模型.我认为,当您最终编写一个几乎不关注关注点分离的服务层时,就会出现反模式. 我经常想到让所有实体对象将一些方法代理到服务层: public function addVote($vote) { $this->_service->addVoteToThing($vote,$thing); } 但是,由于Doctrine没有任何类型的对象水合回调事件系统,我还没有找到一种优雅的方式来注入服务对象. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |