Как обеспечить целостность данных с изменением домена - PullRequest
0 голосов
/ 11 мая 2018

Я работаю над проектом, в котором я применил принципы DDD.

Для обеспечения целостности домена я проверяю каждую модель домена (сущности или объекты-значения) при создании.

Пример объекта пользователя:

class User {
    constructor(opts) {
       this.email = opts.email;
       this.password = opts.password;
       this.validate();
    }

    validate() {
      if(typeof this.email !== 'string') {
        throw new Error('email is invalid');
      }

      if(typeof this.password !== 'string') {
        throw new Error('password is invalid');
      }
    }
}

validate метод - глупая реализация проверки (я знаю, что должен проверять электронную почту, используя Regex, и я обработал ошибку наиболее эффективным способом).
Эта модель затем сохраняется с использованием модуля userRepository.

Теперь представьте, что я хочу добавить новое свойство username в мою пользовательскую модель, мой метод validate будет выглядеть следующим образом:

validate() {
  if(typeof this.email !== 'string') {
    throw new Error('email is invalid');
  }

  if(typeof this.password !== 'string') {
    throw new Error('password is invalid');
  }

  if(typeof this.username !== 'string') {
    throw new Error('username is invalid');
  }
}

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

Чтобы исправить эту проблему, я вижу несколько решений (но ни одно из них не кажется мне хорошим):

  • создать антикоррупционный слой в репозитории пользователя (создать имя пользователя по умолчанию, если оно не определено)
  • Разрешить инвариант в моей модели домена (имя пользователя не требуется)
  • Использовать cron-сервисы, которыеобновить объекты базы данных на основе изменения домена (снова установите имя пользователя по умолчанию)

1 Ответ

0 голосов
/ 11 мая 2018

Проблема в том, что сохраненные старые пользовательские модели не будут иметь свойства username, которое теперь требуется.

Да, это проблема.

Вот как я об этом думаю - постоянная копия вашей доменной модели представляет собой сообщение , отправленное экземпляром вашей доменной модели, работавшим в прошлом, на экземпляр вашей доменной модели, запущенный в будущее.

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

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

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

Но если вам нужно добавить новое обязательное поле, тогда вы создадите новое сообщение .

Сообществу источников событий приходится много беспокоиться о подобных вещах (события - это сообщения); Грег Янг написал Управление версиями в системе источников событий , в которой есть хорошие уроки по управлению версиями сообщений.

Чтобы решить эту проблему, я вижу несколько решений (но ни одно из них не кажется мне хорошим)

Я согласен, все это в некотором роде паршиво - в том смысле, что они все вводят механизм для получения имени пользователя по умолчанию, где его нет. В этом случае поле фактически необязательно; так зачем утверждать, что это требуется?

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

Таким образом, добавление нового обязательного поля является анти-шаблоном в DDD

Добавление новых обязательных полей является анти-шаблоном в обмене сообщениями; DDD имеет мало общего с этим.

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

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

Да, но это не магия . Если ваши новые модели не имеют обратной совместимости со старыми моделями, вам придется каким-то образом управлять этим изменением

Вы можете объявить о банкротстве и просто забыть всю предыдущую историю. Вы можете перенести существующие данные в новую модель данных. Вы можете поддерживать две разные модели данных параллельно.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...