【问题标题】:Service and DAO Design pattern服务和 DAO 设计模式
【发布时间】:2012-08-21 03:48:41
【问题描述】:

我对 Delegate-Service 和 DAO 设计模式有疑问。我们的团队认为我们将为 DAOFactory 和 DAO 对象使用单例模式。 DAOFactory 将包含所有可用的 DAO 作为其属性,并会在需要时提供它们。

现在我们怀疑服务是否说例如AuthenticateSerivce 应包含所有必需的 DAO,例如UserDAO、RoleDAO 等作为属性?或者它应该根据需要调用get**DAO(),而不是设置为自己的属性。(附件是java文件)

代码片段:

public class AuthenticateService {
    UserDao userDao;
    RoleDao roleDao;

    public AuthenticateService(){
        DaoFactory daoFactory = DaoFactory.getInstance();
        userDao = daoFactory.getUserDao();
        roleDao = daoFactory.getRoleDao();
    }


}


public class DaoFactory {

    private static DaoFactory instance = null;

    UserDao userDao;
    RoleDao roleDao;
    AnnualScheduleDao annualScheduleDao;
    WeeklyScheduleDao weeklyScheduleDao;
    ProgramSlotDao programSlotDao;

    private DaoFactory (){
        // Authenticate
        userDao = new UserDaoImpl();
        roleDao = new RoleDaoImpl();

        // Schedule
        annualScheduleDao = new AnnualScheduleDaoImpl();
        weeklyScheduleDao = new WeeklyScheduleDaoImpl();
        programSlotDao = new ProgramSlotDaoImpl();

    }


}

哪种方法更好,在哪些情况下?

【问题讨论】:

    标签: design-patterns jakarta-ee


    【解决方案1】:

    我认为第一个更好(即属性),因为它更容易管理它们。代码也将变得更简洁,而不是在不同的方法中调用工厂,或者在每个方法中都有一个 dao 变量。您可以轻松地修改 Daos 以供以后使用,而无需在多个区域进行替换。如果您决定在那里初始化 Dao,或者创建一个自定义 dao 来使用,或者稍后使用依赖注入,那么您不必重新访问对 DaoFactory 的所有调用。

    第二个问题是关于在 DAO 中使用单例。我不确定每个 DaoImpl 是如何完成的,但是当服务被多个线程访问时(同样,这取决于你如何实现你的 Daos)并且它们共享同一个 Dao,就有可能出现线程问题。或者,也许您想使用一个为每个请求实例化一个新 Dao 的工厂?但如果是这样的话,那么我相信你会选择第一个选项,因为你不想在每个方法中重新创建一个 dao。

    创建 Daos 的成本可能很低(假设您的团队担心性能问题),因此它们不需要按需实例化,但您应该进行一些连接或资源池(例如,重用 Db 连接)。

    【讨论】:

    • 我同意你的两个观点。但是,我认为由于 DAOFactory 是所有 DAO 的容器,它会在需要时将它们提供给 Service(通过创建新的 DAO 或再次重新使用相同的 N 或通过池),因此无需保留 DAO作为服务的态度。但是现在,我将采用您建议的方法,因为我没有任何充分的理由使用第二种方法;)
    • 但是在使用返回一个且仅相同的 Dao 的 DAOFactory 时需要小心,尤其是当它们要维护状态时。这在多线程场景中肯定会出现问题,您必须为其他开发人员记录这一点。另外,其他开发者必须始终如一地使用工厂,或者向工厂添加新的 Daos,我认为这是不必要的,除非你真的打算使用工厂“制造”不同种类的 UserDao。
    • 创建新的 dao 或为服务中每个方法中的每个调用池化似乎比在服务的构造函数中完成一次更昂贵。 Dao 的池化似乎增加了麻烦,因为用户需要将 dao 关闭()或返回()到池中;最好在 Dao 中汇集连接,因为真的应该调用 close()。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-12
    • 1970-01-01
    • 2012-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-28
    相关资源
    最近更新 更多