我想为我的DAO层应用一个通用的设计模式,这样我就可以轻松地在第三方ORM(Hibernate、JPA等)之间切换。显然,我们有一些适用于所有DAO的通用方法,比如:
所有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 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() {}
}
之后,我们将制作一个DAOFactory,使我能够在不同的ORM之间顺利切换:
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();
}
接下来,我们将为hibernate或任何其他可插拔的ORM制作一个DAOFactory:
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;
}
}
为了向每个DAO添加专门化,我们将为每个DAO创建一个接口,该接口将扩展GenericDAOINT
,以在每个DAO中包含服务的常用方法。我们将执行以下操作:
public interface ServicesDAO<T> extends GenericDAOINT<ServicesHome> {
public void specializedMethod();
}
最后我们将为ServicesDAO制作一个具体类,具体用于Hibernate,如下所示:
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之间轻松灵活地切换,但我告诉过你的另一方面是,我想为每个DAO调用同一引用上的所有方法(通用专用),我尝试了以下客户端代码:
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();
}
但我有以下例外:
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)
我想知道如何像前面的客户机代码一样,在同一个引用上调用所有方法(通用专用)。
我希望您已经发布了完整的堆栈跟踪(您缺少了一个导致问题的根本原因)。但是从你的代码来看,你的问题似乎是你在通过类调用
并且该类没有无参数构造函数。你想用ServicesDAOHibernate
上的无参数构造函数。newInstance()
return (GenericDAOHibernate<?>) daoClass.getConstructor(Class.class)
.newInstance(daoClass);
我正在努力学习创造性设计模式,我想我现在理解了工厂方法模式。但在转向抽象工厂模式时,我找不到它的用途。我知道我错过了一些东西,但不知道在哪里。 在抽象工厂模式中,我们将有一个抽象工厂,混凝土工厂将返回实例。假设我们正在处理汽车的创建。我们将有一个像这样的抽象工厂 我们的混凝土工厂将是 在用户类中,我们将像 我认为我们也可以使用工厂模式构建相同的功能 在用户类中,我们可以 如果我的理解是正确的(如果
介绍 与创建型模式类似,工厂模式创建对象(视为工厂里的产品)时无需指定创建对象的具体类。 工厂模式定义一个用于创建对象的接口,这个接口由子类决定实例化哪一个类。该模式使一个类的实例化延迟到了子类。而子类可以重写接口方法以便创建的时候指定自己的对象类型。 这个模式十分有用,尤其是创建对象的流程赋值的时候,比如依赖于很多设置文件等。并且,你会经常在程序里看到工厂方法,用于让子类类定义需要创建的对象类型
简单工厂(Simple Factory) Intent 在创建一个对象时不向客户暴露内部细节,并提供一个创建对象的通用接口。 Class Diagram 简单工厂把实例化的操作单独放到一个类中,这个类就成为简单工厂类,让简单工厂类来决定应该用哪个具体子类来实例化。 这样做能把客户类和具体子类的实现解耦,客户类不再需要知道有哪些子类以及应当实例化哪个子类。客户类往往有多个,如果不使用简单工厂,那么所
4. 抽象工厂(Abstract Factory) Intent 提供一个接口,用于创建 相关的对象家族 。 Class Diagram 抽象工厂模式创建的是对象家族,也就是很多对象而不是一个对象,并且这些对象是相关的,也就是说必须一起创建出来。而工厂方法模式只是用于创建一个对象,这和抽象工厂模式有很大不同。 抽象工厂模式用到了工厂方法模式来创建单一对象,AbstractFactory 中的 cr
工厂方法(Factory Method) Intent 定义了一个创建对象的接口,但由子类决定要实例化哪个类。工厂方法把实例化操作推迟到子类。 Class Diagram 在简单工厂中,创建对象的是另一个类,而在工厂方法中,是由子类来创建对象。 下图中,Factory 有一个 doSomething() 方法,这个方法需要用到一个产品对象,这个产品对象由 factoryMethod() 方法创建。
我想知道在Spring框架中使用依赖注入的工厂模式的当前最佳实践是什么。我想知道工厂模式在使用Spring依赖注入的情况下是否仍然适用。我做了一些搜索,看到了一些过去的讨论(依赖注入vs工厂模式),但似乎有不同的观点。 我在一些现实生活中的项目中看到使用Map来保存所有的bean,并依靠自动装配来创建这些bean。当需要bean时,它使用密钥通过map获取它。 但是我看到这两种方法有些不同。 使用