设计模式:模板设计模式

在spring加载配置文件的时候,可以有不同的加载方式,如根据文件系统目录加载配置文件(FileSystemXmlApplicationContext),类路径加载配置文件(ClassPathXmlApplicationContext),以及根据项目上下文目录(XmlWebApplicationContext)加载配置文件

先通俗的解释一下:完成一件事情,有固定的数个步骤,但是每个步骤根据对象的不同,而实现细节不同;就可以在父类中定义一个完成该事情的总方法,按照完成事件需要的步骤去调用其每个步骤的实现方法。每个步骤的具体实现,由子类完成。

abstract class Action {
    public static final int EAT = 1;
    public static final int SLEEP = 5;
    public static final int WORK = 7;

    public void command(int flag) {
        switch (flag) {
        case EAT:
            this.eat();
            break;
        case SLEEP:
            this.sleep();
            break;
        case WORK:
            this.work();
            break;
        case EAT + WORK:
            this.eat();
            this.work();
            break;
        }
    }

    public abstract void eat();

    public abstract void sleep();

    public abstract void work();
}

class Robot extends Action{
    @Override
    public void eat() {
        System.out.println("机器人充电");
    }

    @Override
    public void sleep() {   
    }

    @Override
    public void work() {
        System.out.println("机器人工作");
    }

}
class Human extends Action{
    @Override
    public void eat() {
        System.out.println("人类正在吃饭");
    }

    @Override
    public void sleep() {
        System.out.println("人类正在睡觉");
    }

    @Override
    public void work() {
        System.out.println("人类正在工作");
    }
}
class Pig extends Action{

    @Override
    public void eat() {
        System.out.println("猪在啃食槽");
    }

    @Override
    public void sleep() {
        System.out.println("猪在睡觉养胖");
    }

    @Override
    public void work() {
    }

}
public class TestDemo {
    public static void main(String[] args) {
        fun(new Robot());   
    }
    public static void fun(Action action){
        action.command(Action.EAT);
        action.command(Action.SLEEP);
        action.command(Action.WORK);
    }
}

这些不同的类型最终都在行为上成功的进行了抽象,即:如果要想使用行为操作,那么就必须按照Action类的标准来实现子类。

那个command就相当于一个模板/(表格),把模板/(表格)填上。
有一个公共的方法,根据用户发出的请求不同,调用不同的功能(这就是abstract方法,子类来具体继承)


模板设计模式常在数据库操作中使用,现在使用模板模式做一个JDBC的查询模板:

抽象查询父类

public abstract class AbstractDao {

    /**
     * 查询
     * @param sql
     * @param params
     * @return
     */
    protected Object find(String sql, Object[] params) {
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        Object obj = null;
        try {
            conn = JDBCUtils.getConnection();
            ps = conn.prepareStatement(sql);
            for (int i = 0; i < params.length; i++) {
                ps.setObject(i + 1, params[i]);
            }
            rs = ps.executeQuery();
            while (rs.next()) {
                obj = rowMapper(rs);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JDBCUtils.free(rs, ps, conn);
        }
        return obj;
    }

    protected abstract Object rowMapper(ResultSet rs) throws SQLException;

    //同时可以添加 insert ,update 等方法
}

具体的UserDao

/**
 * userDao
 * 
 * @author aries
 *
 */
public class UserDao extends AbstractDao {

    public User findUser(int userId) {
        String sql = "select * from t_user where userId = ?";
        Object[] params = new Object[] { userId };
        Object user = super.find(sql, params);
        System.out.println((User) user);
        return (User) user;
    }

    @Override
    protected Object rowMapper(ResultSet rs) throws SQLException {
        User user = new User();
        user.setId(rs.getInt("userId"));
        user.setName(rs.getString("name"));
        user.setAge(rs.getInt("age"));
        user.setSex(rs.getString("sex"));
        user.setAddress(rs.getString("address"));
        return user;
    }
}

以上代码中用到的User类和JDBCUtil

public class JDBCUtils {
    private static String url = "jdbc:mysql://localhost:3306/jdbcstudy";
    private static String user = "root";
    private static String password = "123";

    private JDBCUtils() {
    }

    static {
        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            throw new ExceptionInInitializerError(e);
        }
    }

    public static Connection getConnection() throws SQLException {
        return DriverManager.getConnection(url, user, password);
    }

    public static void free(ResultSet rs, PreparedStatement ps, Connection conn){
        if(rs != null){
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(ps != null){
            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        if(conn != null){
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

用户类User

/**
 * 用户类
 * 
 * @author aries
 *
 */
public class User {
    private Integer id;
    private String name;
    private Integer age;
    private String sex;
    private String address;

    //set...get省略    
}

如上就使用模板模式做的查询,父类中做了算法骨架,子类中具体实现算法中的不同部分。

猜你喜欢

转载自blog.csdn.net/guo_binglo/article/details/80552539