iOS中的设计模式(九)- 外观模式 用外观模式点一份外卖:Swift 实战讲解

一. 引言

今天我们从一个最常见的场景来切入,讲解外观模式。现在中午订外卖已经成了非常普遍的现象。我们打开 App,点了一份麻辣香锅,然后30分钟后门铃响,外卖送到了------看似平常,但这背后发生了什么?

实际上,当我们点击"下单"的那一刻,系统可能在悄悄调用:

  • 餐厅接口,确认菜品与库存
  • 支付网关,处理付款
  • 配送系统,派送骑手
  • 物流追踪服务,实时更新订单状态

如果把这些功能都直接暴露给客户端,每次下单都要手动调用一大堆接口,代码会变得异常复杂。

这就是外观模式(Facade Pattern)登场的场景:它为复杂系统提供一个统一接口,让客户端只需关注核心流程。

二. 外观模式简介

我们可以把外观模式理解为:为复杂子系统提供一个统一的高层接口,让系统使用者能够更简单地完成操作,而无需了解内部复杂细节。

在外卖的例子里:

  • 客户端:用户(下单的人)
  • 外观(Facade):FoodDeliveryFacade
  • 子系统(Subsystem):餐厅、支付、配送

核心思想是:客户端只和外观接口交互,外观负责调度各个子系统完成完整流程。

三. 代码示意:用 Swift 模拟外卖系统

接下来,我们通过 Swift 代码来展示如何用外观模式封装外卖系统的流程。

3.1 子系统定义

每个子系统负责自己的职责:

餐厅系统:

Swift 复制代码
// 餐厅系统:处理点餐和做菜
struct RestaurantSystem {
    func selectDish(_ name: String) {
        print("选择菜品:\(name)")
    }
    func prepareDish() {
        print("厨房正在准备菜品...")
    }
}

支付系统:

Swift 复制代码
// 支付系统:模拟付款
struct PaymentSystem {
    func pay(amount: Double) {
        print("支付金额:¥\(amount)")
    }
}

配送系统:

Swift 复制代码
// 配送系统:负责骑手和派送
struct DeliverySystem {
    func assignRider() {
        print("派送员已接单")
    }
    func deliver() {
        print("配送中...")
    }
}

每个子系统内部可以很复杂,但对客户端来说,这些细节都并不需要关心。

3.2 外观类(Facade)

外观类统一封装整个下单流程,让客户端只需调用一个方法即可完成整个订单操作:

Swift 复制代码
// 外观类:统一封装整个下单流程
struct FoodDeliveryFacade {
    private let restaurant = RestaurantSystem()
    private let payment = PaymentSystem()
    private let delivery = DeliverySystem()
    
    func placeOrder(dish: String, amount: Double) {
        restaurant.selectDish(dish)
        restaurant.prepareDish()
        payment.pay(amount: amount)
        delivery.assignRider()
        delivery.deliver()
        print("订单已完成,祝您用餐愉快!")
    }
}

3.3 客户端调用示意

Swift 复制代码
let app = FoodDeliveryFacade()
app.placeOrder(dish: "麻辣香锅", amount: 48.0)

输出示意:

Swift 复制代码
选择菜品:麻辣香锅
厨房正在准备菜品...
支付金额:¥48.0
派送员已接单
配送中...
订单已完成,祝您用餐愉快!

客户端只需一句 placeOrder(),无需了解子系统内部的调用顺序和复杂流程,这就是外观模式的核心价值。

四. 模式分析

从前面的代码示意可以看出,外观模式在外卖系统里起到了"中介"和"封装"的作用:

  • 客户端:只需要调用 placeOrder(),无需关心内部流程
  • 外观(Facade):FoodDeliveryFacade 统一管理各个子系统的调用顺序
  • 子系统(Subsystem):餐厅、支付、配送,各自负责具体逻辑
角色 Swift 实现 说明
Facade(外观) FoodDeliveryFacade 对外提供统一接口,隐藏内部子系统的复杂调用
Subsystem(子系统) RestaurantSystem、PaymentSystem、DeliverySystem 各自独立实现具体功能,外部无需知道内部流程
Client(客户端) 调用 placeOrder() 的应用层 只与外观交互,降低耦合,简化调用

其实在实际开发中,我们在很多场景化中都会使用到这个外观模式。

直播间/播放器:

  • 比如一个直播 SDK,内部涉及视频拉流、音频处理、弹幕显示、网络状态监控等多个模块
  • 客户端只需调用 startLive() 或 play(url:),即可完成整个播放流程

多媒体编辑系统:

  • 视频编辑 App 可能涉及视频轨道、音频轨道、滤镜、转场等子系统
  • 外观类可以封装成 VideoEditorFacade,客户端调用 exportVideo() 就能完成整个流程

核心思想永远是一样的:外观模式让客户端只关注核心操作,无需了解内部复杂实现。

不管是下单外卖、播放视频,还是开启直播间,调用方式都是统一、简单、直观的。

五. 优缺点总结

5.1 优点

降低客户端复杂性:

外观模式可以降低客户端的复杂性,当外部需要使用某些复杂功能时,只需要调用外观提供的统一接口,而不比知道内部子系统如何写作。

降低耦合:

客户端与子系统功能解耦,系统可以独立修改或升级,而不影响外部调用。

统一管理流程:

外观类可以统一管理子系统调用顺序、错误处理等逻辑,让流程清晰可控。

5.2 缺点

如果封装过多功能,外观类会变得过大,维护难度增加。客户端只能按照外观提供的接口调用,某些自定义需求可能受限。

六. 结语

外观模式的核心价值在于 "让复杂系统对外变得简单"

不管是中午点一份麻辣香锅、播放一段视频,还是开启一个直播间,客户端看到的都是一个清晰、统一的接口:

Swift 复制代码
placeOrder()
play(url:)
startLive()

内部如何调用多个子系统、处理复杂逻辑,这些细节被外观隐藏起来,但一切依然井然有序。

相关推荐
Meteors.3 小时前
23种设计模式——外观模式(Facade Pattern)详解
设计模式·外观模式
czy87874753 小时前
用C语言实现外观模式
c语言·外观模式
Asort5 小时前
JavaScript设计模式(十六)——迭代器模式:优雅遍历数据的艺术
前端·javascript·设计模式
昨天的猫5 小时前
原来我们写的单例还存在缺陷~~
设计模式
Tiny_React6 小时前
智能体设计模式-CH13:人类参与环节(Human-in-the-Loop)
设计模式
Tiny_React6 小时前
智能体设计模式-CH09:学习与适应(Learning and Adaptation)
设计模式
Tiny_React6 小时前
智能体设计模式-CH10:模型上下文协议(Model Context Protocol)
设计模式
Tiny_React6 小时前
智能体设计模式-CH11:目标设定与监控(Goal Setting and Monitoring)
设计模式
Deschen17 小时前
设计模式-外观模式
java·设计模式·外观模式