java设计模式-模板方法模式

模板方法模式概念

模板方法模式属于行为型模式,它定义一个操做中的算法的骨架,而将一些步骤推迟到子类当中实现。父类抽取并实现的是公共方法,对于可变方法,父类作的只是定义了可变行为的接口,具体实现留给子类去完成,实现对代码的重复利用。java

模板方法模式类图

这里的templateMethod方法就是公共方法,是全部子类所拥有的公共行为;abstractMethod方法就是可变的行为,是每一个子类独特行为,这种行为只能由它们来实现。算法

模板方法模式实现

拿<<大话设计模式>>上的例子来讲,学生是共用一套试卷,只是学生各自的答案是不一样的;所以,试题题目是模板方法是不变的,而试题答案对于每一个学生是可变的spring

/**
 *@author 
 *@date 2016/8/31 
 */
public abstract class AbstractTemplate {
    private String name;
    public AbstractTemplate(String name){
        this.name = name;
    }
    public void question(){
        System.out.print(name + ":1 + 1 = ");
        System.out.print(answer());
        System.out.println();
    }
    public abstract int answer();
}

public class StudentATemplate extends AbstractTemplate{
    @Override
    public int answer() {
        return 2;
    }
    public StudentATemplate(String name) {
        super(name);
    }
}

public class StudentBTemplate extends AbstractTemplate{
    public StudentBTemplate(String name) {
        super(name);
    }
    @Override
    public int answer() {
        return 3;
    }
}

模板方法在spring中的运用

spring中的JdbcTemplate类就运用了模板方法,java在执行数据库操做时的步骤无非以下几步: 
1. 加载驱动 
2. 创建链接 
3. 获取Statement 
4. 拼接参数(针对PreparedStatement) 
5. 执行 
6. 返回结果 
7. 销毁链接sql

在这里只是简单,介绍一下,所以针对PreparedStatement,最大的可变之处就是5,6这个部分,所以JdbcTemplate将1,2,3,4,7制做成模板(主要在execute*方法中),而对于5,6它经过匿名内部类的形式来实现(也就是说对于update、query等等操做,都对5,6经过匿名内部类有不一样的实现,匿名内部类实现的都是*callback接口,*callback都是额外定义的接口)数据库

@Override
public <T> T query(final String sql, final ResultSetExtractor<T> rse) throws DataAccessException {
    Assert.notNull(sql, "SQL must not be null");
    Assert.notNull(rse, "ResultSetExtractor must not be null");
    if (logger.isDebugEnabled()) {
        logger.debug("Executing SQL query [" + sql + "]");
    }
    //匿名内部类
    class QueryStatementCallback implements StatementCallback<T>, SqlProvider {
        @Override
        public T doInStatement(Statement stmt) throws SQLException {
            ResultSet rs = null;
            try {
                rs = stmt.executeQuery(sql);
                ResultSet rsToUse = rs;
                if (nativeJdbcExtractor != null) {
                    rsToUse = nativeJdbcExtractor.getNativeResultSet(rs);
                }
                return rse.extractData(rsToUse);
            }
            finally {
                JdbcUtils.closeResultSet(rs);
            }
        }
        @Override
        public String getSql() {
            return sql;
        }
    }
    //真正执行的方法
    return execute(new QueryStatementCallback());
}

这里只贴出了其中一个query方法,其余的”套路”都跟它差很少,若是感兴趣的话本身能够深究一下JdbcTemplate源码设计模式

模板方法模式优缺点

优势:ide

  • 抽出不变行为,对代码的重复利用;要扩展的话,只需添加子类

缺点:this

  • 按照咱们的设计习惯,抽象类负责声明最抽象、最通常的事情属性和方法,实现类完成具体的事物属性和方法。可是模板方法模式却颠倒了,抽象类定义了部分抽象方法,由子类实现,子类执行结果影响了父类的结果,也就是子类对父类产生了影响,这在复杂的项目中,会带来代码阅读的难度,并且也会让新手产生不适感
  • 由于引入了一个抽象类,若是具体实现过多的话,须要用户或开发人员须要花更多的时间去理清类之间的关系
相关文章
相关标签/搜索