【学习背景】
做过很多项目,会发现基本上都会有一个名为base的package。它的设计思路从何而来?下面就以此次学习
项目的dao层为例,看看basedao是如何一步步设计出来的。
【学习过程】
项目结构也是采用简单的三层思想,分别对应为dao、service和action,加上面向接口编程的设计思想,又
在dao和service层添加了实现层。下图为项目目录结构:
而我们一般以数据库的表对应dao层中的类,因此,每个单独的表至少都会产生一个单独的dao类。而每个
dao类中都会存在共有的一些基本方法,如:增、删、改、查(按主键id查询)。这样一来,代码就开始泛滥了。
很容易,我们就想到了抽象和封装,新建一个basedao作为基类,其它的类都继承这个基类。而每个类所需
要传递的参数不一样,这时候以前经常听到的泛型就用上了。
因此,我们可以很快地将basedao中基本的方法定义好,代码如下:
package cn.itcast.oa.base;
import java.util.List;
public interface BaseDao<T> {
/**
* 保存实体
* @param entity
*/
void save(T entity);
/**
* 删除实体
* @param id
*/
void delete(Long id);
/**
* 更新实体
* @param entity
*/
void update(T entity);
/**
* 按id查询
* @param id
* @return
*/
T getById(Long id);
/**
* 查询所有
* @param entity
* @return
*/
List<T> findAll(T entity);
/**
* 按id查询
* @param ids
* @return
*/
List<T> getByIds(Long[] ids);
}
至此,我们解决了dao层中重复代码的问题,那么接下来的一个问题便是dao实现层。既然每个dao类都会继
承basedao,那么每个dao的实现层都需要去实现basedao中的所有方法,第二次泛滥开始了。
所以,我们还需要继续抽象和封装下去,新建一个basedao的实现类,让其他实现类在继承BaseDaoImpl类的
基础上去实现各自的类,uml示意图如下:
这样一来,我们才算是真正解决了dao层代码重复性的问题,也意味着dao层的base基类也设计完毕了。
在这里,提一个实现过程中的问题:在实现层中如何获取到各自类的类名,从而保证泛型的使用。
解决的方法用到的是反射技术,代码如下:
public BaseDaoImpl(){
//使用反射技术得到T的真实类型
ParameterizedType pt=(ParameterizedType)this.getClass().getGenericSuperclass(); //获取当前new的对象的泛型的父类类型
this.clazz=(Class<T>)pt.getActualTypeArguments()[0]; //获取第一个类型参数的真实类型
System.out.println("clazz---->" + clazz);
}
【学习总结】 项目接触的越来越多了,而之前很长一段时间可以说是都处在知识的积累阶段,很多项目在学习过程中并不
是所有的东西都能理解或说是get到。但,后面的学习一方面会让我们和前期的学习产生联系和共鸣,另一方面我们
又在获取新的知识。这一次的学习,便是成长的见证。