2013-05-16 2 views
1

내 DAO 레이어에 일반적인 디자인 패턴을 적용하여 타사 ORM (Hibernate, JPA 등) 사이를 쉽게 전환 할 수 있습니다. 우리는 모든 DAO에 공통적 인 몇 가지 메소드를 가지고 있습니다 :GenericDAO에서 공장 설계 패턴을 사용하는 방법은 무엇입니까?

  • public void create (T entity);
  • public void update (T entity);
  • public void delete (Object pk);
  • 공개 T read (Object pk);
  • public List readAll();

모든 DAO를 각 DAO에 대한 특정 이러한 방법 및 추가 방법을 상속해야한다, 나는 나에 적합한 다음과 같은 디자인 패턴을 발견하지만 난 모든 일반적인 방법을하기 위해 그것을 사용하는 방법을 모른다하고,

먼저 우리 모두가 일반적인 방법에 대한 인터페이스를 만들 것입니다 : 전문 하나는 같은 DAO 참조에 나타납니다

public interface GenericDAOINT<T> { 

    public void create(T entity); 

    public void update(T entity); 

    public void delete(Object pk); 

    public T read(Object pk); 

    public List<T> readAll(); 

} 

을하고 우리는 그 인터페이스를 구현하는 추상 클래스를 만들 것입니다 :를

public class DAOFactoryHibernate extends DAOFactory { 

    public GenericDAOHibernate<?> instantiateDAO(Class<?> daoClass) 
    { 
     try 
     { 
      GenericDAOHibernate<?> dao = (GenericDAOHibernate<?>) daoClass.newInstance(); // Exception is thrown here 
      return dao; 
     } catch (Exception e) { 
      System.out.println(e.toString()); 
      throw new RuntimeException("Can not instantiate DAO: " + daoClass, e); 
     } 
    } 

    @Override 
    public RegionHome getRegionDAO() { 
     // TODO Auto-generated method stub 
     return null; 
    } 

    @Override 
    public ServicesHome getServicesDAO() { 
     // TODO Auto-generated method stub 
     return null; 
    } 

    @Override 
    public StatusHome getStatusDAO() { 
     // TODO Auto-generated method stub 
     return null; 
    } 
} 
: 우리가 최대 절전 모드 또는 기타 플러그 ORM에 대한 DAOFactory를 만들 것입니다

public abstract class DAOFactory { 
    public static DAOFactory getInstance(Class factory) { 
     try { 
      return (DAOFactory) factory.newInstance(); 
     } catch (Exception e) { 
      throw new RuntimeException("Couldn't create DAOFactory: " + factory); 
     } 
    } 
    // return reference to any desired dao in order to call specialized methods 
    public abstract RegionHome getRegionDAO(); 
    public abstract ServicesHome getServicesDAO(); 
    public abstract StatusHome getStatusDAO(); 
} 

다음 : 우리가 원활 다른 ORM 사이를 전환 할 저를 가능하게 할 DAOFactory를 만들 것입니다 그 후 0

public abstract class GenericDAOHibernate<T> implements GenericDAOINT<T> { 
    private Class<T> persistentClass; 
    private Session session; 
    private static SessionFactory sessionFactory; 
    private static Logger LOGGER = Logger.getLogger("InfoLogging"); 

    public GenericDAOHibernate(T theClass) { 
     this.persistentClass = (Class<T>) theClass; 
     session = sessionFactory.openSession(); 
    } 

    public Class<T> getPersistentClass() { 
     return persistentClass; 
    } 

    public void setPersistentClass(Class<T> persistentClass) { 
     this.persistentClass = persistentClass; 
    } 

    static { 
     sessionFactory = new Configuration().configure("hibernate.cfg.xml") 
         .buildSessionFactory(); 
    } 

    public Session getSession() { 
     return session; 
    } 

    public void create(T entity) { 
     // implementation 
    } 

    public void update(T entity) {} 

    public void delete(Object pk) {} 

    public T read(Object pk) {} 

    public List<T> readAll() {} 
} 

각 DAO에 전문화를 추가하기 위해 우리는 각각의 DAO에 대한 인터페이스를 만들 것이며이 인터페이스는 GenericDAOINT을 확장하여 우리가 수행 할 ServicesDAO에 대한 각 DAO의 일반적인 메소드를 포함하게됩니다

public interface ServicesDAO<T> extends GenericDAOINT<ServicesHome> { 

    public void specializedMethod(); 

} 

을 다음과 같이 마지막으로 우리는 최대 절전 모드에 대한 ServicesDAO의 특정에 대한 구체적인 클래스를 만들 것입니다 : 다음

public class ServicesDAOHibernate extends GenericDAOHibernate implements ServicesDAO { 

    public ServicesDAOHibernate(Class theClass) { 
     super(theClass); 
     // TODO Auto-generated constructor stub 
    } 

    @Override 
    public void specializedMethod() { 
     System.err.println("Specialized Method"); 
    } 

} 

내가 이러한 패턴은 쉽게 ORM 사이에 유연하지만 및 전환의 과정을 촉진 생각

public class test { 
    public static void main(String args[]) { 

    DAOFactoryHibernate DFH = (DAOFactoryHibernate) DAOFactory.getInstance(DAOFactoryHibernate.class); 
    ServicesDAOHibernate serviceObjectDAO=(ServicesDAOHibernate) DFH.instantiateDAO(ServicesDAOHibernate.class); 
    serviceObjectDAO.specializedMethod(); 

} 
: 다른면 나는 각각의 DAO에 대해 동일한 기준의 모든 방법 (공통 + 전문)를 호출 할 것입니다에 대해 말했다, 나는 다음과 같은 클라이언트 코드를 시도 나는 이전 클라이언트 코드와 같은 동일한 참조 모든 방법 (공통 + 전문)를 호출하는 방법을 알고 싶어

Exception in thread "main" java.lang.RuntimeException: Can not instantiate DAO: class ServicesDAOHibernate 
    Caused by: java.lang.InstantiationException: ServicesDAOHibernate 
    at java.lang.Class.newInstance0(Class.java:340) 
    at java.lang.Class.newInstance(Class.java:308) 
    at DAOFactoryHibernate.instantiateDAO(DAOFactoryHibernate.java:9) 

:하지만 나는 다음과 같은 예외를 얻었다.

+0

JPA는 이미 다양한 구현 (EclipseLink, Hibernate 등) 위에 공통적 인 추상화 계층입니다. 왜 다른 레이어를 추가하고 싶습니까? ORM을 변경할 확률은 얼마이며,이 매우 희귀 한 이벤트가 코드를 리팩터링 할 때까지 기다리지 않는 이유는 무엇입니까? 야기! –

+0

몇 가지 이유로 나는 지금 최대 절전 모드를 사용해야한다. 그러나 앞으로 다른 ORM으로 바꾸기 위해 플러그 가능한 레이어를 추가하고 싶다. –

+0

DAOFactory가 DAOFactoryHibernate로 수행 한 모든 ORM 특정 구현을 추가 할 수있는 추상화를 추가한다. –

답변

1

전체 스택 추적을 게시했으면 좋겠습니다 (문제의 근본 원인을 발견하지 못했습니다). 그러나 귀하의 코드를 보면, Class.newInstance()을 통해 ServicesDAOHibernate에 인수가없는 생성자가 호출되어 있고 해당 클래스에 인수가없는 생성자가없는 것 같습니다.당신이 사용하고 싶습니다

return (GenericDAOHibernate<?>) daoClass.getConstructor(Class.class) 
    .newInstance(daoClass); 
관련 문제