加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

datamapper – Doctrine2最佳实践,实体应该使用服务吗?

发布时间:2020-12-15 05:05:22 所属栏目:Java 来源:网络整理
导读:我回答了一个类似的问题: Using the Data Mapper Pattern,Should the Entities (Domain Objects) know about the Mapper?然而,它是通用的,我真的很感兴趣如何用Doctrine2专门完成一些事情. 这是一个简单的示例模型:每个Thing可以有一个来自用户的投票,用户
我回答了一个类似的问题: 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没有任何类型的对象水合回调事件系统,我还没有找到一种优雅的方式来注入服务对象.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读