您的位置:首页 > 编程语言 > Java开发

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

2010-01-11 15:59 573 查看
通过 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();


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

By CodingMouse

2010年1月11日
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐