Инкапсуляция вызова службы в методе объекта домена - PullRequest
6 голосов
/ 02 сентября 2010

Это действительный дизайн объекта? У меня есть объект домена, где я внедряю службу и вызываю метод проверки, чтобы обновить состояние объекта и, если все пойдет хорошо, отправить подтверждающее сообщение. Код выглядит так:

class Foo {
  String bar
  Service emailService


  public boolean verify() {
    bar = "foo"
        if(this.save()) {
            emailService.sendConfirmation()
        }
  }
}

Foo.get(1).verify()

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

Спасибо - Кен

Ответы [ 3 ]

11 голосов
/ 02 сентября 2010

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

Вызов конструктора напрямую - это явно плохая идея (поскольку он связывает сущность с реализацией сервиса).

Джимми Богард объяснил, почему внедрение услуг в сущности - плохая идея .

Вместо этого он предложил использовать шаблон ' double dispatch ' (было несколько споров, если это имя подходит) для решения этой проблемы.В этом подходе вызываемый метод домена обеспечивает реализацию сервиса для метода домена.В вашем случае это будет выглядеть примерно так:

class Foo {
  String bar    

  public boolean verify(Service emailService) {
    bar = "foo"
        if(this.save()) {
            emailService.sendConfirmation()
        }
  }
}

Foo.get(1).verify(new Service(...))

Последний (но не менее важный) вариант - использовать шаблон «События домена».Вы можете прочитать об этом в блоге Уди Дахана .При таком подходе сущности отвечают только за публикацию значимых событий, которые подписаны соответствующими обработчиками.Вы можете прочитать полное сравнение всех этих методов в моем блоге .

Надеюсь, что это поможет

3 голосов
/ 02 сентября 2010

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

Возможно, было бы неплохо внедрить сервис приложений.Шаблон событий также поможет.

2 голосов
/ 02 сентября 2010

Я обычно отправляю подтверждение с места (действия?), Откуда будет вызвано подтверждение.Если в результате проверки будет отправлено много писем с подтверждением, то я, вероятно, получу Foo сгенерировать и вернуть ConfirmationMessage s (объект домена), который инкапсулирует все знания для подтверждения.Затем действие сможет поставить эти сообщения в очередь для отправки.

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

...