2010-09-03 2 views
0

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

  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) 
    } 

Все работает нормально, за исключением того, что свойство activationCode не кажется правильным в объекте электронной почты. В любом случае он не описывает состояние объекта и используется только в процессе проверки электронной почты. Поэтому я изменил свой код, чтобы ввести новый объект 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 относится к объекту электронной почты в первой очереди или же она должна быть размещены в другом месте; в сервисе или внутри процесса.
  3. Есть ли шаблон дизайна, который я могу следить, чтобы решать подобные проблемы

Update

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

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

remote://email/6/do/requestVerification 

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

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

remote://service/email/do/requestVerification 

Ребята, что вы думаете ?

Спасибо

Кен

ответ

0

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

Как правило, для инкапсуляции логики проверки используется EmailVerificationService.

+0

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

1

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

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

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

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

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

+0

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

0

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

Вместо этого вы можете использовать шаблон Dependency Injection/Inversion of Control, чтобы ввести 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

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

Смежные вопросы