1. 程式人生 > 其它 >05-05-設計模式 外觀模式

05-05-設計模式 外觀模式

影院管理專案

組建一個家庭影院:

DVD播放器、投影儀、自動螢幕、環繞立體聲、爆米花機,要求完成使用家庭影院的功能,其過程為:

直接用遙控器:統籌各裝置開關

開爆米花機

放下螢幕

開投影儀

開音響

開DVD,

選dvd

去拿爆米花

調暗燈光

播放

觀影結束後,關閉各種裝置

傳統方式解決影院管理

傳統方式解決影院管理問題分析

  1. 在ClientTest的main方法中, 建立各個子系統的物件, 並直接去呼叫子系統(物件)的相關方法,最會造成呼叫過程混亂,沒有清晰的過程
  2. 不利於在ClientTest中, 去維護對子系統的操作
  3. 解決思路: 定義一個高層介面, 給子系統的一組介面提供一個一致的頁面(比如在高層介面提供四個方法 ready, play, pause, end)
    用來訪問子系統中的一群介面
  4. 也就是說 就是通過定義一個一致的介面(介面類) 用以遮蔽內部子系統的細節, 使得呼叫端只需要和這個介面發生呼叫,而無需關心這個子系統的內部細節 => 外觀模式

外觀模式

基本介紹

  1. 外觀模式(Facade), 也叫"過程模式: 外觀模式為子系統中的一組介面提供一個一致的介面, 此模式定義了一個高層介面, 這個介面使得使得這一子系統更加容易呼叫
  2. 外觀模式通過定義一個一致的介面,用以遮蔽內部子系統的細節,使得呼叫端只需跟這個介面發生呼叫,而無需關心這個子系統的內部細節

原理類圖

類圖說明

  1. 外觀類(Facade): 為呼叫端提供統一的介面,外觀類知道那些子系統負責處理請求, 從而將呼叫端的請求代理給適當子系統物件
  2. 呼叫者: 外觀介面的呼叫者
  3. 子系統的集合: 指模組或子系統, 處理Facade物件指派的任務,他是功能的實際提供者

外觀模式解決影院管理

說明

  1. 外觀模式可以理解為轉換一群介面, 客戶只要呼叫一個介面,而不需呼叫多個接口才能達到目的, 比如: 在PC上安裝軟體的時候經常有一鍵安裝選項(省去選擇安裝目錄,安裝的元件等等), 還有就是手機的重啟功能(把關機和啟動合成一個操作,而不是先選擇關機,然後自己再開機)
  2. 外觀模式就是解決多個複雜介面帶來的困難, 起到簡化使用者的作用
  3. 示意圖說明

外觀模式應用例項

使用外觀模式解決家庭影院專案

程式碼實現

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原始碼

  1. Mybatis中的Configuration去建立MetaObject物件使用了外觀模式

對外觀模式的角色類圖

外觀模式的注意事項和細節

  1. 外觀模式對外遮蔽了子系統的細節, 因此外觀模式降低了客戶端對子系統使用的複雜性
  2. 外觀模式對客戶端與子系統的耦合關係 - 解耦, 讓子系統內部的模組更容易維護和擴充套件
  3. 通過合理的使用外觀模式, 可以幫助 我們更好的劃分訪問的層次
  4. 當系統需要進行分層設計時, 可以考慮使用外觀模式
  5. 在維護一個遺留的大型系統時,可能這個系統已經非常難以維護和擴充套件, 此時可以考慮為新系統開發一個外觀類, 來提供遺留系統的比較清晰簡單的介面, 讓新系統與外觀類互動, 提高複用性
  6. 不能過多或者不合理的使用外觀模式, 使用外觀模式好,還是直接呼叫模組好, 要以讓系統有層次, 利於維護為目的