设计模式03-工厂方法
1.引言
抛弃ssh开发自己的框架(公司中一般都采用了内部的技术框架)在做orm中最重要的一点就是要支持各种主流的数据库 , 实际开发中用于生产的数据库一般为DB2 Oracle SqlServer居多,由于各数据库的厂商不同 ,导致数据库库之间都存在各自的特性。 例如:数据的分页
oracle 采用rownum伪列 db2 采用 rownumber()over() sqlserver 可以使用rownumber top等关键字
因此在实现orm的搭建的时候就需要考虑到各数据库的特点 采用不同的代码来体现
2.通过工厂方法来兼容各大数据库特性
以各个数据库的分页为例
在分页的时候一般情况下会对分页的信息进行封装:封装到PageResult类中
/** * 保存分页的信息 */ class PageResult<T>{ private int curPage ; //当前页 private int pageSize ; //每页显示的记录数 private int totalPage ; //总页数 = (总记录数+每页显示的记录数-1)/每页显示的记录数 private int totalRecords ; //总记录数 private List<T> entityList = new ArrayList<T>() ; //分页数据保存的集合 //getter 和 setter方法 }
各数据库分页是通过分页查询的方法获得数据 ,可抽象出一个接口 : DataQuery
/** * 数据查询 :这里以分页为特例 */ interface DataQuery{ /** * @param sql : 查询的sql语句 * @param paramsList : 参数 * @param curPage : 当前页 * @param pageSize :每页显示的记录数 * @return */ public <T> PageResult<T> splitQuery(String sql,List paramsList,int curPage,int pageSize) ; }
实现上面的接口 体现不同数据库的分页特性:
OracleDataQuery
class OracleDataQuery implements DataQuery{ @Override public <T> PageResult<T> splitQuery(String sql, List paramsList, int curPage, int pageSize) { System.out.println("oracle 数据库分页实现"); //等待以后去实现 return null; } }
Db2DataQuery
class Db2DataQuery implements DataQuery{ @Override public <T> PageResult<T> splitQuery(String sql, List paramsList, int curPage, int pageSize) { System.out.println("Db2 数据库分页实现"); //等待以后去实现 return null; } }
实际开发中为了获得DataQuery对象 当然不会选择去直接 new OracleDataQuery() 或者new Db2DataQuery() 了 一般通过创建DataQuery的工厂+反射来获得实际分页实现对象
我们知道 工厂方法定义了一个用于创建对象的接口,让子类决定实例化哪一个类 按照以上的原理创建了一下的接口:
interface POJOFactory{ //数据库操作的若干方法省略 public DataQuery getDataQuery() ; }
来获得DataQuery, 让其子类来实例化对象
class OracleFactory implements POJOFactory{ @Override public DataQuery getDataQuery() { return new OracleDataQuery(); } } class Db2Factory implements POJOFactory{ @Override public DataQuery getDataQuery() { return new Db2DataQuery(); } }
客户端的调用:
public class FacotoryMethodDemo { public static void main(String[] args) { POJOFactory oracleFactory = new OracleFactory() ; DataQuery dataQuery = oracleFactory.getDataQuery() ; dataQuery.splitQuery(null, null, 0, 0) ; } }
要注意的是: 在实际开发中底层选择的数据库信息是通过配置文件来指定的 (例如hibernate中通过dialect来指定采用何种数据库) 通过解析配置文件 然后利用反射机制(或者简单工厂)来获得POJOFactory,而不是想上面客户端那样简单的调用 .
以下为本章节中的具体代码:
/********************************************************************** * <pre> * FILE : FacotoryMethodDemo.java * CLASS : FacotoryMethodDemo * * AUTHOR : Liaokailin * * FUNCTION : TODO * * *====================================================================== * CHANGE HISTORY LOG *---------------------------------------------------------------------- * MOD. NO.| DATE | NAME | REASON | CHANGE REQ. *---------------------------------------------------------------------- * |2014-3-25|Liaokailin| Created | * DESCRIPTION: * </pre> ***********************************************************************/ package org.lkl.patterns.factorymethod; import java.util.ArrayList; import java.util.List; /** * 工厂方法案例 */ public class FacotoryMethodDemo { public static void main(String[] args) { POJOFactory oracleFactory = new OracleFactory() ; DataQuery dataQuery = oracleFactory.getDataQuery() ; dataQuery.splitQuery(null, null, 0, 0) ; } } /** * 数据查询 :这里以分页为特例 */ interface DataQuery{ /** * @param sql : 查询的sql语句 * @param paramsList : 参数 * @param curPage : 当前页 * @param pageSize :每页显示的记录数 * @return */ public <T> PageResult<T> splitQuery(String sql,List paramsList,int curPage,int pageSize) ; } /** * 保存分页的信息 */ class PageResult<T>{ private int curPage ; //当前页 private int pageSize ; //每页显示的记录数 private int totalPage ; //总页数 = (总记录数+每页显示的记录数-1)/每页显示的记录数 private int totalRecords ; //总记录数 private List<T> entityList = new ArrayList<T>() ; //分页数据保存的集合 //getter 和 setter方法 } class OracleDataQuery implements DataQuery{ @Override public <T> PageResult<T> splitQuery(String sql, List paramsList, int curPage, int pageSize) { System.out.println("oracle 数据库分页实现"); //等待以后去实现 return null; } } class Db2DataQuery implements DataQuery{ @Override public <T> PageResult<T> splitQuery(String sql, List paramsList, int curPage, int pageSize) { System.out.println("Db2 数据库分页实现"); //等待以后去实现 return null; } } interface POJOFactory{ //数据库操作的若干方法 public DataQuery getDataQuery() ; } class OracleFactory implements POJOFactory{ @Override public DataQuery getDataQuery() { return new OracleDataQuery(); } } class Db2Factory implements POJOFactory{ @Override public DataQuery getDataQuery() { return new Db2DataQuery(); } }