通过 DAOFactory 的泛型写法来演示Java泛型的特殊用法

通过 DAOFactory 的泛型写法来演示Java泛型的特殊用法

 

小型项目中常常都没有用三方持久化框架,而大都是用公司或自行依据DAO模式封装的一些组件来完成数据库持久化动作,并且,通常为了更具可扩展性,常常使用抽象工厂模式来解耦合。

 

一、先看代码

1、简单工厂代码

/*****************************************************************************/ /* Title: DAOFactory 1.0 */ /* Description: DAOFactory 1.0 Java Source Code. */ /* Copyright: Copyright(c) 2009 - CodingMouse, Inc. All rights are reserved. */ /* Company: CodingMouse's Java R&D Studio */ /* */ /* Created in August 8, 2009 */ /*****************************************************************************/ package com.china.codingmouse.cmsdk4j.dao.factory; import java.io.Serializable; import com.china.codingmouse.cmsdk4j.config.CmSdk4jConfigurationReader; import com.china.codingmouse.cmsdk4j.dao.generaldao.GeneralDAO; import com.china.codingmouse.cmsdk4j.dao.generaldao.IGeneralDAO; import com.china.codingmouse.cmsdk4j.dao.genericsdao.GenericsDAO; import com.china.codingmouse.cmsdk4j.dao.genericsdao.IGenericsDAO; import com.china.codingmouse.cmsdk4j.exception.GeneralException; /** * 数据访问工厂。<br><br> * * 用于封装常规以及泛型数据访问动作实现的构建。 * @param <T> 泛型类型参数。 * @author CodingMouse * @version 1.0 * @see AbstractDAOFactory * @since JDK1.5 */ public class DAOFactory<T extends Serializable> extends AbstractDAOFactory<T> { /** * 构建常规数据访问动作实例。 * @return 常规数据访问动作接口实例。 */ @Override public IGeneralDAO buildGeneralDAO() { try { // 从配置档中读取常规数据访问动作实现类完全限定名 String className = CmSdk4jConfigurationReader.getInstance().getBaseSetting(false).getGeneralDAOFullName(); // 如果没有配置则返回默认实现类实例 if (className == null || className.length() == 0) return new GeneralDAO(); // 否则,将配置的实现类加载到虚拟机环境并通过默认构造器构建实例 Object instance = Class.forName(className).newInstance(); // 返回实现类实例 return IGeneralDAO.class.cast(instance); } catch (Throwable e) { // 调试信息 String debugMsg = "Configuration items <generaldao> the contents of the invalid, " + "can not be converted to the specified class interface " + IGeneralDAO.class.getName() + " instance."; // 抛出自定义异常 throw new GeneralException(debugMsg, e); } } /** * 构建泛型数据访问动作实例。 * @return 泛型数据访问动作接口实例。 */ @Override @SuppressWarnings("unchecked") public IGenericsDAO<T> buildGenericsDAO() { try { // 从配置档中读取常规数据访问动作实现类完全限定名 String className = CmSdk4jConfigurationReader.getInstance().getBaseSetting(false).getGenericsDAOFullName(); // 如果没有配置则返回默认实现类实例 if (className == null || className.length() == 0) return new GenericsDAO<T>(); // 否则,将配置的实现类加载到虚拟机环境并通过默认构造器构建实例 Object instance = Class.forName(className).newInstance(); // 返回实现类实例 return IGenericsDAO.class.cast(instance); } catch (Throwable e) { // 调试信息 String debugMsg = "Configuration items <genericsdao> the contents of the invalid, " + "can not be converted to the specified class interface " + IGenericsDAO.class.getName() + " instance."; // 抛出自定义异常 throw new GeneralException(debugMsg, e); } } }

 

2、抽象工厂代码

 /*****************************************************************************/ /* Title: AbstractDAOFactory 1.0 */ /* Description: AbstractDAOFactory 1.0 Java Source Code. */ /* Copyright: Copyright(c) 2009 - CodingMouse, Inc. All rights are reserved. */ /* Company: CodingMouse's Java R&D Studio */ /* */ /* Created in August 8, 2009 */ /*****************************************************************************/ package com.china.codingmouse.cmsdk4j.dao.factory; import java.io.Serializable; import com.china.codingmouse.cmsdk4j.dao.generaldao.IGeneralDAO; import com.china.codingmouse.cmsdk4j.dao.genericsdao.IGenericsDAO; /** * 抽象数据访问工厂。<br><br> * * 用于封装数据访问工厂实现的构建。 * @param <T> 泛型类型参数。 * @author CodingMouse * @version 1.0 * @see DAOFactory * @since JDK1.5 */ public abstract class AbstractDAOFactory<T extends Serializable> { /** * 获取抽象数据访问工厂实例。 * @param <T> 泛型类型参数。 * @return 抽象数据访问工厂实例。 */ public static<T extends Serializable> AbstractDAOFactory<T> newInstance() { return new DAOFactory<T>(); } /** * 构建常规数据访问动作实例。 * @return 常规数据访问动作接口实例。 */ public abstract IGeneralDAO buildGeneralDAO(); /** * 构建泛型数据访问动作实例。 * @return 泛型数据访问动作接口实例。 */ public abstract IGenericsDAO<T> buildGenericsDAO(); }

 

3、客户端代码

package com.china.codingmouse.cmsdk4j.example; import com.china.codingmouse.cmsdk4j.dao.factory.AbstractDAOFactory; import com.china.codingmouse.cmsdk4j.dao.factory.DAOFactory; import com.china.codingmouse.cmsdk4j.dao.generaldao.IGeneralDAO; import com.china.codingmouse.cmsdk4j.dao.genericsdao.IGenericsDAO; import com.china.codingmouse.cmsdk4j.example.pojo.AccountPOJO; /** * 演示泛型/非泛型DAO工厂的创建。 * * @author CodingMouse * @version 1.0 * @see DAOFactory * @see AbstractDAOFactory * @since JDK1.5 */ public class TestFactory { public static void main(String[] args) { // 演示泛型DAO工厂的创建方法 AbstractDAOFactory<AccountPOJO> factory = AbstractDAOFactory.newInstance(); IGenericsDAO<AccountPOJO> dao = factory.buildGenericsDAO(); AccountPOJO account = dao.get(AccountPOJO.class, 2); System.out.println(account); // 演示普通DAO工厂的创建方法 IGeneralDAO dao2 = AbstractDAOFactory.newInstance().buildGeneralDAO(); AccountPOJO account2 = (AccountPOJO) dao2.get(AccountPOJO.class, 1); System.out.println(account2); dao2.closePool(); } }

 

二、然后说明

 

1、简单工厂代码中使用反射机制构建外部指定的实现类来创建接口 IGeneralDAO 和 IGenericsDAO 的实例。这样以来,我们可以将工厂制造的产品类型放到外部来配置以降低耦合度。其中,有两个抽象方法实现,方法签名为 public IGeneralDAO buildGeneralDAO() 的这个方法没有使用泛型机制,而方法签名为 public IGenericsDAO<T> buildGenericsDAO() 的这个方法则使用了泛型机制。

 

2、抽象工厂代码中名为 newInstance 的静态方法使用了泛型机制。请注意泛型的写法。

/** * 获取抽象数据访问工厂实例。 * @param <T> 泛型类型参数。 * @return 抽象数据访问工厂实例。 */ public static<T extends Serializable> AbstractDAOFactory<T> newInstance() { return new DAOFactory<T>(); }

 

3、客户端代码中则演示了用相同的抽象工厂,如何构建泛型和非泛型的方法。需要注意的是:

AbstractDAOFactory<AccountPOJO> factory = AbstractDAOFactory.newInstance(); IGenericsDAO<AccountPOJO> dao = factory.buildGenericsDAO();

与下面这种写法是不一样的(这段代码无法通过编译,原因在于这时AbstractDAOFactory.newInstance().buildGenericsDAO()返回的是IGenericsDAO<Serializable> 类型,而非IGenericsDAO<AccountPOJO> ):

IGenericsDAO<AccountPOJO> dao = AbstractDAOFactory.newInstance().buildGenericsDAO();

 

怎么样?感觉类似的写法,效果却大不相同。慢慢体会吧!

 

 

 

 

 

你可能感兴趣的:(java,DAO,jdk,String,Class,interface)