Доктрина2 лучшая практика, должны ли организации пользоваться услугами?

StackOverflow https://stackoverflow.com/questions/4465237

Вопрос

Я задал аналогичный вопрос некоторое время назад: Используя шаблон Mapper Data, должны ли объекты (объекты домена) знать о Mapper? Однако это было общее и Меня очень интересно, как сделать несколько вещей с Doctrine2..

Вот простой пример модель: каждая Thing может иметь Vote из User, а User может разыграть более одного Vote но только последний Vote счета. Потому что другие данные (Msssage, и т. д.) связан с Vote, когда второй Vote размещен оригинал Vote Нельзя просто обновлять, его нужно заменить.

В настоящее время Thing имеет эту функцию:

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

А также Vote заботится о настройке отношений:

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

Мне кажется, что обеспечение User только есть последний Vote считается чем -то Thing должен обеспечить, и Не какой -то сервисный слой.

Итак, чтобы сохранить это в модели, новый Thing Функция:

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

Так как же удалить Vote из модели домена? Я должен расслабиться Vote::setThing() Принять а NULL? Должен ли я включить какой -то сервисный слой, который Thing может использовать для удаления голосования? Как только голоса начнут накапливаться, это foreach будет медленным - если сервисный слой будет использован, чтобы разрешить Thing Чтобы искать Vote не загружая всю коллекцию?

Я определенно склоняюсь к использованию легкого сервисного слоя; Однако, Есть ли лучший способ справиться с этим типом вещей с Doctrine2, или я движусь в правильном направлении?

Это было полезно?

Решение

Я голосую за уровень обслуживания. Я часто боролся с попыткой добавить столько логики на саму сущность, и просто расстроился. Без доступа к EntityManager вы просто не можете выполнить логику запросов, и вы обнаружите, что используете много операций O (n) или ленивые наборы отношений, когда вам нужно только несколько записей (что супер хромым по сравнению со всеми преимуществами, которые предлагает DQL).

Если вам нужна помощь, чтобы преодолеть идею, что модель анемичной области всегда является анти-паттерном, посмотрите это презентация Мэтью Вейер О'Финни или этот вопрос.

И хотя я мог бы неверно истолковывать терминологию, я не совсем убежден, что сущности должны быть единственными объектами, разрешенными в вашей модели домена. Я бы легко рассмотрел, что сумма объектов объектов и их услуг составляет модель. Я думаю, что анти-паттерн возникает, когда вы в конечном итоге пишете сервисный слой, который практически не обращает внимания на разделение проблем.

Я часто флиртовал с идеей, чтобы все мои объекты были прокси -серверы для уровня обслуживания:

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

Однако, поскольку доктрина не имеет никакой системы событий обратного вызова при гидратации объектов, я не нашел элегантного способа внедрения объекта обслуживания.

Другие советы

Мой совет - поместить всю логику запросов в EntityRepository, а затем сделать интерфейс из него вроде:

class BlogPostRepository extends EntityRepository implements IBlogPostRepository {}

Таким образом, вы можете использовать интерфейс в ваших единичных тестах для объектов службы, и никакой зависимости от EntityManager не требуется.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top