DAO / Abstract Factory Pattern - несколько источников данных - PullRequest
3 голосов
/ 10 февраля 2012

У меня в настоящее время есть несколько 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(), чтобы теперь этот Facotry DAO использовал SQL для одних DAO и внешнюю службу для других?Или есть другой способ сделать это?

Ответы [ 4 ]

3 голосов
/ 20 февраля 2012

Переименование это полностью зависит от вас. Шаблон 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
    }
3 голосов
/ 14 февраля 2012

Рассматривали ли вы Шаблон стратегии .Логика доступа к SQL или внешней службе может быть реализована как ConcreteStrategy, в то время как пользователю нужно только видеть интерфейс Стратегии.

1 голос
/ 20 февраля 2012

Рассмотрите возможность использования контейнера внедрения зависимостей (например, Spring Framework для получения ссылок на предварительно настроенные экземпляры ваших DAO или других видов служб. Например, в Spring вы можете написать XML-файл, определяющий DAO, обращающиеся к базе данных Oracle, и другой файл. определение DAO, обращающихся к другому поставщику базы данных: просто разверните с соответствующей версией, и ваше приложение заработает.

Также 2 вещи:

1) в то время как намерение шаблона DAO стремится абстрагировать любой тип источника данных (базы данных, веб-службы, файла свойств и т. Д.), Его использование обычно связано только с доступом к базе данных. Любой другой слой доступа к источнику данных, вы можете определить его как «сервисный» объект.

2) В качестве дополнительного комментария, если вы не планируете развернуть свое приложение для использования различных источников данных (сейчас или в обозримом будущем), то нет смысла вводить объект фабрики, плюс общий интерфейс DAO для каждый DAO.

0 голосов
/ 18 февраля 2012

Вы можете сделать это как это .Посмотрите на рисунок 9.8.Итак, что вы на самом деле делаете, это изменяете метод GetDaoFactory в своем абстрактном классе, чтобы получить параметр, представляющий, какую фабрику вы хотите: SqlDaoFactory или ExternalServiceDaoFactory

...