標籤:author 開閉原則 private 使用 ini sele system 模板方法 finally
模板設計模式定義:
定義一個操作中演算法的骨架,而將一些步驟延遲到子類中,模板方法使得子類可以不改變演算法的結構即可重定義該演算法的某些特定步驟。
通俗點的理解就是 :完成一件事情,有固定的數個步驟,但是每個步驟根據對象的不同,而實現細節不同;就可以在父類中定義一個完成該事情的總方法,按照完成事件需要的步驟去調用其每個步驟的實現方法。每個步驟的具體實現,由子類完成。
執行個體說明
來舉個例子: 比如我們做菜可以分為三個步驟 (1)備料 (2)具體做菜 (3)盛菜端給客人享用,這三部就是演算法的骨架 ;然而做不同菜需要的料,做的方法,以及如何盛裝給客人享用都是不同的這個就是不同的實現細節。
下來我們就代碼實現如下
a. 先來寫一個抽象的做菜父類:
public abstract class DodishTemplate { /** * 具體的整個過程 */ protected void dodish(){ this.preparation(); this.doing(); this.carriedDishes(); } /** * 備料 */ public abstract void preparation(); /** * 做菜 */ public abstract void doing(); /** * 上菜 */ public abstract void carriedDishes ();}
b. 下來做兩個番茄炒蛋(EggsWithTomato)和紅燒肉(Bouilli)實現父類中的抽象方法
/** * 西紅柿炒蛋 * @author aries */public class EggsWithTomato extends DodishTemplate{ @Override public void preparation() { System.out.println("洗並切西紅柿,打雞蛋。"); } @Override public void doing() { System.out.println("雞蛋倒入鍋裡,然後倒入西紅柿一起炒。"); } @Override public void carriedDishes() { System.out.println("將炒好的西紅寺雞蛋裝入碟子裡,端給客人吃。"); }}
/** * 紅燒肉 * @author aries * */public class Bouilli extends DodishTemplate{ @Override public void preparation() { System.out.println("切豬肉和馬鈴薯。"); } @Override public void doing() { System.out.println("將切好的豬肉倒入鍋中炒一會然後倒入馬鈴薯連炒帶燉。"); } @Override public void carriedDishes() { System.out.println("將做好的紅燒肉盛進碗裡端給客人吃。"); }}
c. 在測試類別中我們來做菜:
public class App { public static void main(String[] args) { DodishTemplate eggsWithTomato = new EggsWithTomato(); eggsWithTomato.dodish(); System.out.println("-----------------------------"); DodishTemplate bouilli = new Bouilli(); bouilli.dodish(); }}
這樣我們就實現了使用模板模式的一個完整的執行個體。
模板設計模式常在資料庫操作中使用,我現在使用模板模式做一個JDBC的查詢範本:
(1) 抽象查詢父類
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 等方法}
(2)具體的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; }}
(3)以上代碼中用到的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(); } } }}
/** * 使用者類 * * @author aries * */public class User { private Integer id; private String name; private Integer age; private String sex; private String address; //set...get省略 }
如上就使用模板模式做的查詢,父類中做了演算法骨架,子類中具體實現演算法中的不同部分。
模板模式的優點
(1)具體細節步驟實現定義在子類中,子類定義詳細處理演算法是不會改變演算法整體結構。
(2)代碼複用的基本技術,在資料庫設計中尤為重要。
(3)存在一種反向的控制結構,通過一個父類調用其子類的操作,通過子類對父類進行擴充增加新的行為,符合“開閉原則”。
不足
每個不同的實現都需要定義一個子類,會導致類的個數增加,系統更加龐大。
設計模式--模板模式