設計模式 - 模板方法模式

来源:https://www.cnblogs.com/guohaien/archive/2019/03/04/10450491.html
-Advertisement-
Play Games

定義:在基類中定義一個操作中的演算法的骨架,而將一些步驟延遲到子類中。模板方法使得子類可以不改變一個演算法的結構即可重定義該演算法的某些特定步驟。 可以理解為將不變的行為放在父類中,會發生變化的行為在子類中實現,這樣可以避免子類中出現大量重覆的代碼。也就是說當子類中的方法混合了不變和可變的行為,我們通過模 ...


定義:在基類中定義一個操作中的演算法的骨架,而將一些步驟延遲到子類中。模板方法使得子類可以不改變一個演算法的結構即可重定義該演算法的某些特定步驟。

可以理解為將不變的行為放在父類中,會發生變化的行為在子類中實現,這樣可以避免子類中出現大量重覆的代碼。也就是說當子類中的方法混合了不變和可變的行為,我們通過模板方法就能將這些不變的行為放到一個單獨的地方。模板方法的類結構比較簡單,下麵直接貼出代碼

父類

public abstract class AbstractClass {
    /**
     * 可變方法1
     */
    public abstract void changeMethod1();

    /**
     * 可變方法2
     */
    public abstract void changeMethod2();

    public void templateMethod() {
        System.out.println("執行可變方法1前");
        changeMethod1();
        System.out.println("執行可變方法1後");
        System.out.println("執行可變方法2前");
        changeMethod2();
        System.out.println("執行可變方法2後");
    }
}

兩個子類

public class ConcreteClassA extends AbstractClass {
    @Override
    public void changeMethod1() {
        System.out.println("子類A的可變方法1");
    }

    @Override
    public void changeMethod2() {
        System.out.println("子類A的可變方法2");
    }
}
public class ConcreteClassB extends AbstractClass {
    @Override
    public void changeMethod1() {
        System.out.println("子類B的可變方法1");
    }

    @Override
    public void changeMethod2() {
        System.out.println("子類B的可變方法2");
    }
}

測試代碼和輸出結果

AbstractClass a = new ConcreteClassA();
a.templateMethod();
System.out.println("------------------");
AbstractClass b = new ConcreteClassB();
b.templateMethod();

 從上面代碼可以看出templateMethod方法中只有一部分是會隨子類的實現不同發生改變,通過模板方法讓我們不需要在子類中重覆編寫那些不變的代碼。接下來我們通過一個簡單的抄考卷的例子,來加深對模板方法的理解,代碼如下

考卷抽象類

public abstract class AbstractPaper {

    public void createPaper() {
        question1();
        answerText();
        answer1();
        question2();
        answerText();
        answer2();
        question3();
        answerText();
        answer3();
    }

    public void question1() {
        System.out.println("問題1:");
    }

    public void question2() {
        System.out.println("問題2:");
    }

    public void question3() {
        System.out.println("問題3:");
    }

    public void answerText() {
        System.out.print("答案:");
    }

    /**
     * 問題1的答案
     */
    public abstract void answer1();
    /**
     * 問題2的答案
     */
    public abstract void answer2();
    /**
     * 問題3的答案
     */
    public abstract void answer3();
}

兩張答案不同的考卷(省略一個,代碼類似)

public class PaperA extends AbstractPaper {
    @Override
    public void answer1() {
        System.out.println("A");
    }

    @Override
    public void answer2() {
        System.out.println("B");
    }

    @Override
    public void answer3() {
        System.out.println("C");
    }
}

測試代碼和輸出結果

AbstractPaper paperA = new PaperA();
paperA.createPaper();
System.out.println("------------");
AbstractPaper paperB = new PaperB();
paperB.createPaper();

以上就是整個功能的實現代碼,可以通過點擊以下鏈接獲取完整代碼

完整代碼


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 大致步驟: 1、寫一個p標簽,指定一個id選擇器,輸入數字! 2、寫一個input標簽,指定type屬性的屬性值為button,創建一個按鈕,加入onclick事件! 3、為p標簽和input標簽指定相關的CSS樣式(可以省略) 4、用js創建一個自加的函數,在函數中用document對象的getE ...
  • 回調函數作為參數傳給另一個函數,所以我們在調用回調函數時,預先並不知道所調用的函數具體是哪個函數,因為我們調用的是一個參數,形如: 普通函數是通過具體的函數名來調用,所有我們在調用普通函數時,預先知道要調用的是哪個函數,形如: ...
  • 彈性容器單行:主軸居中,交叉軸居中。 彈性容器單行;主軸兩端對齊;交叉軸一個為起點邊緣;一個為終點邊緣; 單選;主軸兩端對齊;交叉軸一個為起點邊緣;一個為居中對齊;一個為終點邊緣; 1:彈性視窗設置為多行,交叉軸為兩端對齊 2:每行基礎大小設置為100%,然後每個子行主軸為兩端對齊 在4的基礎上增加 ...
  • align-content 和 align-items : 1:共同點:它們對齊方向為交叉軸 2:不同點:align-content 應用於為 多行 而 align-items:應用於單行。 單行對齊例子: 多行對齊例子 ...
  • js中有三個改變this指針的方法,分別是 apply,call,bind。很多人只知道能改變的this,但是具體的適用場景不是太清楚。我也是遇到坑後不斷的實踐發現了區別。 call ,apply方法: 在Food類中,因為使用了call改變類Product的類的this執向。所以這個時候在Prod ...
  • 高可用 負載均衡(負載均衡演算法) 反向代理 服務隔離 服務限流 服務降級(自動優雅降級) 失效轉移 超時重試(代理超時、容器超時、前端超時、中間件超時、資料庫超時、NoSql超時) 回滾機制(上線回滾、資料庫版本回滾、事務回滾) 高併發 應用緩存 HTTP緩存 多級緩存 分散式緩存 連接池 非同步併發 ...
  • 在上一篇的-負載均衡Robbin中,我們簡單講解到負債均衡的演算法和策略。負載均衡就是分發請求流量到不同的伺服器,以減小伺服器的壓力和訪問效率,但是當負載均衡的某個伺服器或是服務掛掉之後,那麼程式會出現問題麽?接下來Hystrix將會講解 1.1.簡介 Hystix,即熔斷器。 主頁:https:// ...
  • 前幾天刷朋友圈的時候,看到一段話: 如果現在我是傻逼,那麼我現在不管怎麼努力,也還是傻逼,因為我現在的傻逼是由以前決定的,現在努力,是為了讓以後的自己不再傻逼 。話糙理不糙,如果妄想現在努力一下,馬上就不再傻逼,那是不可能的,需要積累,需要沉澱,才能慢慢的不再傻逼。 好了,雞湯喝完。 今天我們的內容 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...