模版方法模式詳解:使用和實現的指南

目錄

  • 模版方法模式
    • 模版方法模式結構
    • 模版方法模式適合應用場景
    • 模版方法模式優缺點
    • 練手題目
      • 題目描述
      • 輸入描述
      • 輸出描述
      • 題解

模版方法模式

模板方法模式是一種行為設計模式, 它在超類中定義了一個算法的框架, 允許子類在不修改結構的情況下重寫算法的特定步驟。

類比真實世界中建造大量房屋。 標準房屋建造方案中可提供幾個擴展點, 允許潛在房屋業主調整成品房屋的部分細節。

每個建造步驟 (例如打地基、 建造框架、 建造墻壁和安裝水電管線等) 都能進行微調, 這使得成品房屋會略有不同。

在這里插入圖片描述

模版方法模式結構

在這里插入圖片描述

  1. 抽象類 (Abstract-Class) 會聲明作為算法步驟的方法, 以及依次調用它們的實際模板方法。 算法步驟可以被聲明為 抽象類型, 也可以提供一些默認實現。

  2. 具體類 (Concrete-Class) 可以重寫所有步驟, 但不能重寫模板方法自身。

一般,模版方法都加上final關鍵字,不允許被覆寫。

通用代碼結構

//抽象類定義了一個模板方法,其中通常會包含某個由抽象原語操作調用組成的算法框架。
public abstract class AbstractClass{//基本算法步驟protected abstract void step1();protected abstract void step2();//模版方法final public void templateMethod(){//算法基本邏輯this.step1();this.step2();...}
}// 具體類必須實現基類中的所有抽象操作,但是它們不能重寫模板方法自身。
public class ConcreteClass1 extends AbstractClass{//實現基本方法protected abstract void step1(){...};protected abstract void step2(){....};
}public class ConcreteClass2 extends AbstractClass{//實現基本方法protected abstract void step1(){...};protected abstract void step2(){....};
}//客戶端
public class Client{public static void main(String[] args){AbstractClass class1 = new ConcreteClass1();AbstractClass class2 = new ConcreteClass2();class1.templateMethod();class2.templateMethod();}
}

模版方法模式適合應用場景

  • 當你只希望客戶端擴展某個特定算法步驟,而不是整個算法或其結構時,可使用模板方法模式。

  • 當多個類的算法除一些細微不同之外幾乎完全一樣時,你可使用該模式。但其后果就是,只要算法發生變化,你就可能需要修改所有的類。

在這里插入圖片描述

**識別方法:**模版方法可以通過行為方法來識別,該方法已有一個在基類中定義的 “默認” 行為。

模版方法模式優缺點

模版方法模式的優點

  • 你可僅允許客戶端重寫一個大型算法中的特定部分, 使得算法其他部分修改對其所造成的影響減小。

  • 你可將重復代碼提取到一個超類中。

模版方法模式的缺點

  • 部分客戶端可能會受到算法框架的限制。

  • 通過子類抑制默認步驟實現可能會導致違反里氏替換原則

  • 模板方法中的步驟越多, 其維護工作就可能會越困難。

練手題目

題目描述

小明喜歡品嘗不同類型的咖啡,她發現每種咖啡的制作過程有一些相同的步驟,他決定設計一個簡單的咖啡制作系統,使用模板方法模式定義咖啡的制作過程。系統支持兩種咖啡類型:美式咖啡(American Coffee)和拿鐵(Latte)。

咖啡制作過程包括以下步驟:

  1. 研磨咖啡豆 Grinding coffee beans

  2. 沖泡咖啡 Brewing coffee

  3. 添加調料 Adding condiments

其中,美式咖啡和拿鐵的調料添加方式略有不同, 拿鐵在添加調料時需要添加牛奶Adding milk

輸入描述

多行輸入,每行包含一個數字,表示咖啡的選擇(1 表示美式咖啡,2 表示拿鐵)。

輸出描述

根據每行輸入,輸出制作咖啡的過程,包括咖啡類型和各個制作步驟,末尾有一個空行。

在這里插入圖片描述

題解

模版方法實現。

import java.util.Scanner;// 抽象類,定義咖啡制作的基本步驟
abstract class CoffeeModel {private String coffeeName;// 構造函數,接受咖啡名稱參數public CoffeeModel(String coffeeName) {this.coffeeName = coffeeName;}protected abstract void grind();protected abstract void brew();protected abstract void addCondiments();// 添加其他調料可使用該類public void addThings(){};// 模板方法,定義咖啡制作的流程public final void createCoffeeTemplate() {System.out.println("Making " + coffeeName + ":");grind();brew();//根據情況,是否調用添加更多調料if (isAddThings()) {addThings(); }addCondiments();System.out.println();}// 默認不添加其他調料。如牛奶等public boolean isAddThings() {return false;}
}//美式咖啡類實現
class CreateAmericanCoffee extends CoffeeModel {public CreateAmericanCoffee() {super("American Coffee");}@Overrideprotected void grind() {System.out.println("Grinding coffee beans");}@Overrideprotected void brew() {System.out.println("Brewing coffee");}@Overrideprotected void addCondiments() {System.out.println("Adding condiments");}// 美式咖啡默認不添加其他調料,如牛奶等@Overridepublic boolean isAddThings() {return false; }
}//拿鐵類實現
class CreateLatte extends CoffeeModel {private boolean addThingsFlag = true;public CreateLatte() {super("Latte");}@Overrideprotected void grind() {System.out.println("Grinding coffee beans");}@Overrideprotected void brew() {System.out.println("Brewing coffee");}@Overrideprotected void addCondiments() {System.out.println("Adding condiments");}//需要添加調料,牛奶@Overridepublic void addThings(){System.out.println("Adding milk");}// 拿鐵默認添加牛奶@Overridepublic boolean isAddThings() {return this.addThingsFlag; }// 外部調用以改變是否添加牛奶的狀態,鉤子函數public void setAddThingsFlag(boolean flag) {this.addThingsFlag = flag;}
}public class Main {public static void main(String[] args) {try (Scanner scanner = new Scanner(System.in)) {while (scanner.hasNextInt()) {int input = scanner.nextInt();CoffeeModel coffee;switch (input) {case 1:coffee = new CreateAmericanCoffee();break;case 2:coffee = new CreateLatte();break;default:System.out.println("無效選擇,請輸入1或2");continue;}coffee.createCoffeeTemplate();}}}
}

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

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

相關文章

《昇思25天學習打卡營第3天|張量 Tensor》

文章目錄 前言:今日所學:1. 創建張量2. 張量的屬性3.張量索引與運算4. NumPy與Tensor的轉換5. 稀疏張量 前言: 張量?張亮?張量是什么? 張量是一個可以用來表示在一些矢量、標量和其他張量之間的線性關系的…

高并發部署:基于 Gunicorn、Flask 和 Docker

一、準備工作 確保已經安裝以下軟件: DockerDocker ComposePython 3.x 二、創建 Flask 應用 首先,創建一個簡單的 Flask 應用。創建一個新的目錄并在其中創建以下文件: 1. app.py python fromflask importFlask, jsonifyapp Flask(__…

leetcode 第133場雙周賽 100333.統計逆序對的數目【計數dp/滾動數組/前綴和優化】

分析: 先考慮如下問題。 求長度為n,逆序對為m的排列數量。 可以考慮dp,dp[i][j]定義為長度為i,逆序對為j的排列數量。 dp[1][0] 1; //枚舉排列長度,或者認為枚舉當前需要插到長度為i-1的排列中的數字 for(int i 1…

OpenAI封殺不支持地區API:違規封號,7月9日生效

OpenAI 在檢測用戶使用其 API 的地區后,提示所有不支持位置的用戶 昨晚,很多大模型應用的開發者、程序員都收到了 OpenAI 的警告信,心里一驚。 OpenAI 在檢測用戶使用其 API 的地區后,提示所有不支持位置的用戶:即將封…

冒泡排序、選擇排序、插入排序~java版

1、冒泡排序(Bubble Sort) 冒泡排序的基本思想是多次遍歷待排序序列,每次遍歷時兩兩比較相鄰元素,如果順序不對則交換,直到整個序列有序為止。 public class BubbleSort {public static void bubbleSort(int[] arr) …

圖書管理系統(附源碼)

前言:前面一起和小伙伴們學習了較為完整的Java語法體系,那么本篇將運用這些知識連串在一起實現圖書管理系統。 目錄 一、總體設計 二、書籍與書架 書籍(Book) 書架(Booklist) 三、對圖書的相關操作 I…

已解決問題 | 該擴展程序未列在 Chrome 網上應用店中,并可能是在您不知情的情況下添加的

在Chrome瀏覽器中,如果你看到“該擴展程序未列在 Chrome 網上應用店中,并可能是在您不知情的情況下添加的”這樣的提示,通常是因為該擴展程序沒有通過Chrome網上應用店進行安裝。以下是解決這個問題的步驟: 解決辦法:…

Spring Boot整合Redis緩存的最佳實踐

Spring Boot整合Redis緩存的最佳實踐 大家好,我是免費搭建查券返利機器人省錢賺傭金就用微賺淘客系統3.0的小編,也是冬天不穿秋褲,天冷也要風度的程序猿! 在現代應用開發中,緩存是提升系統性能和響應速度的關鍵技術之…

kali/ubuntu安裝vulhub

無須更換源,安裝docker-compose apt install docker.io docker -vdocker-compose #提示沒有,輸入y安裝mkdir -p /etc/docker vi /etc/docker/daemon.json #更換dockerhub國內源┌──(root?kali)-[/home/kali/vulhub-master/tomcat/CVE-2017-12615] …

【VScode】常規插件安裝

以下是VScode常規插件安裝: C/C C/C extension pack C/C themes Draw.io integration highlight 以上插件安裝完畢后,可實現 字體高亮,自動補齊,函數跳轉,主題切換,圖表生成等常用功能。

中介子方程三十七

XXFXXuXXWXXuXXdXXrXXαXXuXpXXKXηXiXXnXXyXηXyXXnXXiXηXKXXpXuXXαXXrXXdXXuXWXπXXWXeXyXeXbXπXpXXNXXqXeXXrXXαXXuXpXXKXηXiXXnXXyXηXyXXnXXiXηXKXXpXuXXαXXrXXeXqXXNXXpXπXbXeXyXeXWXXπXWXuXXdXXrXXαXXuXpXXKXηXiXXnXXyXηXyXXnXXiXηXKXXpXuXXαXXrXXdXXuXXW…

【TensorFlow深度學習】對比學習的核心:實例與上下文的對抗

對比學習的核心:實例與上下文的對抗 對比學習概述實例與上下文的對抗:核心機制實戰代碼示例:使用PyTorch實現SimCLR結語 在深度學習的浩瀚星海中,對比學習作為自我監督學習的一個分支,正以破竹之勢引領著無標注數據利用…

dledger原理源碼分析系列(三)-選主

簡介 dledger是openmessaging的一個組件, raft算法實現,用于分布式日志,本系列分析dledger如何實現raft概念,以及dledger在rocketmq的應用 本系列使用dledger v0.40 本文分析dledger的選主 關鍵詞 Raft Openmessaging 心跳/選…

SpringMVC中的異常處理器

文章目錄 12異常處理器12.1基于配置的異常處理HandlerExceptionResolver接口直接在springmvc中聲明使用 12.2基于注解的異常處理需要書寫異常的配置類 12異常處理器 12.1基于配置的異常處理 HandlerExceptionResolver接口 接口實現類: DefaultHandlerExceptionR…

Linux安裝redis教程(超級詳細,新手必看)

環境: Centos 7.9 一、安裝準備工作 1.配置gcc 安裝redis前需要配置gcc: yum install gcc如果配置gcc出現依賴包問題,可以到主頁查看帖子解決:https://blog.csdn.net/m0_59117906/article/details/134451622?spm1001.2014.300…

這四款軟件很好用,可以提升工作、學習效率

TableConvert TableConvert是一個基于Web的在線表格轉換工具,能夠將多種格式的表格數據進行快速轉換。它支持將Excel、URL、HTML、JSON、CSV等格式轉換為Markdown表、CSV/TSV、XML、YAML、插入SQL、HTML、Excel和LaTeX等格式。用戶只需將表格數據粘貼到編輯器&#…

設置HTML元素的背景顏色

設置HTML元素的背景顏色 大家好,我是免費搭建查券返利機器人省錢賺傭金就用微賺淘客系統3.0的小編,也是冬天不穿秋褲,天冷也要風度的程序猿!在本文中,我們將探討如何使用HTML和CSS來設置HTML元素的背景顏色。背景顏色…

本教程將指導如何通過 Vue 組件和后端 API 交互

本人詳解 作者:王文峰,參加過 CSDN 2020年度博客之星,《Java王大師王天師》 公眾號:JAVA開發王大師,專注于天道酬勤的 Java 開發問題中國國學、傳統文化和代碼愛好者的程序人生,期待你的關注和支持!本人外號:神秘小峯 山峯 轉載說明:務必注明來源(注明:作者:王文峰…

常用TELNET命令及其應用

常用TELNET命令及其應用 大家好,我是免費搭建查券返利機器人省錢賺傭金就用微賺淘客系統3.0的小編,也是冬天不穿秋褲,天冷也要風度的程序猿! TELNET是一種基于文本協議的網絡協議,主要用于遠程登錄到網絡設備和服務器…

計算機視覺全系列實戰教程 (十五):使用opencv對視頻進行基本處理

視頻處理基本介紹 1、基本概述(1)opencv中視頻處理的兩個基礎類(2)視頻的屬性:獲取屬性和設置屬性 2、VideoCapture的介紹(1)Why( VideoCapture類的作用)(2)How( 如何使用VideoCapture)A.播放視頻文件函數B.播放視頻文件并實現暫停和繼續 3、VideoWriter類的介紹(1)…