外觀模式 門面模式 Facade 創建型 設計模式(十三)

来源:https://www.cnblogs.com/noteless/archive/2018/12/03/10058164.html
-Advertisement-
Play Games

外觀模式又稱為門面模式Facade是一種簡單的設計模式,但是他背後的思想為迪米特原則,理解門面模式更有助於理解迪米特原則--不要和陌生人說話的原則,可以降低系統的耦合程度,本文介紹了外觀模式的意圖,結構,並且給出了java代碼示例。 ...


外觀模式(FACADE) 又稱為門面模式 image_5c04c84e_d32  

意圖

為子系統中的一組介面提供一個一致的界面 Facade模式定義了一個高層介面,這一介面使得這一子系統更加易於使用。

意圖解析

隨著項目的持續發展,系統基本上都是會往功能更全面的方向發展,那麼也就意味著我們的系統將會變得更加複雜。 系統會被劃分為多個單獨的子系統,每個子系統完成一部分功能,通過分工協作完成全部功能。 一個子系統也可能進一步拆分為更小的幾個子系統。   程式中的文件將會越來越多,相互關聯也會變得更加複雜 當使用一個功能的時候,作為客戶端 你需要弄清楚相關類之間的關係,以及正確的調用順序。   比如下圖中 你需要自己識別有哪些子系統,涉及哪些相關的類和方法,你需要自己保證順序(如果功能調用依賴順序的話) image_5c04c84e_5ec   如同在醫院裡面,病人需要自己去排隊掛號化驗,跟每個流程的工作人員進行協作 如同在工廠裡面,需要生產一個桌子,你親自用機器生產桌子腿,自己使用機器生產桌面... 如同你去其他公司洽談業務,你單獨跟每個相關業務的人員進行聯繫溝通   你肯定想得到,如果有一個中間人為你代勞 不需要面對林林總總的子系統、部門、人員... 當你需要某種服務時,只需要告訴這個中間人就好了 這個想法就是外觀模式 image_5c04c84e_38cc   有了facade,你就不需要跟每個子系統進行單獨的交流了 如同在醫院裡面,對於VIP,有專人代替你掛號..... 如同在工廠裡面,有一個控制台機器,你選擇產品,控制臺下發命令安排其他的機器生產具體產品 如同你去其他公司洽談業務,有一個介面人負責與你對接,他們那邊的事情都通過這個人進行安排   image_5c04c84e_22f4   外觀模式的意圖含義,如同他的名字一樣,“建築物的正面” 面對一個複雜的大樓,當你在正面遠遠望去,也就只能看到正面 在外觀模式中,形容一個龐大的複雜的系統的一個直觀的界面 藉助於Facade模式 從原來的“客戶端需要跟多個子系統進行交互”,轉變為“只與Facade進行交互” 將客戶端與子系統進行解耦,降低了耦合性,也降低了使用的複雜度

代碼示例

“關好門窗,防火防盜”這句話有沒有聽過? 回想一下,當你早上準備出門離開家時,你會做什麼? 假設你會關水、關燈、關門窗。 我們創建三個類,水 燈 窗,模擬離開家的場景  
package facade;
public class Water {
public void turnOn() {
        System.out.println("打開水龍頭...");
    }   
    public void turnOff() {
        System.out.println("關閉水龍頭...");
    }
}
package facade;
public class Light {
    public void turnOn() {
        System.out.println("開燈...");
    } 
    public void turnOff() {
        System.out.println("關燈...");
    }
}
package facade;
 
public class Window {
    public void open() {
        System.out.println("開窗...");
    } 
    public void close() {
        System.out.println("關窗...");
    }
}
測試代碼 image_5c04c84f_e57   上面的測試代碼Test作為客戶端程式,可以看得出來,他直接跟Water Light Window三個類的對象進行交互 他需要調用相關的方法 也就是說Test 作為客戶端對於“離家”這一系統的內部邏輯是瞭如指掌的--->需要斷水、關燈、關窗 他也清楚每個類的方法 一方面增加了耦合性,另一方面將子系統的內部細節暴露出來

優化重構

試想下,如果你家是智能家居,有一個控制台Facade,或者說有一個手機App 他可以控制整個家庭的設備
package facade;
 
public class Facade {
    private Water water = new Water();
    private Light light = new Light();
    private Window window = new Window();
    
    public void leaveHome(){
        water.turnOff();
        light.turnOff();
        window.close();
    }
     
    public void backHome(){
        light.turnOn();
        window.open();
    }
 
}

 

image_5c04c84f_780b   通過這個控制台,客戶端程式不再需要瞭解子系統的內部細節,他也不清楚每個類到底有哪些方法 所有的交互都是通過Facade來完成的

結構

image_5c04c84f_7b08 Facade 外觀角色 客戶端調用角色,知曉子系統的所有功能與職責 通常,Facade會將所有的請求轉發委派到子系統中去,也就是說該角色沒有實際的業務、   SubSystem子系統角色 可以同時有一個或者多個子系統 註意   :子系統並不是說一個單獨的類,而是一個類的集合,這些類根據邏輯功能點被組織在一起   子系統並不知道Facade的存在,對於子系統來說,Facade也就只是一個客戶端程式   外觀模式的結構比較簡單,類似一個“封裝”提取的過程 他的根本原則為迪米特法則,也就是“不要和陌生人說話”,儘可能少的與其他的對象進行交互 通過外觀模式,做到了子系統只與外觀對象交互   門面類個數 在門面模式中,通常只需要一個門面類,並且這個門面類只有一個實例 換句話說他很可能是一個單例 但是並不是說整個系統中只能有一個門面類 門面類的個數要根據系統中子系統的個數以及業務邏輯的情況

總結

當你需要為一個複雜的子系統提供一個簡單的介面時或者希望子系統能夠更加獨立時,可以考慮使用外觀模式 藉助於外觀模式,可以實現客戶端與子系統的解耦,減少客戶端對子系統的依賴性 一旦完成解耦,就意味著子系統有良好的獨立性,也能擁有更好的擴展性 因為獨立了,就意味著單獨的子系統修改不會影響其他系統 而且,在多層次結構的系統中,可以使用Facade模式進行層與層之間的交互,將層與層之間的耦合性降低,使他們僅僅通過facade進行交互 總之一句話,降低了使用子系統的複雜程度,降低了耦合程度,滿足迪米特法則----不要和陌生人說話  對客戶端屏蔽了子系統的組件 僅僅通過Facade,大大減少了客戶端所需要處理的對象的數目 對於外觀模式,如果是子系統發生變化,Facade則極有可能需要面臨修改,這不符合開閉原則  外觀模式(門面模式)就如同我們開篇的圖片一樣,作為公司前臺 接待來訪賓客,一切事宜都有她來協調安排組織。 在OOP中,這個“前臺”不僅是一個子系統的“正面”看到的樣子,而且還強調了她的全權負責 她提供所有的業務需要的相關方法,儘管內部調用都是子系統中的方法,她提供簡單一致的交流溝通形式  理解了迪米特法則,那麼就比較容易理解外觀模式 外觀模式重點在於提供一個“簡化”“封裝”後的操作控制台,讓你更容易操作整個系統,他幾乎不會涉及子系統的內部邏輯 否則,門面對象將與子系統的業務邏輯耦合,增加了耦合度。 原文地址:外觀模式 門面模式 Facade 創建型 設計模式(十三)  
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 事件的觸發權很多時候都屬於用戶,有些情況下會產生問題: 向後臺發送數據,用戶頻繁觸發,對伺服器造成壓力 一些瀏覽器事件:window.onresize、window.mousemove等,觸發的頻率非常高,會造成瀏覽器性能問題 如果你碰到這些問題,那就需要用到函數節流和防抖了。 一、函數節流(thr ...
  • 項目代碼 "從零開始簡書項目" ​ 從我第一次接觸 這個框架已經過了快一年的時間,陪伴我從前端小白到前端工程師,前端時間也是使用了 +`vue vue`這一塊,也算是比較熟練了,對底層也有一些瞭解,我開始了react的產生了一些興趣 ​ 第一次看 慕課網上的一個免費課程 "React 16實現訂單列 ...
  • nodejs 使用 js 模塊 Intro 最近需要用 nodejs 做一個爬蟲,Google 有一個 Puppeteer 的項目,可以用它來做爬蟲,有關 Puppeteer 的介紹網上也有很多,在這裡就不做詳細介紹了。 node 小白,開始的時候有點懵逼,模塊導出也不會。 官方文檔上說支持 .mj ...
  • 1.Js操作css樣式 div.style.width=”100px”.在div標簽內我們添加了一個style屬性,並設定 了width值。這種寫法會給標簽帶來大量的style屬性,跟實際項目是不符。 我們沒有讓css和html分離。 所以如果是為了獲取css樣式 window.getCompute ...
  • 聲明 本系列文章內容全部梳理自以下幾個來源: 《JavaScript權威指南》 "MDN web docs" "Github:smyhvae/web" "Github:goddyZhao/Translation/JavaScript" 作為一個前端小白,入門跟著這幾個來源學習,感謝作者的分享,在其基 ...
  • 即時通訊:支持好友,群組,發圖片、文件,消息聲音提醒,離線消息,保留聊天記錄 (即時聊天功能支持手機端,詳情下麵有截圖) 工作流模塊 1.模型管理 :web線上流程設計器、預覽流程xml、導出xml、部署流程 2.流程管理 :導入導出流程資源文件、查看流程圖、根據流程實例反射出流程模型、激活掛起 3 ...
  • 訪問者模式(Visitor Pattern)的目的是封裝一些於某種數據結構元素之上的操作,一旦這些元素需要修改,接受這個操作的數據結構則可以保持不變。 定義: 封裝一些作用於某種數據結構中的各元素的操作,它可以在不改變數據結構的前提下定義於作用這些元素的新的操作。 訪問者模式的類圖如下。 訪問者模式 ...
  • 備忘錄模式(Memento Pattern)又稱為快照(Snapshot)模式或Token模式。 意思是:在不破壞封裝性的前提下,捕獲一個對象的內部狀態,併在該對象之外保存這個對象。這樣,以後就可以將該對象恢復到原先保存的狀態。 通俗地說,備忘錄模式就是將一個對象進行備份,提供一種程式數據的備份方法 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...