模板方法模式:

定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

模板方法模式实际上是所有模式中最为常见的几个模式之一,而且很多人可能使用过模板方法模式而没有意识到自己已经使用了这个模式。模板方法模式是基于继承的代码复用的基本技术,模板方法模式的结构和用法也是面向对象设计的核心。

缺点:算法骨架不容易升级(模板和子类是非常耦合的,如要对模板中的算法骨架进行变更,会影响子类变化)

UML结构图(以登录界面实现为例):

例(通过JDBC方式连接数据库):

//The "Template Method":

public abstract class DataObject {
   
	//Methods
	abstract public void Connect();
	abstract public void Select();
	abstract public void Process();
	abstract public void Disconnect();
	
	//The "Template Method"
	public void Run() {
   
		Connect();
		Select();
		Process();
		Disconnect();
	}
	
}
//具体实现:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class CustomerDataObject extends DataObject{
   

	//声明Connection对象
    Connection con;
    //驱动程序名
    String driver = "com.mysql.cj.jdbc.Driver";
    //URL指向要访问的数据库名mydata
    String url = "jdbc:mysql://localhost:3306/mysql"
    		+ "?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai";
    //数据库配置时的用户名
    String user = "root";
    //数据库配置时的密码
    String password = "******";

	//与微软的OLEDB有所不同,OLEDB在加载数据库的过程中直接就能完成连接和查询,但是JDBC需要手动进行连接数据库:
	@Override
	public void Connect() {
   
		try {
   
			Class.forName(driver);          
			//1.getConnection()方法,连接数据库
			con = DriverManager.getConnection(url,user,password);
			if(!con.isClosed())
			    System.out.println("Succeeded connecting to the Database!");
		} catch (ClassNotFoundException e) {
   
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		} catch (SQLException e) {
   
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}
	}

	@Override
	public void Select() {
   
		//不同的客户选择不同的适配
	}

	@Override
	public void Process() {
   
		//执行过程:
		try {
   
			//2.创建statement类对象,用来执行SQL语句!!
			Statement statement = con.createStatement();
			//要执行的SQL语句
			String sql = "select * from jdbc_test";
			//3.ResultSet类,用来存放获取的结果集!!
			ResultSet rs = statement.executeQuery(sql);
			System.out.println("--------------------------------------");
			System.out.println("执行结果如下所示:");  
			System.out.println("------------------------");  
			System.out.println("学号" + "\t" + "姓名" + "\t" + "性别" + "\t" + "年龄");  
			System.out.println("--------------------------------------");  
			String name= null;
			String id = null;
			String sex = null;
			String age = null;
			while(rs.next()){
   
			 //获取sno这列数据
			    id = rs.getString("sno");
			    //获取sname这列数据
			    name = rs.getString("sname");
			    //获取sex这列数据
			    sex = rs.getString("sex");
			    //获取age这列数据
			    age = rs.getString("age");
			    //输出结果
			    System.out.println(id + "\t" + name + "\t" + sex + "\t" + age);
			}
			rs.close();
			con.close();
		} catch (SQLException e) {
   
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		} finally{
   
            System.out.println("数据库数据成功获取!!");
        }
	}

	@Override
	public void Disconnect() {
   
		//程序结束时自动回收数据库连接
	}

}
//main:

public class Test {
   
	public static void main(String[] args) {
   
		DataObject dataObject = new CustomerDataObject();
		dataObject.Run();
	}
}