3

我目前使用抽象工厂模式设置了一些 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,而对另一个使用外部服务?还是有不同的方法来实现这一点?

4

4 回答 4

3

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

于 2012-02-14T12:57:31.427 回答
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
    }
于 2012-02-20T10:12:38.293 回答
1

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

另外,有两件事:

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

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

于 2012-02-20T02:28:13.607 回答
0

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

于 2012-02-18T16:20:36.243 回答