Question

J'ai le code qui ressemble à ceci:

public interface BaseDAO{
// marker interface
}

public interface CustomerDAO extends BaseDAO{
public void createCustomer();
public void deleteCustomer();
public Customer getCustomer(int id);
// etc
}

public abstract class DAOFactory {
public BaseDAO getCustomerDAO();
public static DAOFactory getInstance(){
  if(system.getProperty("allowtest").equals("yes")) {
  return new TestDAOFactory();
  }
  else return new ProdDAOFactory();
}

public class TestDAOFactory extends DAOFactory{
public BaseDAO getCustomerDAO() {
  return new TestCustomerDAO(); // this is a concrete implementation
  //that extends CustomerDAO
  //and this implementation has dummy code on methods
}

public class ProdDAOFactory extends DAOFactory {
public BaseDAO getCustomerDAO() {
  return new ProdCustomerDAO(); // this implementation would have 
  // code that would connect to the database and do some stuff..
}
}

Maintenant, je sais que cela sent code .. pour de nombreuses raisons. Cependant, ce code est ici aussi: http://java.sun.com/blueprints/corej2eepatterns/Patterns/DataAccessObject.html , consultez 9.8

Ce que je compte faire est la suivante: 1) Mettre mes mises en œuvre DAOS lors de l'exécution en fonction de l'environnement (propriétés du système). 2) Exploitez les génériques java pour que je puisse éviter la coulée de type ...    par exemple fait quelque chose comme ceci:

CustomerDAO dao = factory.getCustomerDAO();
dao.getCustomer();

Par opposition à:

CustomerDAO dao = (CustomerDAO) factory.getCustomerDAO();
dao.getCustomer();

Vos idées et suggestions, s'il vous plaît.

Était-ce utile?

La solution

Vous devez définir l'usine comme ça:

public abstract class DAOFactory<DAO extends BaseDAO> {
public DAO getCustomerDAO();
public static <DAO extends BaseDAO> DAOFactory<DAO> getInstance(Class<DAO> typeToken){
  // instantiate the the proper factory by using the typeToken.
  if(system.getProperty("allowtest").equals("yes")) {
  return new TestDAOFactory();
  }
  else return new ProdDAOFactory();
}

getInstance doit retourner un DAOFactory typé approprié.

La variable usine aura du type:

DAOFactory<CustomerDAO> factory = DAOFactory<CustomerDAO>.getInstance(CustomerDAO.class);

et l'utilisation sera bien saisi:

CustomerDAO dao = factory.getCustomerDAO();
dao.getCustomer();

le seul problème sera probablement une distribution nécessaire à l'intérieur des méthodes de getInstance.

Autres conseils

Il y a un tas d'articles détaillant ce que vous avez besoin:

S'il vous plaît noter que, contrairement à votre exemple, il n'y a aucune raison pour que les méthodes de ne pas retourner DAOFactory les sous-classes réelles (à savoir CustomerDAO getCustomerDAO()). En outre, principal avantage de l'utilisation OTI générique est d'avoir le type d'entité « genericized », de sorte que vous ne devez pas jeter de méthodes similaires et load()/get()/find().

Votre exemple ne démontre pas besoin de BaseDAO, et il n'y a aucune raison pour ne devrait pas être DAOFactory.getCustomerDAO() déclaré retourner un CustomerDAO. Donc, je ne vois pas vraiment besoin de médicaments génériques là-bas. Cependant, considérer les points suivants:

interface DataAccess<T> {
  void store(T entity);
  T lookup(Serialiable identifier);
  void delete(Serializable identifier);
  Collection<? extends T> find(Criteria query);
}

abstract class DataAccessFactory {
  abstract DataAccess<T> getDataAccess(Class<T> clz);
  static DataAccessFactory getInstance() {
    ...
  }
}

Je l'ai utilisé quelque chose comme cette approche dans plusieurs projets, et il est très agréable d'écrire un OAC qui fonctionne pour toutes les entités dans le modèle. La faiblesse est les méthodes « Finder ». Il y a des approches soignées, et les travaux à venir dans le JPA normalise une API « Critères », mais pour l'instant il est souvent plus facile d'exposer les critères du mécanisme de persistance sous-jacente.

Quand je l'ai utilisé des usines que j'ai généralement utilisé instanceof pour déterminer le vrai type de l'objet. Par exemple:

CustomerDAO dao;
if (factory.getCustomerDAO() instanceof CustomerDAO) {
   dao = factory.getCustomerDAO();
}
dao.getCustomer();

Cela semble juste me plus propre, surtout si factory.getCustomerDAO () ne retourne rien à proximité d'un CustomerDAO (en raison de changements dans la mise en œuvre).

Juste mes deux cents.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top