Обновить сущность внутри агрегата - PullRequest
8 голосов
/ 26 августа 2011

Я читал аналогичный вопрос о SO: Как обновить сущность внутри Aggregate , но я все еще не уверен, как пользовательский интерфейс должен взаимодействовать с сущностями внутри агрегата.

Допустим, у меня есть User с кучей Address эс.Пользователь - это корень совокупности, а Адрес существует только в совокупности.

В веб-интерфейсе пользователь может редактировать свои адреса.По сути, происходит следующее:

  • Пользователь видит список адресов в своем веб-интерфейсе
  • Он нажимает на адрес и перенаправляется на эту страницу: edit-address?user=1&address=2
  • На этой странице он получает форму, в которой он может изменить этот адрес.

Если мы решили обойти корень агрегата, это будет просто:

  • Мы бы напрямую загрузили Address с Id
  • Мы обновили бы его, а затем сохранили его

Поскольку мы хотим сделать это способом DDD, у нас есть разныерешения:

  1. Либо мы просим пользователя получить этот адрес по Id :

    address = user.getAddress(id);address.setPostCode("12345");address.setCity("New York");em.persist(user);

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

  2. Или мы сообщаем агрегату обновить существующий адрес :

    user.updateAddress(id, "12345", "New York");em.persist(user);

    Теперь агрегат может контролировать, что происходит с этим адресом, и может предпринимать любые необходимые действия, связанные с обновлением адреса.

  3. Или мы обрабатываемАдрес как значение объекта , и мы не обновляем наш Address, а удаляем его и воссоздаем :

    user.removeAddress(id);address = new Address();address.setPostCode("12345");address.setCity("New York");user.addAddress(address);em.persist(user);

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

Я довольноЯ уверен, что здесь что-то упущено, чтобы правильно понять концепцию совокупности и то, как она используется в реальных примерах, поэтому, пожалуйста, не стесняйтесь комментировать!

1 Ответ

6 голосов
/ 26 августа 2011

Нет, вы ничего не упускаете - в большинстве случаев лучшим вариантом будет число 2 (хотя я бы назвал этот метод changeAddress, затем updateAdress - обновление кажется не-DDD ) и это независимо от того, является ли адрес объектом или объектом значения. С Ubiquitous Language вы бы предпочли сказать, что Пользователь изменил свой адрес, так что именно так вы должны смоделировать его - это метод changeAddress, который решает, будут ли обновляться свойства (если Address является сущностью) или назначить совершенно новый объект (когда это VO).

Следующий пример кода предполагает наиболее распространенный сценарий - Адрес как VO:

    public void ChangeAddress(AddressParams addressParams)
    {
        // here we might include some validation

        address = new Address(addressParams);

        // here we might include additional actions related with changing address
        // for example marking user as required to confirm address before
        // next billing
    }

Что важно в этом примере, так это то, что после создания адреса он считается действительным - в вашем агрегате не может быть недопустимого объекта Address. Имейте в виду, однако, что то, следует ли вам следовать этому примеру или нет, зависит от вашего фактического домена - нет единого пути для подражания. Это самый распространенный вариант.

И да, вы всегда должны выполнять операции со своими сущностями, проходя через сводный корень - причина этого была дана во многих ответах по SO (например, в этом Базовом совокупном вопросе ).

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

Другой пример - для большинства доменов Money будет объектом значения - 10 $ - 10 $, кроме суммы, у него нет идентификатора. Однако, если вы смоделируете домен, который имеет дело с деньгами на уровне счетов, каждый счет будет иметь свою собственную идентификацию (выраженную с помощью какого-то уникального числа), таким образом, это будет сущность.

...