外观模式 (Facade Pattern)

🚪 外观模式 (Facade Pattern)

🎯 模式概述

外观模式是一种结构型设计模式,它为复杂的子系统提供一个简化的接口。就像酒店的前台一样,客人不需要直接与清洁部、厨房、维修部等各个部门打交道,只需要通过前台就能享受各种服务。

外观模式隐藏了系统的复杂性,为客户端提供了一个简单易用的接口。它不会封装子系统,而是提供一个更高层次的接口,使子系统更容易使用。

🔍 核心思想

外观模式通过引入一个外观类,将客户端与复杂的子系统解耦。客户端只需要与外观类交互,外观类负责调用相应的子系统完成工作。

📊 UML类图结构

外观模式 UML

                    ┌─────────────────┐
                    │     Client      │
                    │                 │
                    │ + doSomething() │
                    └─────────────────┘
                             │
                             │ uses
                             ▼
                    ┌─────────────────┐
                    │     Facade      │
                    │                 │
                    │ - subsystem1:   │
                    │   SubSystem1*   │
                    │ - subsystem2:   │
                    │   SubSystem2*   │
                    │ - subsystem3:   │
                    │   SubSystem3*   │
                    │                 │
                    │ + operation1()  │
                    │ + operation2()  │
                    │ + complexOp()   │
                    └─────────────────┘
                             │
                             │ manages
                             ▼
                    ┌─────────────────┐
                    │   SubSystem1    │
                    │                 │
                    │ + method1A()    │
                    │ + method1B()    │
                    └─────────────────┘
                    
                    ┌─────────────────┐
                    │   SubSystem2    │
                    │                 │
                    │ + method2A()    │
                    │ + method2B()    │
                    │ + method2C()    │
                    └─────────────────┘
                    
                    ┌─────────────────┐
                    │   SubSystem3    │
                    │                 │
                    │ + method3A()    │
                    │ + method3B()    │
                    └─────────────────┘

🔍 关键点:Facade封装了复杂子系统的调用,为客户端提供简单接口

外观模式交互示意

Without Facade:                    With Facade:

Client                             Client
  │                                  │
  ├─► SubSystem1.method1A()          └─► Facade.complexOperation()
  │                                        │
  ├─► SubSystem1.method1B()                ├─► SubSystem1.method1A()
  │                                        │
  ├─► SubSystem2.method2A()                ├─► SubSystem1.method1B()
  │                                        │
  ├─► SubSystem2.method2C()                ├─► SubSystem2.method2A()
  │                                        │
  ├─► SubSystem3.method3A()                ├─► SubSystem2.method2C()
  │                                        │
  └─► SubSystem3.method3B()                ├─► SubSystem3.method3A()
                                           │
                                           └─► SubSystem3.method3B()

🔍 外观模式大大简化了客户端的使用复杂度

🤔 为什么需要外观模式?

📊 问题场景对比

问题场景 不使用外观模式 使用外观模式
🔧 复杂调用流程 客户端需了解详细步骤 一个方法完成所有操作
📚 学习成本 需要学习多个子系统 只需学习外观接口
🔄 维护难度 调用代码分散各处 统一在外观类中维护
🎯 错误处理 每个调用点都要处理 外观类统一处理错误

💡 问题演示

// ❌ 不使用外观模式的复杂调用
void clientCodeWithoutFacade() {
   
   
    // 客户端需要了解复杂的调用序列
    CPU cpu;
    Memory memory;
    HardDisk hardDisk;
    
    // 启动计算机需要复杂的步骤
    cpu.freeze();
    memory.load(BOOT_ADDRESS, hardDisk.read(BOOT_SECTOR, SECTOR_SIZE));
    cpu.jump(BOOT_ADDRESS);
    cpu.execute();
    
    // 如果步骤错误或遗漏,系统就无法正常工作
    // 而且每个使用的地方都要重复这些复杂的调用
}

🚪 外观模式实现方式

1️⃣ 经典外观模式实现

让我们用家庭影院系统来演示外观模式:

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

// 子系统1:音响系统
class AudioSystem {
   
   
private:
    int volume = 50;
    std::string audioMode = "Stereo";
    bool isPoweredOn = false;
    
public:
    void powerOn() {
   
   
        isPoweredOn = true;
        std::cout << "🔊 音响系统: 开机" << std::endl;
        std::cout << "   ├─ 自检中..." << std::endl;
        std::cout << "   └─ 音响系统就绪" << std::endl;
    }
    
    void powerOff() {
   
   
        isPoweredOn = false;
        std::cout << "🔊 音响系统: 关机" << std::endl;
    }
    
    void setVolume(int vol) {
   
   
        if (isPoweredOn) {
   
   
            volume = std::max(0, std::min(100, vol));
            std::cout << "🔊 音响系统: 音量设置为 " << volume << std::endl;
        } else {
   
   
            std::cout << "⚠️ 音响系统: 请先开机" << std::endl;
        }
    }
    
    void setAudioMode(const std::string& mode) {
   
   
        if (isPoweredOn) {
   
   
            audioMode = mode;
            std::cout << "🔊 音响系统: 音效模式设置为 " << audioMode << std::endl;
        }
    }
    
    void playTestSound() {
   
   
        if (isPoweredOn) {
   
   
            std::cout << "🔊 音响系统: 播放测试音频 ♪♫♪" << std::endl;
        }
    }
    
    bool isOn() const {
   
    return isPoweredOn; }
    int getVolume() const {
   
    return volume; }
};

// 子系统2:投影仪系统
class ProjectorSystem {
   
   
private:
    bool isPoweredOn = false;
    std::string resolution = "1920x1080";
    int brightness = 80;
    std::string inputSource = "HDMI1";
    
public:
    void powerOn() {
   
   
        isPoweredOn = true;
        std::cout << "📽️ 投影仪: 开机" << std::endl;
        std::cout << "   ├─ 灯泡预热中..." << std::endl;
        std::cout << "   ├─ 镜头对焦中..." << std::endl;
        std::cout << "   └─ 投影仪就绪" << std::endl;
    }
    
    void powerOff() {
   
   
        if (isPoweredOn) {
   
   
            std::cout << "📽️ 投影仪: 关机" << std::endl;
            std::cout << "   └─ 灯泡冷却中..." << std::endl;
            isPoweredOn = false;
        }
    }
    
    void setResolution(const std::string& res) {
   
   
        if (isPoweredOn) {
   
   
            resolution = res;
            std::cout << "📽️ 投影仪: 分辨率设置为 " << resolution << std::endl;
        }
    }
    
    void setBrightness(int bright) {
   
   
        if (isPoweredOn) {
   
   
            brightness = std::max(1, std::min(100, bright));
            std::cout << "📽️ 投影仪: 亮度设置为 " << brightness << "%" << std::endl;
        }
    }
    
    void setInputSource(const std::string& source) {
   
   
        if (isPoweredOn) {
   
   
            inputSource = source;
            std::cout << "📽️ 投影仪: 输入源切换到 " << inputSource << std::endl;
        }
    }
    
    void displayTestPattern() {
   
   
        if (isPoweredOn) {
   
   
            std::cout << "📽️ 投影仪: 显示测试图案 ▓▓▓░░░▓▓▓" << std::endl;
        }
    }
    
    bool isOn() const {
   
    return isPoweredOn; }
};

// 子系统3:灯光控制系统
class LightingSystem {
   
   
private:
    struct Light {
   
   
        std::string name;
        bool isOn;
        int brightness;
        std::string color;
        
        Light(const std::string& n) : name(n), isOn(false), brightness(100), color("白色") {
   
   }
    };
    
    std::vector<Light> lights;
    std::string currentScene = "Normal";
    
public:
    LightingSystem() {
   
   
        lights.emplace_back("主灯");
        lights.emplace_back("环境灯");
        lights.emplace_back("装饰灯");
        lights.emplace_back("走廊灯");
    }
    
    void turnOnAllLights() {
   
   
        std::cout << "💡 灯光系统: 开启所有灯光" << std::endl;
        for (auto& light : lights) {
   
   
            light.isOn = true;
            std::cout << "   ├─ " << light.name << " 开启" << std::endl;
        }
    }
    
    void turnOffAllLights() {
   
   
        std::cout << "💡 灯光系统: 关闭所有灯光" << std::endl;
        for (auto& light : lights) {
   
   
            light.isOn = false;
            std::cout << "   ├─ " << light.name << " 关闭" << std::endl;
        }
    }
    
    void setScene(const std::string& scene) {
   
   
        currentScene = scene;
        std::cout << "💡 灯光系统: 切换到 " << scene << " 模式" << std::endl;
        
        if (scene == "Movie") {
   
   
            // 电影模式:调暗灯光
            for (auto& light : lights) {
   
   
                if (light.name == "主灯") {
   
   
                    light.isOn = false;
                    std::cout << "   ├─ " << light.name << " 关闭" << std::endl;
                } else {
   
   
                    light.isOn = true;
                    light.brightness = 20;
                    light.color = "暖黄色";
                    std::cout << "   ├─ " << light.name << " 调至 " << light.brightness 
                              << "% " << light.color << std::endl;
                }
            }
        } else if (scene == "Party") {
   
   
            // 聚会模式:彩色灯光
            for (auto& light : lights) {
   
   
                light.isOn = true;
                light.brightness = 80;
                light.color = "彩色";
                std::cout << "   ├─ " << light.name << " 调至 " << light.brightness 
                          << "% " << light.color << std::endl;
            }
        }
    }
    
    void dimLights(int level) {
   
   
        std::cout << "💡 灯光系统: 调光至 " << level << "%" << std::endl;
        for (auto& light : lights) {
   
   
            if (light.isOn) {
   
   
                light.brightness = level;
            }
        }
    }
    
    std::string getCurrentScene() const {
   
    return currentScene; }
};

// 子系统4:窗帘控制系统
class CurtainSystem {
   
   
private:
    bool isMotorized = true;
    int openLevel = 100; // 0=完全关闭, 100=完全打开
    std::string curtainType = "遮光窗帘";
    
public:
    void openCurtains() {
   
   
        if (isMotorized) {
   
   
            std::cout << "🪟 窗帘系统: 自动打开窗帘" << std::endl;
            std::cout << "   ├─ 电机启动..." << std::endl;
            openLevel = 100;
            std::cout << "   └─ 窗帘完全打开" << std::endl;
        } else {
   
   
            std::cout << "🪟 窗帘系统: 请手动打开窗帘" << std::endl;
        }
    }
    
    void closeCurtains() {
   
   
        if (isMotorized) {
   
   
            std::cout << "🪟 窗帘系统: 自动关闭窗帘" << std::endl;
            std::cout << "   ├─ 电机启动..." << std::endl;
            openLevel = 0;
            std::cout << "   └─ 窗帘完全关闭" << std::endl;
        }
    }
    
    void setCurtainLevel(int level) {
   
   
        if (isMotorized) {
   
   
            openLevel = std::max(0, std::min(100, level));
            std::cout << "🪟 窗帘系统: 窗帘开启度设置为 " << openLevel << "%" << std::endl;
        }
    }
    
    int getOpenLevel() const {
   
    return openLevel; }
};

// 子系统5:空调系统
class AirConditioningSystem {
   
   
private:
    bool isPoweredOn = false;
    int temperature = 25;
    std::string mode = "Auto";
    int fanSpeed = 2;
    
public:
    void powerOn() {
   
   
        isPoweredOn = true;
        std::cout << "❄️ 空调系统: 开机" << std::endl;
        std::cout << "   ├─ 压缩机启动..." << std::endl;
        std::cout << "   └─ 空调系统就绪" << std::endl;
    }
    
    void powerOff() {
   
   
        isPoweredOn = false;
        std::cout << "❄️ 空调系统: 关机" << std::endl;
    }
    
    void setTemperature(int temp) {
   
   
        if (isPoweredOn) {
   
   
            temperature = std::max(16, std::min(30, temp));
            std::cout << "❄️ 空调系统: 温度设置为 " << temperature << "°C" << std::endl;
        }
    }
    
    void setMode(const std::string& m) {
   
   
        if (isPoweredOn) {
   
   
            mode = m;
            std::cout << "❄️ 空调系统: 模式设置为 " << mode << std::endl;
        }
    }
    
    void setFanSpeed(int speed) {
   
   
        if (isPoweredOn) {
   
   
            fanSpeed = std::max(1, std::min(5, speed));
            std::cout << "❄️ 空调系统: 风速设置为 " << fanSpeed << " 档" << std::endl;
        }
    }
    
    bool isOn() const {
   
    return isPoweredOn; }
    int getTemperature() const {
   
    return temperature; }
};

// 外观类:家庭影院系统
class HomeTheaterFacade {
   
   
private:
    std::unique_ptr<AudioSystem> audioSystem;
    std::unique_ptr<ProjectorSystem> projectorSystem;
    std::unique_ptr<LightingSystem> lightingSystem;
    std::unique_ptr<CurtainSystem> curtainSystem;
    std::unique_ptr<AirConditioningSystem> acSystem;
    
    bool isSystemReady = false;
    
public:
    HomeTheaterFacade() {
   
   
        std::cout << "🏠 家庭影院系统: 初始化中..." << std::endl;
        
        audioSystem = std::make_unique<AudioSystem>();
        projectorSystem = std::make_unique<ProjectorSystem>();
        lightingSystem = std::make_unique<LightingSystem>();
        curtainSystem = std::make_unique<CurtainSystem>();
        acSystem = std::make_unique<AirConditioningSystem>();
        
        std::cout << "🏠 家庭影院系统: 初始化完成" << std::endl;
    }
    
    // 简单接口:开始观影
    void startMovie(const std::string& movieTitle = "Unknown Movie") {
   
   
        std::cout << "\n🎬 开始观影: " << movieTitle << std::endl;
        std::cout << std::string(50, '=') << std::endl;
        
        // 复杂的启动序列,客户端无需了解
        std::cout << "正在准备观影环境..." << std::endl;
        
        // 1. 关闭窗帘
        curtainSystem->closeCurtains();
        
        // 2. 设置灯光为电影模式
        lightingSystem->setScene("Movie");
        
        // 3. 启动投影仪
        projectorSystem->powerOn();
        projectorSystem->setInputSource("HDMI1");
        projectorSystem->setResolution("4K");
        projectorSystem->setBrightness(85);
        
        // 4. 启动音响系统
        audioSystem->
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

clearwwu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值