Ассоциация Доменных Моделей Ленивая Загрузка

В настоящее время я сталкиваюсь с проблемой обработки ассоциаций между сущностями в совокупности.

Рассмотрим следующий пример:

Прямо сейчас у нас есть объект "Пользователь", который также является моим совокупным корнем. У него может быть ровно один "Продукт", связанный с ним, и много "Псевдонимов". В настоящее время мне нужна возможность поиска связанных "Продукт" и "Псевдонимы" по запросу в доменной модели. Пользователь создается UserFactory, которую можно использовать отдельно или также в UserRepository при создании сущностей из данных в постоянном режиме.

<?php
class User {
   private $id;

   private $aliases;
   private $product;

   public function isEligibleForCompanyPromotion() {
      //I need a good way to populate this without a performance bottleneck. 
      $product = $this->product;
      [.. code comparing things between User and Product begins ..]
   }     

}

Причина этого заключается в том, что наша бизнес-логика (как вы можете видеть в примере) во многом зависит от ассоциаций между объектами, и я полагаю, что эта логика, связанная с ассоциациями между объектами, должна выполняться в рамках модели предметной области (или, возможно, ее следует исключить?)

Я рассмотрел следующие решения:

1) Просто загрузите все (связанный продукт и псевдонимы), когда создается пользователь.

Плюсы:

  • Работает?

Минусы:

  • БОЛЬШАЯ проблема производительности (и, к сожалению, я работаю над живой системой с высокой нагрузкой, так что от этого нельзя отказаться)

2) Внедрить хранилище отношений в модель предметной области

  private $productRepository;
  private $aliasesRepository;
  [...]

}

Плюсы:

  • Работает..

Минусы:

  • Поражает ( imo) цель DDD, при этом от пользователя требуется наличие репозиториев внутри (поэтому модель домена связана с постоянством..)

3) Делегировать связанную с ассоциацией логику из доменной модели (может быть, в доменные службы и политики?)

Плюсы:

  • Также работает

Минусы:

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

4) Создайте специальный объект Relationship для обработки отношения:

<?php
class UserFactory { 

private $relationshipFactory;

public function createUser($persistenceData) {
    $user = new User();
    [.. creating of User, populating data etc .. ]
    $user->product = $this->relationshipFactory->createUserProductRelationship($user);
}

}


class UserProductRelationship {

    private $user;
    private $product;
    private $productRepository;

    [.. productRepository is being injected within relationshipFactory, and user is  provided ..]

    public function loadProduct() { 
      [.. load the product based on the relationship criterias ..]
    }

    [.. calls to this object are proxied to lazy-loaded product via __call, __get etc. )
}

Плюсы:

  • Также работает

Минусы:

  • Круговая зависимость (пользователь должен иметь внутри UserProductRelationship и полагаться на него. UserProductRelationship должен быть предоставлен с сущностью User. Объединение этих двух классов приведет к сценарию № 2).

Может быть, я что-то не поняла правильно... если у кого-нибудь есть предложение, я буду рада услышать об этом.

Спасибо!

1 ответ

Ввести объект спецификации, если некоторая ответственность не принадлежит какому-либо объекту или объекту домена требуется слишком много несвязанных данных для решения проблемы.

То, что вам нужно, - это ElptableForCompanyPromotionSpecification, например:

class EligibleForCompanyPromotion {
    private $productRepository;
    private $aliasesRepository;

    public function isSatisfiedBy(User user) {
       //I need a good way to populate this without a performance bottleneck. 
       $product = $productRepository.find(user.productId);
       [.. code comparing things between User and Product begins ..]
}   

class User {
   private $id;

   private $aliasesId;//only identifiers needed
   private $productId;//only identifiers needed 

В этом случае логика домена не просачивается на прикладной уровень, и нам не нужно внедрять репозитории в пользователя.

Другие вопросы по тегам