Свойства объекта домена и инкапсуляция - PullRequest
0 голосов
/ 03 сентября 2010

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

  1. Установить код активации для электронной почты
  2. Отправьте электронное письмо с кодом активации, чтобы убедиться, что оно действительно

Объект электронной почты выглядит следующим образом:

class Email {
    String label
    String value
    EmailStatus status
    String activationCode

    boolean requestVerification() {
        // Set the activationCode that will be refereced to change the email status 
        this.activationCode = UUID
        // Raise an event to send a notification email by a communication service
        EventManager.fire('emailVerificationRequest',this)
    }

Все работает нормально, за исключением того, что свойство activCode не чувствует себя в пределах объекта Email. В любом случае он не описывает состояние объекта и используется только в процессе проверки электронной почты. Поэтому я изменил свой код, чтобы ввести новый объект с именем ActivationToken. Объект будет использоваться для инкапсуляции кода активации. Вот новая версия объекта электронной почты

 class Email {
    String label
    String value
    EmailStatus status

    boolean requestVerification() {
        new ActivationToken(target:this,code:UUID,expiryDate:new Date()).save()
        // Raise an event to send a notification email by a communication service
        EventManager.fire('emailVerificationRequest',this)
    }

 class ActivationToken {
    Email target
    String code
    Date expiryDate
 }
  1. Это надежный дизайн предметной области или я усложняю свой объект даром
  2. относится ли метод requestVerification к объекту Email в первую очередь или он должен быть размещен в другом месте; в службе или в процессе.
  3. Есть ли какой-то шаблон проектирования, который я могу использовать для решения подобных проблем

Update

Я хотел объяснить, почему я сохранил часть метода requestVerfication объекта домена электронной почты даже после второго подхода к рефакторингу.

У меня есть удаленный интерфейс, который напрямую взаимодействует с объектами домена через диспетчер:

remote://email/6/do/requestVerification

Первоначально я хотел сохранить всю связь с бэкэндом, передаваемым через доменные объекты, и, если есть необходимость взаимодействовать, скажем, со службой, я использовал IOC, чтобы внедрить его в объект домена и использовать объект домена как прокси. Разделение между удаленным интерфейсом и доменным объектом выглядело чистым, но это оказалось очень плохой идеей, поскольку оно не учитывает дизайн домена и вводит бесполезную зависимость от внешнего объекта (в данном случае EmailVerificationService), который не имеет ничего общего с поведением или аспекты состояния доменного объекта

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

 remote://service/email/do/requestVerification

Что вы, ребята, думаете?

Спасибо

1041 * Кен *

Ответы [ 3 ]

1 голос
/ 03 сентября 2010

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

Что касается ваших индивидуальных вопросов:

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

  2. Как упоминалось, я действительно думаю,что это ответственность уровня сервиса, и она должна быть в каком-то виде EmailVerificationService.В самой доменной модели вас действительно волнует , если письмо действительно, а не то, каким образом оно проверено.

  3. Вы уже используете лучший подходчто вы можете, на мой взгляд.Шина событий с событиями, вызванными из объекта домена, является чистой и надежной.

0 голосов
/ 03 сентября 2010

Я думаю, что это хорошая идея для инкапсуляции функциональности в ActivationToken.Но, инициализируя ActivationToken в классе Email, вы создали скрытую зависимость от внешнего ресурса.Это фактически делает Email сложным для модульного тестирования и повторного использования другими клиентами, которые имеют другую схему активации.

Вместо этого вы можете использовать шаблон Внедрение зависимости / инверсия управления ввести ActivationToken в класс Email.Это позволяет вам вводить различные стратегии активации и открывает для простого юнит-тестирования класса Email.

Для этого вам потребуется интерфейс для ActivationToken и конструктор класса Emailдолжен ссылаться на объект, реализующий этот интерфейс:

interface IActivationToken
{
   void Save(object target, string code, DateTime date);
}

class Email
{
    IActivationToken token;
    // Other properties go here.

    public Email(IActivationToken token)
    {
        this.token = token;
    }

    boolean RequestVerification() 
    {    
        token.Save(this, code, date);        
        // Raise an event to send a notification email by a communication service    
        EventManager.fire('emailVerificationRequest', this)    
    }    
}

Теперь класс Email не имеет скрытых зависимостей от внешних ресурсов.

0 голосов
/ 03 сентября 2010

Вы предприняли правильные шаги в отделении Email от ActivationToken - концептуально это разные вещи (кстати, я бы использовал EmailActivationToken для ясности).

Обычно EmailVerificationService используется для инкапсуляции логики проверки.

...