DAO /抽象工厂模式 - 多个数据源

时间:2012-02-10 18:18:03

标签: design-patterns dao abstract-factory

我目前使用抽象工厂模式设置了一些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现在将SQL用于某些DAO而将外部服务用于其他DAO吗?或者有不同的方法来实现这一目标吗?

4 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:3)

重命名它完全取决于你。 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 :(得分:1)

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

另外,有两件事:

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

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

答案 3 :(得分:0)

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