【问题标题】:DAO/Abstract Factory Pattern - multiple data sourcesDAO/抽象工厂模式 - 多数据源
【发布时间】:2012-02-10 18:18:02
【问题描述】:

我目前有一些使用抽象工厂模式设置的 DAO。它看起来像这样:

public abstract class DaoFactory
    public static GetDaoFactory()
    public abstract IPersonDao GetPersonDao()
    // etc.

静态GetDaoFactory() 返回底层SqlDaoFactory。直到今天,所有的 Daos 都使用同一个 SQL 数据库。现在,我想向这个工厂添加另一个 DAO,但是 DAO 将与外部服务而不是 SQL 数据库交互(假设这是GetCompanyDao())。我基本上只想将此GetCompanyDao() 方法添加到抽象DaoFactory 类中,以便公共接口与底层实现完全解耦(无需/方式来判断特定dao 是使用SQL 还是外部服务)。

我是否应该简单地将SqlDaoFactory 重命名为更合适的名称并在其中包含GetCompanyDao() 方法,以便这个DAO Facotry 现在对某些DAO 使用SQL,对另一个使用外部服务?或者有什么不同的方法可以做到这一点?

【问题讨论】:

    标签: design-patterns dao abstract-factory


    【解决方案1】:

    重命名完全取决于您。 DAO 模式抽象了任何类型的数据访问,不一定是数据库访问。所以你绝对可以继续你的计划。

    您可以使用 spring 之类的框架,而不是手动创建模式。

    我曾尝试对这些模式进行一次硬编码。

    public abstract class DAOFactory {
    
      // List of DAO types supported by the factory
      public static final int MYSQL = 1;
      public static final int ORACLE = 2;
      public abstract UserDAO getUserDAO() throws SQLException;
      public static DAOFactory getDAOFactory(int whichFactory) {
    
        switch (whichFactory) {
          case MYSQL: 
              return new MySQLDAOFactory();
          case ORACLE    :
              ......
    
    
    public class MySQLDAOFactory extends DAOFactory {
    
        public MySQLDAOFactory() {
        }
        public static final String DRIVER= "/*driver here*/";
        public static final String DBURL="/*conn string here*/";
        /* instead of using constants you could read them from an external xml file*/
    
        public static Connection createConnection() {
            /*create connection object here*/
            return conn;
        }
        public UserDAO getUserDAO() throws SQLException{
            return new MySQLUserDAO();
        }
    
    public interface UserDAO {
        public int insertUser(String fname, String lname);
        public ArrayList<User> selectUsers();
    }
    
    public class MySQLUserDAO implements UserDAO {
    
        Connection conn=null;
        Statement s=null;
        public MySQLUserDAO() throws SQLException{
            conn = MySQLDAOFactory.createConnection();
            s = conn.createStatement();
        }
    
        public int insertUser(String fname, String lname) 
        {
            //implementation
        }
    
    
        public ArrayList<User> selectUsers() 
        {
            //implementation
        }
    

    【讨论】:

      【解决方案2】:

      您考虑过Strategy Pattern。 SQL或外部服务访问逻辑可以实现为ConcreteStrategy,而用户只需要看到Strategy接口。

      【讨论】:

        【解决方案3】:

        考虑使用依赖注入容器(如 Spring 框架来获取对 DAO 或其他类型服务的预配置实例的引用。例如,在 Spring 中,您可以编写一个 XML 文件来定义访问 Oracle 数据库的 DAO 和其他文件定义访问另一个数据库供应商的 DAO:只需使用适当的版本进行部署,您的应用程序就可以运行。

        还有两件事:

        1) 虽然 DAO 模式意图试图抽象出任何类型的数据源(数据库、Web 服务、属性文件等),但它的使用通常仅与数据库访问相关联。您可以将任何其他数据源访问层定义为“服务”对象。

        2) 作为旁注,除非您实际上计划部署您的应用程序以使用不同的数据源(现在或在可预见的将来),否则引入工厂对象以及通用 DAO 接口是没有意义的每个 DAO。

        【讨论】:

          【解决方案4】:

          您可以像this 那样做。看那里的图 9.8。 所以你实际上要做的是在你的抽象类中更改 GetDaoFactory 方法,以获取代表你想要的工厂的参数,SqlDaoFactory 或 ExternalServiceDaoFactory

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2010-09-06
            • 1970-01-01
            • 1970-01-01
            • 2023-03-30
            相关资源
            最近更新 更多