设计模式---模板模式(Template)
目录
- 简介
- 包含角色
- UML类图
- java实现
- 优缺点
1. 简介
定义一个操作中的算法的骨架,而将一些步骤延迟到子类中,使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤
2. 包含角色
2.1 抽象模板角色
- 定义了一个或多个抽象操作,以便让子类实现,这些操作叫做基本操作
- 定义并实现了一个模板方法,这个模板方法一般是一个具体方法,它给出了一个顶级逻辑的骨架,而逻辑的组成步骤在相应的抽象操作中,推迟到子类实现
2.2 具体模板角色
- 实现父类锁定义的一个或多个抽象方法,他们是一个顶级逻辑的组成部分
- 每一个抽象模板角色都可以由任意多个具体模板角色与之对应,而每一个具体模板角色都可以给出这些抽象方法的不同实现,从而使得顶级逻辑的实现各不相同
3. UML类图
4. java实现
以JDBC连接数据库为例,mysql和oracle链接数据库
4.1 抽象策略角色
/**
* @program: pattern
* @description: jdbc的链接抽象类
* @author: chengqj
* @create: 2018-07-30 18:59
**/
public abstract class AbstractJdbcTemplate {
public List<?> executeQuery(String sql) {
//1、获取连接
Connection conn = getConnection();
//2、创建语句集
PreparedStatement pstmt = createPreparedStatement(conn, sql);
//3、执行语句集,并且获得结果集
ResultSet rs = execute(pstmt);
//4、解析语句集
List<?> result = parseResultSet(rs);
//5、各个服务关闭
close(conn, pstmt, rs);
return null;
}
protected abstract Connection getConnection();
protected abstract List<?> parseResultSet(ResultSet rs);
protected PreparedStatement createPreparedStatement(Connection conn, String sql) {
try {
return conn.prepareStatement(sql);
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
protected ResultSet execute(PreparedStatement pstmt) {
try {
return pstmt.executeQuery();
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
protected void close(Connection conn, PreparedStatement pstmt, ResultSet rs) {
try {
rs.close();
pstmt.close();
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
4.2 具体策略角色1(mysql)
/**
* @program: pattern
* @description: mysql的数据库链接实现
* @author: chengqj
* @create: 2018-07-30 19:05
**/
public class MysqlJDBCTemplate extends AbstractJdbcTemplate {
@Override
protected Connection getConnection() {
System.out.println("mysql执行 parseResultSet");
try {
Class.forName("com.mysql.jdbc.Driver");// 动态加载mysql驱动
String url = "jdbc:mysql://localhost:3306/demo";
Connection conn = DriverManager.getConnection(url);
return conn;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
protected List<?> parseResultSet(ResultSet rs) {
System.out.println("mysql执行 parseResultSet");
List<String> resultList = new ArrayList<>();
try {
while (rs.next()) {
resultList.add(rs.getString("mysqlcolumnName"));
}
} catch (Exception e) {
e.printStackTrace();
}
return resultList;
}
}
4.3 具体策略角色2(Oracle)
/**
* @program: pattern
* @description: Oracle连接数据库
* @author: chengqj
* @create: 2018-07-30 19:17
**/
public class OracleJDBCTemplate extends AbstractJdbcTemplate{
@Override
protected Connection getConnection() {
String url = "jdbc:oracle:thin:@//127.0.0.1:1521/orcl"; //连接字符串
String username = "system"; //用户名
String password = "123456"; //密码
try{
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection conn = DriverManager.getConnection(url, username, password);
return conn;
}catch (Exception e){
e.printStackTrace();
}
return null;
}
@Override
protected List<?> parseResultSet(ResultSet rs) {
System.out.println("mysql执行 parseResultSet");
List<String> resultList = new ArrayList<>();
try{
while (rs.next()) {
resultList.add(rs.getString("oraclecolumnName"));
}
}catch (Exception e){
e.printStackTrace();
}
return resultList;
}
}
5. 优缺点
5.1 优点
具体细节步骤实现定义在子类中,子类定义详细处理算法是不会改变算法整体结构
5.2 缺点
每个不同的实现都需要定义一个子类,会导致类的个数增加,系统更加庞大