Template Method是我们最常用的模式,也是最好理解的模式了.
意图: 定义一个操作中的算法的骨架,而将一些步骤延迟到子类中. Template Method使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤.
问题: 需要遵循一个过程或一系列步骤, 它们在某个具体层次上保持一致, 但单个步骤在更详细的层次上可能有不同的实现.
效果: 模板为代码复用提供了一个优秀的平台. 它们还有助于确保需要的步骤得到实现. 它们为每个具体类将重载后的步骤捆绑在一起, 因此只有在这些重载方法总是并且只能一起发生时, 才应该使用Template Method模式.
实现: 创建一个抽象类, 用抽象方法实现一个过程. 这些抽象方法必须在子类中得到实现, 用以执行过程的每个步骤. 如果这些步骤各自独立变化, 那么每个步骤都可以用Strategy模式来实现.
实例: 我们需要一个分页查询功能,针对不同的数据库有mysql的和oracle的,一般有这么几个步骤:
创建连接
格式化sql语句
让数据库执行sql语句
返回查询结果
其中创建连接和格式化sql语句是不同的, 让数据库执行sql语句与返回查询的操作都相同,我们可以这样实现:
将操作步骤都封装到抽象类中, 并将执行步骤都封装到抽象类中, 不同的操作各自实现
java 代码
- public abstract class QueryTemplate {
- protected List doQuery() {
- List dataList = new ArrayList();
- try {
- Connection conn = getConnection();
- String sql = formatSql();
- Statement stmt = conn.createStatement();
- ResultSet rs = stmt.executeQuery(sql);
-
- while (rs.next()) {
- dataList.add(rs.getString("name"));
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- return dataList;
- }
-
- protected abstract Connection getConnection();
-
- protected abstract String formatSql();
- }
- public class OracleQTemplate extends QueryTemplate {
- public Connection getConnection() {
- System.out.println("getConnection");
- return null;
- }
-
- public String formatSql() {
- System.out.println("formatSql");
- return null;
- }
- }
- public class MysqlQTemplate extends QueryTemplate {
- protected Connection getConnection() {
- System.out.println("getConnection");
- return null;
- }
-
- protected String formatSql() {
- System.out.println("formatSql");
- return null;
- }
-
- }
是不是很简单呢? 其实就是我们常用的继承,哈哈, Template Method模式适用于"有几个不同但概念相似的步骤存在"的情况, 为我们提供了一个算法的框架.
代码实例: http://www.netobjectives.com/resources/books/design-patterns-explained/code-fragments