模板模式和適配器模式

来源:https://www.cnblogs.com/ZekiChen/archive/2020/03/28/12571428.html
-Advertisement-
Play Games

一、模板模式 1、模板模式(Template Method pattern):指定義一個演算法的骨架,並允許子類為一個或者多個步驟提供實現。模板方法使得子類可以在不改變演算法結構的情況下,重新定義演算法的某些步驟。(屬於行為型模式) 2、適用場景 一次性實現一個演算法的不變的部分,並將可變的行為留給子類來實 ...


一、模板模式

1、模板模式(Template Method pattern):指定義一個演算法的骨架,並允許子類為一個或者多個步驟提供實現。模板方法使得子類可以在不改變演算法結構的情況下,重新定義演算法的某些步驟。(屬於行為型模式)

2、適用場景

  • 一次性實現一個演算法的不變的部分,並將可變的行為留給子類來實現
  • 各子類中公共的行為被提取出來並集中到一個公共的父類中,從而避免代碼重覆

3、優點

  • 提高代碼的復用性
  • 提高代碼的擴展性
  • 符合開閉原則

4、缺點

  • 類數目的增加
  • 間接地增加了系統實現的複雜度
  • 繼承關係自身缺點,如果父類添加新的抽象方法,所有子類都要改一遍

5、應用場景舉例

比如辦理入職流程:填寫入職登記表-->列印簡歷-->複印學歷-->複印身份證-->簽訂勞動合同-->辦理工牌-->安排工位。

比如平時炒菜流程:洗鍋-->點火--> 熱鍋-->上油-->下菜-->翻炒-->放調料-->出鍋。

再如趙本山問宋丹丹:“如何把大象放進冰箱?”宋丹丹答:“第一步:打開冰箱門,第二步:把大象塞進冰箱,第三步:關閉冰箱門”。趙本山再問:“怎麼把長頸鹿放進冰箱?”宋丹丹答:“第一步:打開冰箱門,第二步:把大象拿出來,第三步:把長頸鹿塞進去,第四步:關閉冰箱門”,這些都是模板模式的體現。

例子1:以簡單的網校課程創建流程為例:發佈預習資料-->線上直播-->提交筆記-->佈置作業-->檢查作業。

首先定義一個NetworkCourse網課抽象類:

上面代碼中有個鉤子方法,主要是用來干預執行流程,使得我們控制行為流程更加靈活、更符合實際業務的需求。鉤子方法的返回值一般為適合條件分支語句的返回值(如boolean、int等),可根據真實業務場景來決定是否需要用鉤子方法。

接下來定義一個JavaCourse課程類:

定義一個BigDataCourse課程類:

客戶端測試代碼:

運行結果:

例子2:利用模板模式重構JDBC操作業務場景。

定義一個JdbcTemplate模板類,封裝所有的JDBC操作。以查詢為例,每次查詢的表不同,返回的數據結構也不一樣。我們針對不同的數據,都要封裝成不同的實體對象。而每個實體封裝的邏輯都是不一樣的,但封裝前和封裝後的處理流程是不變的,因此可以用模板模式來設計這樣的業務場景。 先定義一個約束ORM邏輯的介面RowMapper:

再定義一個封裝了所有處理流程的抽象類JdbcTemplate:

定義一個實體類User:

定義一個資料庫操作類UserDao:

客戶端測試代碼:

6、模板模式在源碼中的應用

① 先看JDK中的AbstractList:

我們看到get()是一個抽象方法,那麼它的邏輯就是交給子類來實現,ArrayList就是AbstractList的子類。同理,有AbstractList就有AbstractSet和AbstractMap,有興趣可自行研究。還有一個每天都在用的HttpServlet,有service()、doGet()和doPost()方法,都是模板方法的抽象實現。

② Mybatis框架中的BaseExecutor類,是一個基礎的SQL執行類,實現了大部分的SQL執行邏輯,然後把幾個方法交給子類定製化完成,源碼如下:

如doUpdate()、doQuery()等方法都交由子類來實現,如下類圖:

二、適配器模式

1、適配器模式(Adapter Pattern):指將一個類的介面轉換成客戶期望的另一個介面,使原本介面不相容的類可以一起工作。(屬於結構型設計模式)

2、適用場景

  • 已經存在的類,它的方法和需求不匹配(方法結果相同或相似)的情況
  •  適配器模式不是軟體設計階段考慮的設計模式,是隨著軟體維護,由於不同產品、不同廠家造成功能類似而介面不相同情況下的解決方案(有點亡羊補牢的感覺)

3、優點

  • 能提高類的透明性和復用,現有的類復用但不需要改變
  • 目標類和適配器類解耦,提高程式的擴展性
  • 在很多業務場景中符合開閉原則

4、缺點

  • 適配器編寫過程需要全面考慮,可能會增加系統的複雜性
  • 增加代碼閱讀難度,降低代碼可讀性,過多使用適配器會使系統代碼變得凌亂

5、應用場景舉例

比如電源插轉換頭、手機充電轉換頭、顯示器轉接頭。

例子1:在中國民用電都是220V交流電,但我們手機使用的鋰電池使用5V直流電。因此,我們給手機充電時就需要使用電源適配器來進行轉換。下麵代碼還原場景:

定義一個AC220類,表示220V交流電:

定義一個DC5介面,表示5V直流電的標準:

定義一個電源適配器PowerAdapter類:

客戶端測試代碼:

上面的案例中,通過增加PowerAdapter電源適配器,實現了二者的相容。

例子2:重構第三方登錄自由適配的業務場景。

以前開發的老系統應該都有登錄介面, 但隨著業務的發展和社會的進步,單純地依賴用戶名密碼登錄顯示不能滿足用戶需求了。現在,我們大部分系統都已經支持多種登錄方式,如QQ登錄、微信登錄、手機登錄等,同時保留用戶名密碼的登錄方式。雖然登錄形式豐富了,但登錄後的處理邏輯可不必改變,同樣是將登錄狀態保存到session,遵循開閉原則。

首先定義統一的返回結果Result類:

假設老系統的登錄邏輯SignInService:

為了遵循開閉原則,老系統的代碼我們不去修改。下麵開始重構,先定義User類:

定義一個第三方登錄新類SignInForThirdService繼承原來的邏輯,運行非常穩定的代碼我們不去改動:

客戶端測試代碼:

通過這麼一個簡單的適配,完成了代碼相容。當然,代碼還可以更加優雅,根據不同的登錄方式,創建不同的Adapter。

首先,定義一個LoginAdapter介面:

分別實現不同的登錄適配,QQ登錄LoginForQQAdapter類:

微信登錄LoginForWechatAdapter類:

然後定義第三方登錄相容介面IPassportForThird:

實現相容PassportForThirdAdapter類:

客戶端測試代碼:

類結構圖:

至此,我們在遵循開閉原則的前提下,完整地實現了一個相容多平臺登錄的業務場景。適配器模式主要解決的是功能相容問題,且適配器的實現邏輯並不依賴於介面,我們完全可以將LoginAdapter介面去掉,加上介面只是為了代碼規範。上面的代碼可以說是策略模式、簡單工廠模式和適配器模式的綜合運用。

6、適配器模式在源碼中的應用

簡單看看適配器模式在源碼中的應用,SpringMVC的HandlerAdapter類,它也有多個子類:


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

-Advertisement-
Play Games
更多相關文章
  • 按照國際慣例,先放效果圖 index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>index</title> <style> .ball{ background:linear-gradient( ...
  • 1.1 JavaScript簡史 在web日益流行的今天,人們對客戶端腳本語言的需求也越來越高。 1995.2 就職於網景公司的Brendan Eich發佈了其開發的LiveScript,改語言同時在瀏覽器和伺服器使用。為了趕工期,在Netscape Navigator 2發佈前夕,Netscape ...
  • HTML佈局標簽,定義文檔區塊,塊級(block-level);定義 span,用來組合文檔中的行內元素。雖然我們可以使用HTML table標簽來設計出漂亮的佈局,但是table標簽是不建議作為佈局工具使用的,設計表格的目的是呈現表格化數據 - 表格不是佈局工具! ...
  • html中的標簽元素大體被分為三種不同的類型:塊狀元素、內聯元素(又叫行內元素)和內聯塊狀元素。HTML網頁基本標簽的嵌套規則:1.塊元素可以嵌套行元素2.行元素可以嵌套行元素3.行元素不可以嵌套塊元素4.文字類塊元素不可以嵌套塊元素5.容器類塊元素可以嵌套塊元素 ...
  • <ol>定義有序列表;<ul>定義無序列表;<li>定義列表項,<dl>定義列表,<dt>自定義列表項目,<dd>定義自定義列表的描述;同時列表項內部可以使用段落、換行符、圖片、鏈接以及其他列表等等 ...
  • 路由原理 傳統開發方式 url改變後 立刻發起請求,響應整個頁面,渲染整個頁面 SPA 錨點值改變後 不會發起請求,發起ajax請求,局部改變頁面數據 頁面不跳轉 用戶體驗更好 SPA single page application(單頁應用程式) 前端路由 錨點值監視 ajax獲取動態數據 核心點 ...
  • 全局安裝/配置API更改 在Vue2.x中對全局屬性和全局API函數是這麼玩的 現在,讓我們看看它如何在Vue 3中運行: 您可能已經註意到,每個配置都限於使用定義的某個Vue應用程式createApp。 它可以使您的代碼更易於理解,並且不易出現由第三方插件引起的意外問題。當前,如果某些第三方解決方 ...
  • 關於HTML5 廣義上對HTML5前端的解釋是包含HTML、CSS和JavaScript在內的一套技術組合。隨著最近幾年來互聯網的迅猛發展和普及,HTML5前端工程師已經成為互聯網時代軟體產品研發中不可缺少的一種專業的研發角色,“錢”途不可限量! HTML5能做什麼? 第一:最近火爆的微信小程式,非 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...