Comment concevoir une classe DAO?

Quelle devrait être la meilleure façon de concevoir une classe DAO?

Approche n ° 1: Concevoir une classe DAO en tant qu’object .

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(Ssortingng[] args) { CustomerDAO customerDAO = new CustomerDAO(); Customer customer = new Customer(); customerDAO.saveCustomer(customer); } } 

Approche n ° 2: Concevoir une classe DAO avec des méthodes statiques (alias classe statique)

 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(Ssortingng[] args) { Customer customer = new Customer(); CustomerDAO.saveCustomer(customer); } } 

Dans l’approche n ° 1, je dois créer un object de classe DAO dans tout le code client (une autre option consiste à transmettre la référence de DAO tout autour). tandis que dans l’approche n ° 2, je n’ai pas à créer l’object et les méthodes statiques peuvent être conçues sans suivi d’état.

Alors, quelle approche est la meilleure dans la conception des classes DAO?

Je recommanderais l’approche n ° 1, mais utiliserais Spring pour l’dependency injections plutôt que d’instancier directement les DAO.

De cette façon, pour tester le code client, vous pouvez remplacer les DAO simulés et vérifier que les bons DAO sont appelés avec les arguments appropriés. (Mockito est utile ici.)

Si vous utilisez des méthodes statiques, les tests unitaires sont beaucoup plus difficiles, car les méthodes statiques ne peuvent pas être remplacées.

Avoir plus d’abstraction:

 interface IDAO { public save(T t); public T getById(int id); //...etc } 

puis

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

et DAO à un autre domaine

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

Maintenant, la couche de présentation ou la classe principale contiendra le code comme ceci:

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

Je choisirais également l’option 1, mais je vous recommande également de programmer des interfaces. Créez une interface qui définit les fonctions que DAO doit fournir, puis vous pouvez implémenter celles avec des classes différentes en fonction de vos besoins.

 public interface CustomerDao { public void saveCustomer(Customer customer); public Customer getCustomer(int id); } 

Ensuite, vous pouvez avoir la class SimpleCustomerDao implements CustomerDAO {/*code here*/} .

Dans votre main (et partout où vous en avez besoin), vous aurez:

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

Vous pouvez comprendre les avantages de le faire!

Et oui, si vous utilisez Spring ou Guice , utilisez l’dependency injection!

Référez-vous à l’article comment écrire un DAO générique (en utilisant Spring AOP): Ne répétez pas le DAO!

Vous pouvez trouver des exemples d’implémentations DAO génériques pour votre stack technologique (google “Ne répétez pas la DAO my_technology”).

Je préférerais l’approche par couches et ce que cette approche nous dit simplement est:

  1. Vous avez votre classe de modèle client
  2. Vous avez un contrat avec le client via Interface CustomerDAO

     public interface CustomerDAO{ public void saveCustomer(Customer customer); public Customer getCustomer(int id); } 
  3. Vous avez une implémentation concrète comme CustomerDAOImpl

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

Ensuite, écrivez un gestionnaire pour les gérer ou encapsulez d’autres DAO comme:

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

Maintenant, la couche de présentation ou la classe principale contiendra le code comme ceci:

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