Подтвердить что ты не робот

Как создать класс DAO?

Каким должен быть лучший способ разработки класса DAO?

Подход №1: Дизайн класса DAO как объекта.

class Customer {
//customer class
}

class CustomerDAO {
  public void saveCustomer(Customer customer) {
  //code
  }

  public Customer getCustomer(int id) {
  //code
  }
}

//Client code
class client {
  public static void main(String[] args) {

   CustomerDAO customerDAO = new CustomerDAO();
   Customer customer = new Customer();
   customerDAO.saveCustomer(customer);
  }
}

Подход № 2: Дизайн класса DAO со статическими методами (aka static class)

class Customer {
//customer class
}

class CustomerDAO {
  public static void saveCustomer(Customer customer) {
  //code
  }

  public static Customer getCustomer(int id) {
  //code
  }
}

//Client code
class client {
  public static void main(String[] args) {

   Customer customer = new Customer();
   CustomerDAO.saveCustomer(customer);
  }
}

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

Итак, какой подход является лучшим в дизайне классов DAO?

4b9b3361

Ответ 1

Я бы рекомендовал подход № 1, но использовал бы Spring для инъекции зависимостей, а не для непосредственного создания DAO.

Таким образом, для модульного тестирования клиентского кода вы можете подменять макеты DAO и проверять, что правильные DAO вызываются с соответствующими аргументами. (Мокито полезен здесь.)

Если вы используете статические методы, то модульное тестирование намного сложнее, поскольку статические методы не могут быть переопределены.

Ответ 2

Чтобы иметь больше абстракции:

interface IDAO<T> {

  public save(T t);
  public T getById(int id);
  //...etc

}

то

public CustomerDao implements IDAO<Customer>{
   public save(Customer c){
        //Code here
    }
   public Customer getById(int id){
      //Code here
    }
}

и DAO другого домена

public UniversityDao implements IDAO<University>{

     public save(University u){
       //Code here
      }
     public University getById(int id){
        //Code here
     }
}

Теперь уровень представления или основной класс будет содержать такой код:

IDAO  dao;
dao=new CustomerDao();
//...
dao=new UniversityDao();

Ответ 3

Я бы пошел на вариант 1, но я бы также рекомендовал вам программировать интерфейсы. Создайте интерфейс, который устанавливает, какие функции должен предоставить DAO, и затем вы можете реализовать те, у которых есть разные классы, в зависимости от ваших потребностей.

public interface CustomerDao {
    public void saveCustomer(Customer customer);

    public Customer getCustomer(int id);
}

Тогда вы можете иметь class SimpleCustomerDao implements CustomerDAO {/*code here*/}.

В вашем main (и везде, где это необходимо) вы будете иметь:

//Note that you have an interface variable and a real class object 
CustomerDao customerDao = new SimpleCustomerDao();

Вы можете понять преимущества этого!

И да, если вы используете Spring или Guice, тогда используйте Injection Dependency!

Ответ 4

Обратитесь к статье, как написать общий DAO (используя Spring AOP): Не повторяйте DAO!

Вы можете найти примеры общих реализаций DAO для вашего стека технологий (просто Google "Не повторяйте DAO my_technology" ).

Ответ 5

Я бы предпочел, чтобы слоистый подход и что этот подход просто сказал нам:

  • У вас есть модельный класс Customer
  • У вас есть контракт с клиентом через интерфейс CustomerDAO

    public interface CustomerDAO{
    
        public void saveCustomer(Customer customer);
        public Customer getCustomer(int id);
    }
    
  • У вас есть конкретная реализация, например CustomerDAOImpl

    public class CustomerDAOImpl extends CustomerDAO{
    
        public void saveCustomer(Customer customer){
          saveCustomer(customer);
        }
    
        public Customer getCustomer(int id){
          return fetchCustomer(id);
        }
    }
    

Затем запишите менеджера для управления этими или инкапсулированием некоторых других DAO, например:

public class ManagerImpl extends Manager{
    CustomerDAO customerDAOObj;

    // maybe you need to collect
    // all the customer related activities here in manger
    // because Client must not bother about those things.

    UserBillingDAO userBillingDAOObj; 

    public void saveCustomer(Customer customer){
      customerDAOObj.saveCustomer(customer);
    }

    public Customer getCustomer(int id){
      return customerDAOObj.fetchCustomer(id);
    }

    // Note this extra method which is defined in 
    //UserBillingDAO which I have not shown, but you are exposing 
    //this method to your Client or the Presentation layer.

     public boolean doBillingOFCustomer(id) {
        return userBillingDAOObj.doBilling(id);
    }
}

Теперь уровень представления или основной класс будет содержать такой код:

public static void main(String... ar){
     Manager manager = new ManagerImpl();
     manager.saveCustomer();
    // or manager.doBillingOfCustomer(); // etc
}