Должны ли несколько объектов уровня обслуживания совместно использовать DAO?

StackOverflow https://stackoverflow.com/questions/900279

  •  23-08-2019
  •  | 
  •  

Вопрос

У меня есть класс Contact, который содержит объект PortalAccount .Когда я хочу создать "Учетную запись портала" для контакта, учетная запись создается удаленно в приложении портала с использованием soap / axis, а затем заполняется учетная запись 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 изменяет Контакт, который я ему передаю.

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

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

Это было полезно?

Решение

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

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

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

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

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

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

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

Удачи.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top