首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

設計模式精講:外觀模式——為複雜子系統提供統一入口

     編輯:關於C語言

設計模式精講:外觀模式——為複雜子系統提供統一入口

外觀模式為子系統中的一群介面提供一個一致的高層介面,讓子系統更容易使用。生活譬喻:早期看電視只需開電視,現代需開電視、機頂盒、音響、切換訊號源……外觀模式就是那個「萬用遙控器」,一鍵搞定所有步驟。

模式定義與核心價值

外觀模式:提供一個統一介面,封裝子系統的一組介面,降低客戶端與子系統的耦合度。

核心價值:

  • 簡化介面:隱藏子系統複雜性
  • 解耦依賴:客戶端不直接依賴具體子系統類別
  • 分層架構:外觀作為系統層級的入口點

UML 結構

┌──────────┐     ┌──────────┐     ┌──────────┐     ┌──────────┐
│  Client  │────▶│  Facade  │────▶│SubsystemA│
└──────────┘     └──────────┘     └──────────┘
                       │            ┌──────────┐     ┌──────────┐
                       ├───────────▶│SubsystemB│
                       │            └──────────┘     └──────────┘
                       ▼
                 ┌──────────┐
                 │SubsystemC│
                 └──────────┘

程式碼實作:家庭影院系統

#include <iostream>
#include <memory>
#include <string>

// 子系統類別(無共同基類)
class Amplifier {
public:
    void On() { std::cout << "功放開機\n"; }
    void SetVolume(int v) { std::cout << "音量設為 " << v << "\n"; }
    void Off() { std::cout << "功放關機\n"; }
};

class Tuner {
public:
    void On() { std::cout << "調諧器開機\n"; }
    void SetFrequency(double f) { std::cout << "頻率 " << f << " MHz\n"; }
    void Off() { std::cout << "調諧器關機\n"; }
};

class DvdPlayer {
public:
    void On() { std::cout << "DVD 開機\n"; }
    void Play(const std::string& movie) { std::cout << "播放電影: " << movie << "\n"; }
    void Stop() { std::cout << "DVD 停止\n"; }
    void Off() { std::cout << "DVD 關機\n"; }
};

class Projector {
public:
    void On() { std::cout << "投影機開機\n"; }
    void WideScreenMode() { std::cout << "寬螢幕模式\n"; }
    void Off() { std::cout << "投影機關機\n"; }
};

class Lights {
public:
    void Dim(int level) { std::cout << "燈光調暗至 " << level << "%\n"; }
    void On() { std::cout << "燈光全開\n"; }
};

class Screen {
public:
    void Down() { std::cout << "螢幕降下\n"; }
    void Up() { std::cout << "螢幕收起\n"; }
};

class PopcornPopper {
public:
    void On() { std::cout << "爆米花機開機\n"; }
    void Pop() { std::cout << "開始爆米花!\n"; }
    void Off() { std::cout << "爆米花機關機\n"; }
};

// 外觀類別:簡化客戶端操作
class HomeTheaterFacade {
public:
    HomeTheaterFacade(Amplifier* amp, Tuner* tuner, DvdPlayer* dvd,
                      Projector* projector, Lights* lights, Screen* screen,
                      PopcornPopper* popper)
        : amp_(amp), tuner_(tuner), dvd_(dvd), projector_(projector),
          lights_(lights), screen_(screen), popper_(popper) {}

    void WatchMovie(const std::string& movie) {
        std::cout << "=== 準備看電影 ===\n";
        popper_->On(); popper_->Pop();
        lights_->Dim(10);
        screen_->Down();
        projector_->On(); projector_->WideScreenMode();
        amp_->On(); amp_->SetVolume(5);
        dvd_->On(); dvd_->Play(movie);
        std::cout << "=== 享受電影中 ===\n";
    }

    void EndMovie() {
        std::cout << "=== 結束觀影 ===\n";
        popper_->Off();
        lights_->On();
        screen_->Up();
        projector_->Off();
        amp_->Off();
        dvd_->Stop(); dvd_->Off();
        std::cout << "=== 系統關閉 ===\n";
    }

private:
    Amplifier* amp_;
    Tuner* tuner_;
    DvdPlayer* dvd_;
    Projector* projector_;
    Lights* lights_;
    Screen* screen_;
    PopcornPopper* popper_;
};

// 客戶端
int main() {
    // 建立子系統實例
    Amplifier amp; Tuner tuner; DvdPlayer dvd;
    Projector projector; Lights lights; Screen screen; PopcornPopper popper;

    // 外觀封裝複雜初始化
    HomeTheaterFacade theater(&amp, &tuner, &dvd, &projector,
                              &lights, &screen, &popper);

    // 客戶端極簡呼叫
    theater.WatchMovie("星際效應");
    theater.EndMovie();
    return 0;
}

外觀模式 vs 相關模式

模式意圖關係
外觀提供簡化介面封裝子系統,單向依賴
中介者協調物件互動雙向依賴,行為邏輯集中
抽象工廠建立相關物件族專注建構,非操作封裝

設計原則檢核

  • ✅ 最少知識原則:客戶端只認識 Facade
  • ✅ 單一職責:Facade 只負責協調流程,不含業務邏輯
  • ✅ 開放封閉:新增子系統不修改客戶端,只擴充 Facade
  • ⚠️ 避免 上帝類別:Facade 不應包含業務邏輯,僅委派

實務應用場景

  • 框架初始化:SpringApplication.run()、QApplication 建構
  • API 閘道:Kong、Zuul 封裝微服務召集
  • 建構器模式的簡化版:StringBuilder、ProcessBuilder
  • 舊系統遷移:新系統透過 Facade 呼叫舊系統 API

總結

外觀模式是「為複雜系統設計一個好用的介面」的藝術。它不引入新功能,而是重新組織既有功能,降低使用門檻。記住:好的外觀像萬用遙控器,壞的外觀像萬用膠水——前者簡化操作,後者混淆職責。實務中,外觀常與依賴注入、模組化架構結合,作為微服務邊界或框架進入點。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved