05-05-設計模式 外觀模式
阿新 • • 發佈:2022-05-27
影院管理專案
組建一個家庭影院:
DVD播放器、投影儀、自動螢幕、環繞立體聲、爆米花機,要求完成使用家庭影院的功能,其過程為:
直接用遙控器:統籌各裝置開關
開爆米花機
放下螢幕
開投影儀
開音響
開DVD,
選dvd
去拿爆米花
調暗燈光
播放
觀影結束後,關閉各種裝置
傳統方式解決影院管理
傳統方式解決影院管理問題分析
- 在ClientTest的main方法中, 建立各個子系統的物件, 並直接去呼叫子系統(物件)的相關方法,最會造成呼叫過程混亂,沒有清晰的過程
- 不利於在ClientTest中, 去維護對子系統的操作
- 解決思路: 定義一個高層介面, 給子系統的一組介面提供一個一致的頁面(比如在高層介面提供四個方法 ready, play, pause, end)
- 也就是說 就是通過定義一個一致的介面(介面類) 用以遮蔽內部子系統的細節, 使得呼叫端只需要和這個介面發生呼叫,而無需關心這個子系統的內部細節 => 外觀模式
外觀模式
基本介紹
- 外觀模式(Facade), 也叫"過程模式: 外觀模式為子系統中的一組介面提供一個一致的介面, 此模式定義了一個高層介面, 這個介面使得使得這一子系統更加容易呼叫
- 外觀模式通過定義一個一致的介面,用以遮蔽內部子系統的細節,使得呼叫端只需跟這個介面發生呼叫,而無需關心這個子系統的內部細節
原理類圖
類圖說明
- 外觀類(Facade): 為呼叫端提供統一的介面,外觀類知道那些子系統負責處理請求, 從而將呼叫端的請求代理給適當子系統物件
- 呼叫者: 外觀介面的呼叫者
- 子系統的集合: 指模組或子系統, 處理Facade物件指派的任務,他是功能的實際提供者
外觀模式解決影院管理
說明
- 外觀模式可以理解為轉換一群介面, 客戶只要呼叫一個介面,而不需呼叫多個接口才能達到目的, 比如: 在PC上安裝軟體的時候經常有一鍵安裝選項(省去選擇安裝目錄,安裝的元件等等), 還有就是手機的重啟功能(把關機和啟動合成一個操作,而不是先選擇關機,然後自己再開機)
- 外觀模式就是解決多個複雜介面帶來的困難, 起到簡化使用者的作用
- 示意圖說明
外觀模式應用例項
使用外觀模式解決家庭影院專案
程式碼實現
package com.flower.waiguan; public class TestMain { public static void main(String[] args) { HomeYouFacade homeYouFacade = HomeYouFacade.homeYouFacade; homeYouFacade.start(); homeYouFacade.stop(); } } abstract class OnAndOff{ protected String deviceName; public OnAndOff(String deviceName) { this.deviceName = deviceName; } public void on(){ System.out.println(deviceName + " on"); } public void off(){ System.out.println(deviceName + " off"); } } class DVDPlayer extends OnAndOff{ public static final DVDPlayer dvdPlayer = new DVDPlayer(); public DVDPlayer() { super("dvd"); } } class Popcorn extends OnAndOff{ public static final Popcorn popcorn = new Popcorn(); public Popcorn() { super("popcorn"); } } class Projector extends OnAndOff{ public static final Projector projector = new Projector(); public Projector() { super("projector"); } } class Screen extends OnAndOff{ public static final Screen screen = new Screen(); public Screen() { super("screen"); } } class HomeYouFacade{ public static final HomeYouFacade homeYouFacade = new HomeYouFacade(); // 組合裝置 private static final DVDPlayer dvdPlayer = DVDPlayer.dvdPlayer; private static final Popcorn popcorn = Popcorn.popcorn; private static final Projector projector = Projector.projector; private static final Screen screen = Screen.screen; public void start(){ dvdPlayer.on(); popcorn.on(); projector.on(); screen.on(); } public void stop(){ dvdPlayer.off(); popcorn.off(); projector.off(); screen.off(); } }
我這裡沒有寫的太複雜,只是寫了簡單的off 和 on方法, 能理解思想就可以
原始碼剖析
Mybatis原始碼
- Mybatis中的Configuration去建立MetaObject物件使用了外觀模式
對外觀模式的角色類圖
外觀模式的注意事項和細節
- 外觀模式對外遮蔽了子系統的細節, 因此外觀模式降低了客戶端對子系統使用的複雜性
- 外觀模式對客戶端與子系統的耦合關係 - 解耦, 讓子系統內部的模組更容易維護和擴充套件
- 通過合理的使用外觀模式, 可以幫助 我們更好的劃分訪問的層次
- 當系統需要進行分層設計時, 可以考慮使用外觀模式
- 在維護一個遺留的大型系統時,可能這個系統已經非常難以維護和擴充套件, 此時可以考慮為新系統開發一個外觀類, 來提供遺留系統的比較清晰簡單的介面, 讓新系統與外觀類互動, 提高複用性
- 不能過多或者不合理的使用外觀模式, 使用外觀模式好,還是直接呼叫模組好, 要以讓系統有層次, 利於維護為目的