外观模式(Facade Pattern)

定义

外观模式 (Facade Pattern) 是一种结构型设计模式,它为子系统中的一组接口提供一个统一的高层接口。这个接口使得子系统更容易使用。

基本结构

  • 外观类 (Facade):提供简化的接口,内部协调多个子系统

  • 子系统类 (Subsystem):实现具体的业务逻辑

  • 客户端 (Client):通过外观类来使用子系统

(1)代码模板

c# 复制代码
// 1. 创建子系统类
class A { public void DoA() {} }
class B { public void DoB() {} }
class C { public void DoC() {} }

// 2. 创建外观类
class Facade
{
    private A _a = new A();
    private B _b = new B();
    private C _c = new C();
    
    // 3. 提供简单方法
    public void DoAll()
    {
        _a.DoA();
        _b.DoB();
        _c.DoC();
    }
}

// 4. 客户端使用
Facade facade = new Facade();
facade.DoAll();  // 一行代替三行

(2)简单示例:智能家居系统

下面是用 C# 实现的外观模式 示例项目,以智能家居控制系统为应用场景。

c# 复制代码
namespace 外观模式
{
    // 子系统组件1:灯光
    class Light
    {
        public void TurnOn()
        {
            Console.WriteLine("客厅灯已打开");
        }

        public void TurnOff()
        {
            Console.WriteLine("客厅灯已关闭");
        }

        public void SetBrightness(int level)
        {
            Console.WriteLine($"灯光亮度设置为: {level}%");
        }
    }

    // 子系统组件2:空调
    class AirConditioner
    {
        public void TurnOn()
        {
            Console.WriteLine("空调已打开");
        }

        public void TurnOff()
        {
            Console.WriteLine("空调已关闭");
        }

        public void SetTemperature(int temperature)
        {
            Console.WriteLine($"空调温度设置为: {temperature}°C");
        }
    }

    // 子系统组件3:电视
    class TV
    {
        public void TurnOn()
        {
            Console.WriteLine("电视已打开");
        }

        public void TurnOff()
        {
            Console.WriteLine("电视已关闭");
        }

        public void SetChannel(int channel)
        {
            Console.WriteLine($"切换到频道: {channel}");
        }

        public void SetVolume(int volume)
        {
            Console.WriteLine($"音量设置为: {volume}");
        }
    }

    // 子系统组件4:音响
    class SoundSystem
    {
        public void TurnOn()
        {
            Console.WriteLine("音响系统已打开");
        }

        public void TurnOff()
        {
            Console.WriteLine("音响系统已关闭");
        }

        public void SetVolume(int volume)
        {
            Console.WriteLine($"音响音量设置为: {volume}");
        }

        public void PlayMusic()
        {
            Console.WriteLine("播放音乐...");
        }
    }

    // 外观类:提供简化的接口
    class SmartHomeFacade
    {
        private Light light;
        private AirConditioner airConditioner;
        private TV tv;
        private SoundSystem soundSystem;

        public SmartHomeFacade()
        {
            light = new Light();
            airConditioner = new AirConditioner();
            tv = new TV();
            soundSystem = new SoundSystem();
        }

        // 场景1:回家模式
        public void ComeHome()
        {
            Console.WriteLine("========== 执行回家模式 ==========");
            light.TurnOn();
            light.SetBrightness(80);
            airConditioner.TurnOn();
            airConditioner.SetTemperature(24);
            tv.TurnOn();
            tv.SetChannel(1);
            tv.SetVolume(30);
            Console.WriteLine("=================================\n");
        }

        // 场景2:离家模式
        public void LeaveHome()
        {
            Console.WriteLine("========== 执行离家模式 ==========");
            light.TurnOff();
            airConditioner.TurnOff();
            tv.TurnOff();
            soundSystem.TurnOff();
            Console.WriteLine("=================================\n");
        }

        // 场景3:观影模式
        public void WatchMovie()
        {
            Console.WriteLine("========== 执行观影模式 ==========");
            light.TurnOn();
            light.SetBrightness(20);
            tv.TurnOn();
            tv.SetChannel(5);
            tv.SetVolume(25);
            soundSystem.TurnOn();
            soundSystem.SetVolume(40);
            airConditioner.TurnOn();
            airConditioner.SetTemperature(22);
            Console.WriteLine("=================================\n");
        }

        // 场景4:睡眠模式
        public void Sleep()
        {
            Console.WriteLine("========== 执行睡眠模式 ==========");
            light.TurnOff();
            tv.TurnOff();
            soundSystem.TurnOff();
            airConditioner.TurnOn();
            airConditioner.SetTemperature(26);
            Console.WriteLine("=================================\n");
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            // 创建外观对象
            SmartHomeFacade smartHome = new SmartHomeFacade();

            // 使用简化的接口来控制智能家居
            smartHome.ComeHome();     // 回家
            smartHome.WatchMovie();   // 看电影
            smartHome.Sleep();        // 睡觉
            smartHome.LeaveHome();    // 离家

            Console.WriteLine("\n如果不使用外观模式,需要逐个调用各个子系统的方法:");
            Console.WriteLine("================================================================\n");

            // 对比:不使用外观模式的情况
            Light directLight = new Light();
            AirConditioner directAC = new AirConditioner();
            TV directTV = new TV();

            // 客户端需要知道所有子系统的细节
            directLight.TurnOn();
            directLight.SetBrightness(100);
            directAC.TurnOn();
            directAC.SetTemperature(25);
            directTV.TurnOn();
            directTV.SetChannel(3);
            directTV.SetVolume(35);
        }
    }
}

效果展示:

bash 复制代码
Hello, World!
========== 执行回家模式 ==========
客厅灯已打开
灯光亮度设置为: 80%
空调已打开
空调温度设置为: 24°C
电视已打开
切换到频道: 1
音量设置为: 30
=================================

========== 执行观影模式 ==========
客厅灯已打开
灯光亮度设置为: 20%
电视已打开
切换到频道: 5
音量设置为: 25
音响系统已打开
音响音量设置为: 40
空调已打开
空调温度设置为: 22°C
=================================

========== 执行睡眠模式 ==========
客厅灯已关闭
电视已关闭
音响系统已关闭
空调已打开
空调温度设置为: 26°C
=================================

========== 执行离家模式 ==========
客厅灯已关闭
空调已关闭
电视已关闭
音响系统已关闭
=================================


如果不使用外观模式,需要逐个调用各个子系统的方法:
================================================================

客厅灯已打开
灯光亮度设置为: 100%
空调已打开
空调温度设置为: 25°C
电视已打开
切换到频道: 3
音量设置为: 35
  • 使用外观模式前:客户端需要逐个调用7+个方法,必须了解每个子系统的细节。

  • 使用外观模式后:客户端只需调用1个方法(如 smartHome.ComeHome() ),无需知道内部实现细节。

这种模式降低了系统的耦合度,提高了代码的可维护性和易用性。

适用场景

✅ 系统越来越复杂,客户端需要简化的接口

✅ 客户端与多个子系统之间存在大量依赖关系

✅ 需要分层架构,定义每一层的入口

✅ 为遗留系统创建新的接口

优缺点

  • 优点:

降低客户端使用复杂度

减少客户端与子系统之间的耦合

提高代码的可维护性和可读性

不影响客户端直接使用子系统

  • 缺点:

可能增加不必要的外观类

不符合开闭原则(修改子系统可能需要修改外观类)

  • 现实生活中的例子

智能家居的一键模式

电脑开机(CPU、内存、硬盘、显示器协同工作)

银行转账(验证账户、检查余额、扣款、入账、通知)

相关推荐
进击的小头2 小时前
C语言实现设计模式的核心基石
c语言·开发语言·设计模式
Engineer邓祥浩2 小时前
设计模式学习(15) 23-13 模版方法模式
java·学习·设计模式
茶本无香2 小时前
设计模式之四:建造者模式(Builder Pattern)详解
java·设计模式·建造者模式
山风wind3 小时前
设计模式-访问者模式详解
python·设计模式·访问者模式
Yu_Lijing3 小时前
基于C++的《Head First设计模式》笔记——组合模式
c++·笔记·设计模式·组合模式
Engineer邓祥浩3 小时前
设计模式学习(17) 23-15 访问者模式
学习·设计模式·访问者模式
Geoking.19 小时前
【设计模式】23 种设计模式全景总结
设计模式
sg_knight21 小时前
工厂方法模式(Factory Method)
java·服务器·python·设计模式·工厂方法模式·工厂模式
鳄鱼皮坡21 小时前
设计模式(二):工厂模式
设计模式