模板方法模式(Template Method Pattern)

模板方法模式(Template Method Pattern)

定义一个骨架,允许子类为其中一个或者多个步骤提供实现。简而言之,就是使用一个类的方法对流程进行规范,子类对这些方法进行实现,以便于达到流程统一的目的。各个子类的公共行为被提取出来放在公共的父类中,其中的某个流程可以交给子类去自己实现,子类也可以选择不实现,作为父类可以定义一个钩子方法,以此告知父类是否执行父类的实现方法,最典型的一个例子就是JDBCTEMPLATE.下面我会写一个简单课程发布的demo,然后模拟一个jdbctempleate写一个demo。

 launch a course

public abstract  class AbstractCourse {
    boolean needPpt;

    AbstractCourse(boolean needPpt) {
        this.needPpt = needPpt;
    }

   // the whole process will be controled here
final void createCourse() { postPreResource(); liveVideo(); postResource(); postHomework();
    // here we judge whether the method that should be exucuted or not
if (needPpt()) { createPPT(); } } private boolean needPpt() { return needPpt; } private void postHomework(){ System.out.println("postHomework"); } private void postResource(){ System.out.println("postResource"); } private void liveVideo(){ System.out.println("liveVideo"); }   // this is a hook method protected abstract void createPPT(); private void postPreResource(){ System.out.println("postPreResource"); } }
  • first, we should have a method to control the whole process
  • second,we could have a method to let subclass to implement,we call hook method
  • finally,we can give subclass power whether  i need implement father class or not
public class Arithmetic  extends  AbstractCourse {

    Arithmetic(boolean needPpt) {
        super(needPpt);
    }

    @Override
    protected void createPPT() {
        System.out.println("createPPT of  Arithmetic");
    }
}
public class JavaCourse extends  AbstractCourse {
    JavaCourse(boolean needPpt) {
        super(needPpt);
    }
    @Override
    protected void createPPT() {
        System.out.println("create ppt of java");
    }
}

To test(we can control whether we need to create a ppt or not dynamically)

public class Test {
    public static void main(String[] args) {
        Arithmetic arithmetic=new Arithmetic(true);
        arithmetic.createCourse();

        System.out.println("---------JavaCourse-----------------");
        JavaCourse javaCourse=new JavaCourse(false);
        javaCourse.createCourse();
    }
}

there is a  scene to simulate jdbcTemplate

public abstract class JdbcTemplate {
    private DataSource dataSource;
    public JdbcTemplate(DataSource dataSource) {
        this.dataSource = dataSource;
    }


  // formulate a process
public final List<?> executeQuery(String sql, RowMapper<?> rowMapper, Object[] values) { try { //simulate get data Connection connection = this.getConnection(); PreparedStatement statement = this.createPrePareStatement(connection, sql); ResultSet resultSet = this.executeQuery(statement, values);
      // here could be a hook method List
<?> result = this.parseResultSet(resultSet, rowMapper); return result; } catch (Exception e) { e.printStackTrace(); } // get connection return null; } private List<?> parseResultSet(ResultSet resultSet, RowMapper<?> rowMapper) throws Exception { List<Object> result = new ArrayList<Object>(); int rowNum = 1; while (resultSet.next()) { Object o = rowMapper.mapRow(resultSet, rowNum++); result.add(o); } return result; } private ResultSet executeQuery(PreparedStatement statement, Object[] values) throws SQLException { for (int i = 0; i < values.length; i++) { statement.setObject(i, values); } return statement.executeQuery(); } private PreparedStatement createPrePareStatement(Connection connection, String sql) throws SQLException { return connection.prepareStatement(sql); } private Connection getConnection() throws Exception { return this.dataSource.getConnection(); } }

each dao want to query whole data should to implement a interface called RowMapper,in class named JdbcTemplate  will cope with the RowMapper you implement

public class MemberDao  extends JdbcTemplate {

    public MemberDao(DataSource dataSource) {
        super(dataSource);
    }

    public List<?> selectAll() {
        String sql="Select * from t_member";
        return super.executeQuery(sql, new  () {
            @Override
            public Member mapRow(ResultSet rs, int rowNum) throws Exception {
                Member member = new Member();
                member.setUsername(rs.getString("username"));
                member.setPassword(rs.getString("password"));
                member.setAge(rs.getInt("age"));
                member.setAddr(rs.getString("addr"));
                return member;
            }
        },null);
    }
}

additional assistant class

public interface RowMapper<T> {
    T mapRow(ResultSet resultSet,int rowNum) throws Exception;
}
@Data
public class Member {
    private String username;
    private String password;
    private String nickname;
    private int age;
    private String addr;
}

 To test

public class Test {
    public static void main(String[] args) {
        MemberDao memberDao=new MemberDao(null);
        memberDao.selectAll();
    }
}

How is Template Method  used in source of code

java.util.AbstractList#get

 

 

 apparently,it is an abstract method(hook method),but it is called in the same class, as we mentiond other examples

 

javax.servlet.http.HttpServlet#doGet(actually,in source of code, it wasn't  implemented, so it like a hook method)

 

org.apache.ibatis.executor.BaseExecutor#doUpdate

 

 

  

 

 

Sum up

advantages:

  • reusability:makeing the same logical code in the one class
  • expansibility:different subclass do different code

disadvatnages:

  if we need add a new method,that means we need to add a new method to every subclasses

 

posted @ 2021-05-14 13:06  UpGx  阅读(65)  评论(0编辑  收藏  举报