Должны ли несколько объектов уровня обслуживания совместно использовать DAO? - PullRequest
1 голос
/ 23 мая 2009

У меня есть класс Contact, который содержит объект PortalAccount. Когда я хочу создать «Учетную запись портала» для контакта, учетная запись удаленно создается в приложении портала с использованием мыла / оси, а затем заполняется учетная запись portalAccount и контакт сохраняется (локальная база данных содержит информацию об удаленной учетной записи, например, идентификатор пользователя и имя пользователя и т. д.).

Итак, у меня есть класс обслуживания PortalServiceImpl, в котором есть методы для фактического создания пользователя на удаленном портале с учетом экземпляра Contact.

Учитывая всю эту информацию, мой вопрос заключается в следующем: должен ли PortalServiceImpl получить экземпляр объекта ContactDAO и действительно выполнить сохранение, или класс PortalServiceImpl просто создаст удаленного пользователя, изменить переданный объект Contact и позволить клиент несет ответственность за сохранение?

Метод 1:

class ServiceFacadeImpl {
  public void createPortalAccount(Contact contact) {
    // here the contact is implicitly saved
    this.portalService.createPortalAccount(contact);
  }
}

Метод 2:

class ServiceFacadeImpl {
  public void createPortalAccount(Contact contact) {
    // here contact is implicitly modified
    this.portalService.createPortalAccount(contact);
    this.contactDAO.save(contact);
  }
}

Оба метода кажутся мне неправильными. Метод 1 кажется неправильным, потому что PortalService создает удаленного пользователя и сохраняет контакт в базе данных (хотя и через интерфейс DAO). Метод 2 кажется неправильным, потому что я должен предположить, что PortalService изменяет контакт, который я ему передаю.

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

(Кстати, я уже использовал оба метода и не хочу продолжать рефакторинг в бесконечном кругу. Здесь что-то кажется неправильным.)

1 Ответ

3 голосов
/ 23 мая 2009

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

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

Если вышеприведенные мысли для вас неприемлемы, то я бы сделал это так:

class ServiceFacadeImpl {
  public void CreatePortalAccountAndSaveContact(Contact contact) {
    try
    {
      contact.portalAccount = this.portalService.createPortalAccount(contact);
      this.contactDAO.save(contact);
    }
    catch(...)
    {
      // do cleanup, for example do you need to delete account from remote 
      // portal if it couldn't be saved locally?
      // If yes, delete it from portal and set contact.portalAccount = null;
    }
  }
}

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

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

PS. Почему вы используете это ключевое слово? Является ли portalService частным участником? Если да, то, возможно, вам нужно пересмотреть свое соглашение об именах и назвать частных членов, например, с префиксом «_» (я думаю, что он самый популярный), например, _portalService - тогда будет легко понять, что _portalService является частным членом. Извините за оффтоп.

Удачи.

...