設計模式(八): 從“小弟”中來類比"外觀模式"(Facade Pattern)

来源:http://www.cnblogs.com/ludashi/archive/2016/04/29/5417645.html
-Advertisement-
Play Games

在此先容我拿“小弟”這個詞來扯一下淡。什麼是小弟呢,所謂小弟就是可以幫你做一些瑣碎的事情,在此我們就拿“小弟”來類比“外觀模式”。在上面一篇博文我們完整的介紹了“適配器模式”,接下來我們將要在這篇博客中介紹“外觀模式”(Facade Pattern)。其實外觀模式與之前我們介紹過的“命令模式”有些相 ...


在此先容我拿“小弟”這個詞來扯一下淡。什麼是小弟呢,所謂小弟就是可以幫你做一些瑣碎的事情,在此我們就拿“小弟”來類比“外觀模式”。在上面一篇博文我們完整的介紹了“適配器模式”,接下來我們將要在這篇博客中介紹“外觀模式”(Facade Pattern)。其實外觀模式與之前我們介紹過的“命令模式”有些相似之處,都是對方法的封裝。但兩者有著明顯的不同,命令模式是對同一個對象中的不同方法進行封裝,而外觀模式是對多個對象中的多個方法進行封裝。當然在實現時我們要循序“依賴介面而不依賴具體實現”的原則。更確切的說“外觀模式”是對多個介面進行整合,以簡化用戶調用的方式。下方是外觀模式的定義:

外觀模式:提供了一個統一的介面,用來訪問子系統中的一群介面。外觀定義了一個高層介面,讓子系統更容易使用。

定義一般都是不太好理解的,那麼接下來讓我們通俗易懂的來解釋一下外觀模式。比如你做一件事情需要三步,你必須挨個的去執行。如果你使用外觀模式進行簡化後,你只需要執行外觀模式中的一步即可,因為這一步會包括你之前執行的三步。當然“外觀模式”並不是對你之前要執行的三步的東西進行封裝,使用“外觀模式”後你仍然可以親自的去執行之前的那三步。

接下來我們將通過一個示例來認識一下“外觀模式”,就以上面的工作三部曲為例。就以我為例吧,每天早晨上班,我都會做三件事情:第一,打開插排;第二,打開MacBook;第三步,打開外接顯示器(當然如果你沒有小弟就要自己去做這些事情了)。接下來我們將通過模擬這三件事情來學習一下我們的外觀模式。下方先給出沒有外觀模式的類圖與代碼實現,然後在此基礎上給出使用“外觀模式”的類圖與代碼實現。

 

一、沒有小弟(無“外觀模式”)的情況下的類圖與代碼實現

如果你沒有小弟,那麼你就得事必躬親了。該部分我們將會把上面的“工作三部曲”用代碼去實現,當然在實現是依然是我們之前的風格。下方我們會先給出類圖,然後在給出代碼實現,最後給出測試用例。測試用例就是用戶對插排、MacBook Pro、顯示器進行相應的操作。當然下班時也要做一些相應的操作,下班所做的操作與上班所做的操作正好相反,在下方的測試用例中我們也給出了相應的實現。廢話少說,開始我們的實現。

1、無“小弟”的類圖(無外觀模式)

下方的截圖是沒有使用外觀模式的類圖。在下方類圖中有三個協議(介面),分別是SocketType(插排協議)、ComputerType(電腦協議)和DisplayDeviceType(顯示器設備協議)。OXSocket(公牛插座)、MacBookPro和SamsungDisplay(三星的顯示器)又分別實現了這些協議。Client客戶端(也就是我了)依賴於這三種物品的介面而不依賴於具體實現。也就是說我打開的只要是插排就行,至於什麼品牌我不關心,只要符合要求即可。

   

 

2、代碼實現

有了上面的類圖我們給出代碼實現就不成問題了,因為測試用例就是我們的Client,在此我們就不詳細的給出Client類了。關於Client類中的內容請參見下方的測試用例。下方黃框中的是我們插排介面與公牛插座的具體代碼,其中on()是打開,off()是關閉下方的綠框中是我們筆記本介面與MacBook Pro的代碼實現,startUp()是啟動,shutdown()是關閉最後一個紅框中的代碼是顯示器介面與三星顯示器的代碼實現,其中on()是打開,off()是關閉。具體代碼如下所示:

   

 

3.測試用例

在沒用外觀模式的情況下,我們的Client仍然可以逐一的使用上述代碼。測試用例就是我們Client中的代碼,因為我們是在Playground中進行測試的,再次就不在創建Client類了,下方的代碼就是Client中的代碼。在下方的代碼段中,我們先創建了我們需要的對象(公牛插座、MacBook Por以及三星的顯示屏)。緊接著是上班要做的三件事情(開插座、啟動電腦、打開外接顯示器),然後給出了下班要做的事情(關外接顯示器、關閉電腦、關插座)。具體代碼如下所示:

  

下方截圖就是上述測試用例輸出的結果,至此我們沒有使用“外觀模式”的代碼就實現完畢。

     

 

二、你收了個小弟(添加“外觀模式”)

現在你收了個小弟,接下來該你“小弟”出場了。在上面的測試用例中,也就是我們Client調用上述對象做一些事情時我們會發現過程有些繁瑣,能不能簡化一下上述操作呢。也就是說用戶只需要只需一步就可以將插座、筆記本、外接顯示器給打開呢?當然可以,舉個例子,假如你是公司比較NX的人物,又假如你下邊有好多小弟,上面這些東西就可以完全交個你的小弟去做。比如你說我要工作了,然後你的小弟就會幫你打開插座,啟動MacBookPro,打開顯示器。如果你說我要下班了,然後你這個小弟呀,又屁顛屁顛的把顯示器關掉,將筆記本和插排關掉。

我們來對比一下,沒有“小弟”之前你上下班得做六件事情。但是如果你有了“小弟”的話,你上下班就需要兩件事情,就是告訴你的“小弟”你何時下班何時上班。這個“小弟”在此扮演的角色就是“外觀模式”。言歸正傳,“外觀模式”就如同小弟一樣可以簡化你的操作,接下來我們就在上一部分的基礎上添加一個“外觀”類(也就是我們的小弟了),將上面我們那些瑣碎的工作交給我們的“小弟”去做。

1、帶有“小弟”的類圖

我們將上述沒有“小弟”的類圖添加上“小弟”,也就是添加刪“外觀模式”所需要的外觀類。下方這個截圖中就是帶有“小弟”的類圖,上面的那個紅框中的EveryDayWorking就是我們的“小弟”類,也就是外觀模式所需要的“外觀”類。其中定義了上述我們沒有“小弟”時要做的事情。EveryDayWorking依賴於插排介面、電腦介面和顯示器介面。我們的Client就可以使用這個外觀類EveryDayWorking做我們之前做的事情。簡化了Client的一些操作。如下所示:

   

 

2、“小弟”的具體代碼實現

有上面的類圖可知,我們沒有修改之前的任何代碼,只是在原來的基礎上添加了一個EveryDayWorking類。所以在代碼實現時我們只需要添加上這個類即可,下方代碼片段就是EveryDayWorking類的具體實現。在下方代碼片段中的startWorking()方法就是我們之前上班時要親自做的三件事情,而endWorking()就是我們下班時要做的事情。現在我們都交給了我們的小弟去做,具體如下所示:

   

 

3、給“小弟”派工作

給“小弟”派工作,其實就是我們的測試用例。我們添加完EveryDayWorking類後,我們就可以委托EveryDayWorking來做之前那些瑣碎的事情了。下方就是Client調用“小弟”的代碼。下方的測試用例和上一部分的測試用例相比簡單了許多,這就是“外觀模式”的優點,可以簡化操作,並且可以將你與你的瑣事之間進行解耦。下方就是我們引入“外觀模式”後的測試用例與該測試用例的輸出結果。當然,此時此刻擁有小弟的你仍然可以事必躬親,仍然可以自己去做之前的事情呢,小弟只是幫你簡化你的操作,至於你使用還是不使用他就在那。

   

 

至此我們的“外觀模式”就介紹完了,用大白話說,“外觀模式”就是你的“小弟”,扯淡點將,你可以將外觀模式看做是你的“小弟模式”,它可以簡化介面的調用。本篇博客中的代碼實例仍然會在Github上進行分享。

github分享地址:https://github.com/lizelu/DesignPatterns-Swift

 


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

-Advertisement-
Play Games
更多相關文章
  • 談起自動摘要演算法,常見的並且最易實現的當屬TF-IDF,但是感覺TF-IDF效果一般,不如TextRank好。 TextRank是在 Google的PageRank演算法啟發下,針對文本里的句子設計的權重演算法,目標是自動摘要。它利用投票的原理,讓每一個單詞給它的鄰居(術語稱視窗) 投贊成票,票的權重取 ...
  • Java Servlet 技術,簡稱Servlet,是Java中用於開發web應用程式的基本技術。 Servlet實際上也就是一個Java程式。一個Servlet應用程式通常包含很多Servlet。而我們熟知的JSP頁面最終也是要被編譯為Servlet。 Servlet應用程式是不能像一個普通類直接 ...
  • Python批量替換文件內容,支持嵌套文件夾 ...
  • https://www.v2ex.com/t/142644 http://stackoverflow.com/questions/10558465/memcached-vs-redis 待整理 r.get() cache.get() ...
  • 獲取【下載地址】 【免費支持更新】三大資料庫 mysql oracle sqlsever 更專業、更強悍、適合不同用戶群體【新錄針對本系統的視頻教程,手把手教開發一個模塊,快速掌握本系統】 A集成代碼生成器 [正反雙向(單表、主表、明細表、樹形表,開發利器)+快速構建表單;freemaker模版技術 ...
  • Redis真是好,其中的鍵值用起來真心強大啊有木有, 之前的文章講過搭建了redis集群 那麼咋們該如何調用單機版的redis以及集群版的redis來使用緩存服務呢? 先講講單機版的,單機版redis安裝非常簡單,不多說了,直接使用命令: 1 [root@nginx bin]# ./redis-se ...
  • 裝飾設計模式就是對已有的對象的功能進行增強 簡單小例子: 我們考慮一下使用繼承也可以對父類中的功能進行增強只需要調用super就可以調用父類的方法,那使用裝飾和繼承有什麼區別?使用繼承體系就會有點臃腫,因為當平房想要改成歐式時,還要建立子類。 Writer |--FileWriter |--Buff ...
  • 在介紹Dubbo的內部邏輯的時候提到很多次註冊中心的概念.實現註冊中心的有很多,主要是以下四個註冊中心分別是: Multicast註冊中心 Zookeeper註冊中心 Redis註冊中心 Simple註冊中心 這裡將對註冊中心的一個實現Zookeeper跟大家分享,因為Zookeeper是應用比較多 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...