2011-08-29 21 views
38

¿Cuál debería ser la mejor manera de diseñar una clase DAO?¿Cómo diseñar una clase DAO?

Enfoque # 1:Diseño clase DAO como un objeto.

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); 
    } 
} 

Enfoque # 2:clase de diseño DAO con métodos estáticos (clase aka estática)

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); 
    } 
} 

En el enfoque # 1, que tiene que crear un objeto de la clase DAO en todo el código del cliente (otra opción es pasar la referencia de DAO por todas partes). mientras que en el enfoque n.º 2, no tengo que crear el objeto y los métodos estáticos se pueden diseñar sin seguimiento del estado.

¿Cuál enfoque es el mejor en diseño de clases DAO?

+4

Uso enfoque # 1 e inyectar referencias usando un contenedor de IOC como Spring –

+3

Es extraño que nadie haya mencionado un tutorial tan agradable e informativo de [BalusC] (http://stackoverflow.com/users/157882/balusc): [DAO tutorial - the dat una capa] (http://balusc.blogspot.com/2008/07/dao-tutorial-data-layer.html). Léelo y encontrará las respuestas a muchas preguntas relacionadas con el diseño e implementación de DAO. – informatik01

Respuesta

37

Recomendaría el enfoque n. ° 1, pero utilizaría Spring para la inyección de dependencias en lugar de crear instancias de DAO directamente.

De esta forma, para probar la unidad del código de cliente, puede sustituir DAO simulados y verificar que se invocan los DAO correctos con los argumentos apropiados. (Mockito es útil aquí.)

Si utiliza métodos estáticos, entonces la prueba unitaria es mucho más difícil, ya que los métodos estáticos no se pueden anular.

+5

+1 Yo era demasiado perezoso para escribir esta respuesta yo mismo. Pero hubiera sido bastante idéntico a este :-) –

+0

¿Qué sucede si uno de los clientes (usuario) de un objeto DAO representa al cliente (usuario) registrado actualmente. ¿Proporcionaría un método como getCurrentCustomer() o sería transparente para la clase DAO y este usuario siempre se obtendría mediante id? – Piotr

+1

@Piotr Creo que el DAO no debería preocuparse por quién originó la solicitud. –

6

Iría también por la opción 1 pero también recomendaría que programara interfaces. Cree una interfaz que establezca qué funciones debe proporcionar DAO y luego puede implementar aquellas con diferentes clases según sus necesidades.

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

    public Customer getCustomer(int id); 
} 

Entonces usted puede tener class SimpleCustomerDao implements CustomerDAO {/*code here*/}.

En su main (y en cualquier otro que lo necesite) tendrá:

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

se puede averiguar los beneficios de hacer esto!

Y sí, si usa Spring o Guice, ¡utilice Inyección de Dependencia!

5

consulte el artículo de cómo escribir un DAO genérico (utilizando Spring AOP): Don't repeat the DAO!

se pueden encontrar ejemplos de implementaciones DAO genéricos para su tecnología de pila (sólo Google "No repita el my_technology DAO") .

+0

Gracias por la referencia. – nibin012

0

yo preferiría que el enfoque por capas, y Lo Este enfoque simplemente nos dicen es:

  1. Usted está teniendo su modelo de clase Cliente
  2. Usted tiene un contrato con el cliente a través de la interfaz CustomerDAO

    public interface CustomerDAO{ 
    
        public void saveCustomer(Customer customer); 
        public Customer getCustomer(int id); 
    } 
    
  3. Usted está teniendo una aplicación concreta como CustomerDAOImpl

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

luego escribir un administrador para gestionar estos o encapsular algunos otros DAOs como:

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); 
    } 
} 

Ahora la capa de presentación o de la clase principal contendrá el código como el siguiente:

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

'public void saveCustomer (Cliente cliente) {saveCustomer (cliente); } 'LOL + tiene errores como' cliente público getCustomer (int id); 'y luego' customerDAOObj.fetchCustomer'. Sin mencionar tu formateo ... Corrige esos - -1 hasta entonces –

11

Para tener más abstracción:

interface IDAO<T> { 

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

} 

continuación

y DAO a otro dominio

public UniversityDao implements IDAO<University>{ 

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

Ahora la capa de presentación o de la clase principal contendrá el código como el siguiente:

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