外觀模式 門面模式 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
更多相關文章
  • js獲取選中日期的當周的周一和周日 ...
  • 如果這是第二次看到我的文章,歡迎右側掃碼訂閱我喲~ 👉 本文長度為5269字,預計讀完需1.2MB流量,建議閱讀14分鐘。 可能你在網上看過不少「限流」相關的文章,但是z哥的這篇可能是最全面,最深入淺出的一篇了(容我飄幾秒~)。 開個玩笑,希望你能收穫一些增量價值就好~。 之前有瞭解到z哥的一部分 ...
  • 系統架構設計師-軟體水平考試高級-理論-電腦網路。其中涉及TCP/IP協議族,網路規劃與設計,網路接入,網路存儲,綜合佈線,物聯網,雲計算等。 ...
  • 模板方法模式(Template Method Pattern)是一種簡單的、常見的且應用非常廣泛的模式。 定義: 定義一個操作中演算法的框架,而將一些步驟延遲到子類中。使得子類可以不改變一個演算法的結構即可重定義該演算法的某些特定步驟。 模板方法模式的類圖如下所示。 模板方法模式涉及兩個角色: 抽象模板( ...
  • 海康&大華&DSS獲取RTSP 實時流 海康:rtsp://[username]:[password]@[ip]:[port]/[codec]/[channel]/[subtype]/av_stream說明:username: 用戶名。例如admin。password: 密碼。例如12345。ip: ...
  • 命令模式(Command Pattern)又稱為行動(Action)模式或交易(Transaction)模式。 定義: 將一個請求封裝成一個對象,從而讓你使用不同的請求把客戶端參數化,對請求排隊或記錄請求日誌,可以提供命令的撤銷和恢復功能。 命令模式類圖如下所示。 命令模式中有如下4個角色。 命令( ...
  • 搬到小機房後終於能用VSCode啦(~~沒錯以前的系統是xp~~) 但是這東西比Dev難搞多了qwq,簡單記一下自己的DIY歷程吧(~~不然全搞炸就涼了~~) 設置語言為中文 可以直接下載插件 讓VSCode支持編譯C++程式 首先要有MingW,一個很simple的方法是直接把DevC++的Min ...
  • 代理模式是一種很常用的模式,JDK也內置了對於代理的支持,動態代理,本文對代理模式進行了介紹,意圖,結構,java實現,對靜態代理和動態代理進行了分析,並且給出了代碼示例,並且介紹了CGLIB的使用。 ...
一周排行
    -Advertisement-
    Play Games
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...