代码之家  ›  专栏  ›  技术社区  ›  Boden

多个服务层对象是否应该共享一个DAO?

  •  1
  • Boden  · 技术社区  · 17 年前

    我有一个包含PortalAccount对象的Contact类。当我要为联系人创建“门户帐户”时,使用soap/axis在门户应用程序上远程创建帐户,然后填充联系人的portalAccount并保存联系人(本地数据库保存有关远程帐户的信息,如用户id和用户名等)。

    考虑到所有这些信息,我的问题是:PortalServiceImpl应该获取ContactDAO对象的实例并实际执行保存,还是PortalServiceImpl类应该创建远程用户、修改传入的Contact对象并让客户端负责保存?

    方法1:

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

    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 回复  |  直到 17 年前
        1
  •  3
  •   nightcoder    17 年前

    您确定本地和远程都有不同的联系人ID是个好主意吗?这对我来说似乎是错误的,但也许我只是不知道你的领域。

    在我的应用程序中,所有新联系人都通过Web服务发送到远程门户并保存在那里。因此,当我在本地保存新联系人时,它会被发送到远程门户并保存在那里。也许你也需要同样的?

    如果你不能接受上述想法,那么我会这样做:

    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打破了单一责任原则,但我认为在这种情况下,这是绝对正常的,因为正如我所理解的,你需要这个操作是原子的。正当

    或者,您可以向该方法添加布尔标志,指示是否要保存联系人。但如果您总是需要在从远程门户获取联系人后直接保存与PortalAccount的联系,则不需要布尔标志。

    另外,你为什么使用“this”关键字?portalService是私人会员吗?如果是,那么您可能需要重新考虑您的命名约定,并使用前缀“u”命名私有成员(我认为这是最流行的一种),例如_portalService-那么很容易理解_portalService是私有成员。对不起,我离题了。

    祝你好运