Java模板方法模式詳解

模板方法模式詳解

一、模式定義

模板方法模式(Template Method Pattern)定義一個操作中的算法骨架,將某些步驟延遲到子類實現。

二、核心結構

1. 抽象模板類

public abstract class AbstractTemplate {// 模板方法(final防止子類覆蓋)public final void templateMethod() {step1();step2();step3();if(hook()) {step4();}}// 抽象方法(必須由子類實現)protected abstract void step2();// 具體方法(已有默認實現)protected void step1() {System.out.println("執行步驟1");}protected void step3() {System.out.println("執行步驟3");}// 鉤子方法(可選覆蓋)protected boolean hook() {return true;}protected void step4() {System.out.println("執行步驟4");}
}

2. 具體實現類

public class ConcreteClassA extends AbstractTemplate {protected void step2() {System.out.println("A實現-步驟2");}protected boolean hook() {return false; // 關閉步驟4}
}public class ConcreteClassB extends AbstractTemplate {protected void step2() {System.out.println("B實現-步驟2");}protected void step4() {System.out.println("B定制-步驟4");}
}

三、完整示例:飲料制作系統

1. 抽象飲料類

public abstract class BeverageTemplate {// 模板方法(final)public final void prepareBeverage() {boilWater();brew();pourInCup();if(customerWantsCondiments()) {addCondiments();}}protected abstract void brew();protected abstract void addCondiments();protected void boilWater() {System.out.println("煮沸水");}protected void pourInCup() {System.out.println("倒入杯中");}// 鉤子方法protected boolean customerWantsCondiments() {return true;}
}

2. 具體飲料實現

// 咖啡
public class Coffee extends BeverageTemplate {protected void brew() {System.out.println("沖泡咖啡粉");}protected void addCondiments() {System.out.println("加糖和牛奶");}protected boolean customerWantsCondiments() {String answer = getUserInput();return answer.toLowerCase().startsWith("y");}private String getUserInput() {System.out.print("要加糖和牛奶嗎(y/n)? ");BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));try {return reader.readLine();} catch (IOException e) {return "no";}}
}// 茶
public class Tea extends BeverageTemplate {protected void brew() {System.out.println("浸泡茶葉");}protected void addCondiments() {System.out.println("加檸檬");}
}

3. 客戶端使用

public class BeverageTest {public static void main(String[] args) {System.out.println("制作咖啡...");BeverageTemplate coffee = new Coffee();coffee.prepareBeverage();System.out.println("\n制作茶...");BeverageTemplate tea = new Tea();tea.prepareBeverage();}
}

四、高級應用:數據庫操作模板

1. 抽象DAO模板

public abstract class JdbcTemplate {// 模板方法public final <T> T execute(String sql, RowMapper<T> rowMapper) {Connection conn = null;PreparedStatement stmt = null;ResultSet rs = null;try {conn = getConnection();stmt = conn.prepareStatement(sql);setParameters(stmt);rs = stmt.executeQuery();return rowMapper.mapRow(rs);} catch (SQLException e) {throw new RuntimeException(e);} finally {closeResources(conn, stmt, rs);}}protected abstract void setParameters(PreparedStatement stmt) throws SQLException;protected Connection getConnection() throws SQLException {return DriverManager.getConnection("jdbc:mysql://localhost:3306/test");}protected void closeResources(Connection conn, Statement stmt, ResultSet rs) {try { if (rs != null) rs.close(); } catch (SQLException e) {}try { if (stmt != null) stmt.close(); } catch (SQLException e) {}try { if (conn != null) conn.close(); } catch (SQLException e) {}}
}

2. 行映射接口

public interface RowMapper<T> {T mapRow(ResultSet rs) throws SQLException;
}

3. 具體DAO實現

public class UserDao extends JdbcTemplate {public User findById(long id) {return execute("SELECT * FROM users WHERE id = ?", rs -> {User user = new User();user.setId(rs.getLong("id"));user.setName(rs.getString("name"));return user;});}protected void setParameters(PreparedStatement stmt) throws SQLException {stmt.setLong(1, 1L); // 設置查詢參數}
}

五、模式優勢

  1. 提高代碼復用性
  2. 實現反向控制(好萊塢原則)
  3. 便于擴展和維護
  4. 符合開閉原則

六、適用場景

  1. 多個類有相同算法結構
  2. 需要控制子類擴展點
  3. 存在公共行為需要抽取
  4. 框架設計中的流程控制

七、注意事項

  1. 模板方法應該聲明為final
  2. 合理設計抽象方法和鉤子方法
  3. 避免過度抽象導致復雜度增加
  4. 與策略模式區分使用場景

八、最佳實踐

  1. 使用鉤子方法提供靈活擴展點
  2. 保持模板方法簡潔
  3. 合理命名抽象方法
  4. 考慮與工廠方法模式結合使用
  5. 為常用操作提供默認實現

九、完整示例代碼結構

src/
├── main/
│ ├── java/
│ │ ├── template/
│ │ │ ├── AbstractTemplate.java
│ │ │ ├── ConcreteClassA.java
│ │ │ ├── ConcreteClassB.java
│ │ │ ├── BeverageTemplate.java
│ │ │ ├── Coffee.java
│ │ │ ├── Tea.java
│ │ │ ├── JdbcTemplate.java
│ │ │ ├── UserDao.java
│ │ │ └── BeverageTest.java

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/75764.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/75764.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/75764.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

(5)模擬后——Leonardo的可視化操作

1 引言 經過n天的模擬&#xff0c;模擬結果相信已經到手&#xff0c;但如何進行分析呢。 首先是可視化&#xff0c;可視化方法基本分為兩類 基于ENVI-met自帶軟件Leonardo的可視化操作基于NetCDF的可視化操作 2 模擬結果變量說明 首先&#xff0c;模擬結果會有以下幾個文件…

基于YOLO11實例分割與奧比中光相機的快遞包裹抓取點檢測

本博客來源于CSDN機器魚&#xff0c;未同意任何人轉載。 更多內容&#xff0c;歡迎點擊本專欄&#xff0c;查看更多內容。 0 引言 項目采用六軸機械臂搭配末端真空吸盤&#xff0c;從無序包裹中抓取想要的包裹。AI算法需要提供各包裹的抓取點的3D坐標與3D姿態。由于快遞包裹含…

【學Rust寫CAD】31 muldiv255函數(muldiv255.rs)

源碼 // Calculates floor(a*b/255 0.5) #[inline] pub fn muldiv255(a: u32, b: u32) -> u32 {// The deriviation for this formula can be// found in "Three Wrongs Make a Right" by Jim Blinn.let tmp a * b 128;(tmp (tmp >> 8)) >> 8 }代…

藍橋云客--團隊賽

2.團隊賽【算法賽】 - 藍橋云課 問題描述 藍橋杯最近推出了一項團隊賽模式&#xff0c;要求三人組隊參賽&#xff0c;并規定其中一人必須擔任隊長。隊長的資格很簡單&#xff1a;其程序設計能力值必須嚴格大于其他兩名隊友程序設計能力值的總和。 小藍、小橋和小杯正在考慮報名…

#Linux內存管理# 假設設備上安裝了一塊2G的物理內存,在系統啟動時,ARM Linux內核是如何映射的?

在ARM Linux系統啟動過程中&#xff0c;對2GB物理內存的映射實現分為以下幾個關鍵階段&#xff1a; 一、設備樹解析與內存信息獲取 1.設備樹定義 物理內存范圍通過設備樹&#xff08;DTS&#xff09;的memory節點定義&#xff0c;例如&#xff1a; memory60000000 { device_ty…

使用MATIO庫讀取Matlab數據文件中的多維數組

使用MATIO庫讀取Matlab數據文件中的多維數組 MATIO是一個用于讀寫Matlab數據文件(.mat)的開源C庫。下面是一個完整的示例程序&#xff0c;展示如何使用MATIO庫讀取Matlab數據文件中的多維數組。 示例程序 #include <stdio.h> #include <stdlib.h> #include <…

react+antd中做一個外部按鈕新增 表格內部本地新增一條數據并且支持編輯刪除(無難度上手)

需求背景 做一個可以外部控制新增刷新表格 表格內部可以編輯刪除 類似下方需求圖 實現過程 因為我實現時有兩個這樣的表格 所以我的事件里面會有傳參用于判斷 可忽略傳參判斷部分 代碼中有formatMessage部分為國際化可忽略 <div style{{ marginBottom: 10px, margin…

【深度學習新浪潮】視覺與多模態大模型文字生成技術研究進展與產品實踐

一、研究進展 跨模態架構創新 原生多模態模型:微軟KOSMOS系列通過統一框架支持文本、圖像、語音等多模態輸入輸出,實現跨模態推理與遷移。例如,KOSMOS-2.5可處理文本密集圖像,生成結構化文本描述,并通過重采樣模塊優化視覺與語言的對齊。混合專家架構:第三代模型(如Deep…

重生之我是去噪高手——diffusion model

diffusion model是如何運作的&#xff1f; 想象一下&#xff0c;你有一張清晰的圖片。擴散模型的核心思想分為兩個過程&#xff1a; 前向過程&#xff08;Forward Process / Diffusion Process&#xff09;&#xff1a;逐步加噪反向過程&#xff08;Reverse Process / Denois…

華為項目管理“六步一法”方法論全解析:目標確認、項目活動分解與日事清系統協同

大家都知道&#xff0c;項目管理在現在各個行業里都是越來越重要了。 要是搞不好&#xff0c;項目就會拖沓&#xff0c;甚至走向失敗。 今天咱們就來聊聊華為是怎么做項目管理的&#xff0c;比較知名的就是它們的“六步一法”。華為通過“六步一法”來進行項目管理&#xff0…

OpenCV 圖形API(9)用于執行矩陣與標量之間的逐元素除法操作函數divC()

操作系統&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 編程語言&#xff1a;C11 算法描述 矩陣除以標量。 該函數 divC 將矩陣 src 的每個元素除以給定的標量值&#xff1a; dst(I) saturate(src(I)*scale/divisor) \texttt{dst(I) s…

單例模式(懶漢模式/餓漢模式)

相關概念參考&#xff1a;【C】C 單例模式總結&#xff08;5種單例實現方法&#xff09;_單例模式c實現-CSDN博客 #include<iostream>class LazySingle{ public:static LazySingle& getInstance(){static LazySingle instance;return instance;}void hello(){std::c…

RocketMQ初認識

ProducerCustomerNameServer: Broker的注冊服務發現中心BrokerServer:主要負責消息的存儲、投遞和查詢以及服務高可用保證 RocketMQ的集群部署&#xff1a; 單個master的分支多個Master 模式&#xff1a;集群中有多個 Master 節點&#xff0c;彼此之間相互獨立。生產者可以將消…

Maven/Gradle的講解

一、為什么需要構建工具? 在理解 Maven/Gradle 之前,先明確它們解決的問題: ??依賴管理??:項目中可能需要引入第三方庫(如 Spring、JUnit 等),手動下載和管理這些庫的版本非常麻煩。??標準化構建流程??:編譯代碼、運行測試、打包成 JAR/WAR 文件等步驟需要自動…

基于SSM的車輛管理系統的設計與實現(代碼+數據庫+LW)

摘要 當下&#xff0c;正處于信息化的時代&#xff0c;許多行業順應時代的變化&#xff0c;結合使用計算機技術向數字化、信息化建設邁進。以前企業對于車輛信息的管理和控制&#xff0c;采用人工登記的方式保存相關數據&#xff0c;這種以人力為主的管理模式已然落后。本人結…

嵌入式硬件篇---JSON通信以及解析

文章目錄 前言一、JSON特點語法簡單數據格式靈活輕量化跨語言使用二、JSON數據結構對象數組三、JSON在單片機之間通信的應用數據封裝與傳輸四、JSON示例代碼五、JSON在上位機與單片機之間通信的應用數據交互六、JSON示例代碼七、JSON解析與生成解析生成八、Python中的數據解析1…

【C#】.net core 6.0 依賴注入常見問題之一,在構造函數使用的類,都需要注入到容器里,否則會提示如下報錯,讓DeepSeek找找原因,看看效果

&#x1f339;歡迎來到《小5講堂》&#x1f339; &#x1f339;這是《C#》系列文章&#xff0c;每篇文章將以博主理解的角度展開講解。&#x1f339; &#x1f339;溫馨提示&#xff1a;博主能力有限&#xff0c;理解水平有限&#xff0c;若有不對之處望指正&#xff01;&#…

《P1072 [NOIP 2009 提高組] Hankson 的趣味題》

題目描述 Hanks 博士是 BT&#xff08;Bio-Tech&#xff0c;生物技術) 領域的知名專家&#xff0c;他的兒子名叫 Hankson。現在&#xff0c;剛剛放學回家的 Hankson 正在思考一個有趣的問題。 今天在課堂上&#xff0c;老師講解了如何求兩個正整數 c1? 和 c2? 的最大公約數…

nginx的自動跳轉https

mkdir /usr/local/nginx/certs/ 創建一個目錄 然后用openssl生成證書 編輯nginx的配置文件 自動跳轉成功 做一個優化&#xff0c;如果訪問的時候后面加了其他的uri也一起自動跳轉了

力扣刷題——508.出現次數最多的子樹和

給你一個二叉樹的根結點 root &#xff0c;請返回出現次數最多的子樹元素和。如果有多個元素出現的次數相同&#xff0c;返回所有出現次數最多的子樹元素和&#xff08;不限順序&#xff09;。 一個結點的 「子樹元素和」 定義為以該結點為根的二叉樹上所有結點的元素之和&…