103、23种设计模式之外观模式(12/23)
一、定义
外观模式是一种结构型设计模式,通过引入一个外观类(Facade),为复杂子系统提供简化的统一接口。其核心思想是“门面”——客户端只需与外观类交互,无需直接操作子系统中的多个类,从而降低系统复杂度并解耦模块。
二、应用场景
1.复杂子系统简化
- 当子系统包含多个相互依赖的模块(如数据库操作、文件处理、网络请求)时,外观模式可封装这些模块的调用流程,提供一键式操作。
- 示例:电商系统下单需调用商品查询、库存扣减、订单生成、日志记录等子系统,外观类可封装这一流程为PlaceOrder()方法。
2.分层架构设计
- 在经典三层架构(表现层、业务逻辑层、数据访问层)中,外观类可作为层间接口,减少跨层调用时的耦合。
- 示例:业务逻辑层通过外观类调用数据访问层的多个DAO,而无需直接依赖具体实现。
3.遗留系统集成
- 当维护旧系统时,可通过外观类为新功能提供清晰接口,避免直接修改遗留代码。
- 示例:为老旧的支付系统封装外观类,新模块仅需调用ProcessPayment(),无需理解内部复杂逻辑。
4.多技术栈整合
- 在微服务或混合架构中,外观模式可统一不同服务的调用方式。
- 示例:通过外观类封装REST API、GraphQL和gRPC三种服务的调用细节。
三、优缺点
1.优点
- 简化调用:客户端无需了解子系统内部细节。
- 解耦模块:降低客户端与子系统的直接依赖。
- 提高可维护性:子系统变更仅影响外观类。
2.缺点
- 违背开闭原则:新增子系统需修改外观类代码。
- 过度简化风险:可能隐藏关键子系统功能,导致调试困难。
- 性能开销:额外封装层可能增加调用链耗时。
四、C# 示例代码
using System;// 子系统1:库存服务
public class InventoryService {public void CheckStock(string productId) {Console.WriteLine($"Checking stock for {productId}...");}
}// 子系统2:支付服务
public class PaymentService {public void ProcessPayment(decimal amount) {Console.WriteLine($"Processing payment of ${amount}...");}
}// 子系统3:订单服务
public class OrderService {public void CreateOrder(string customerId) {Console.WriteLine($"Creating order for customer {customerId}...");}
}// 外观类
public class OrderFacade {private InventoryService _inventory;private PaymentService _payment;private OrderService _order;public OrderFacade() {_inventory = new InventoryService();_payment = new PaymentService();_order = new OrderService();}// 统一下单接口public void PlaceOrder(string productId, decimal amount, string customerId) {_inventory.CheckStock(productId);_payment.ProcessPayment(amount);_order.CreateOrder(customerId);Console.WriteLine("Order placed successfully!");}
}// 客户端代码
public class Program {public static void Main() {var facade = new OrderFacade();facade.PlaceOrder("P123", 99.99m, "C456");}
}/* 输出:
Checking stock for P123...
Processing payment of $99.99...
Creating order for customer C456...
Order placed successfully!
*/
五、关键点总结
1.单一职责原则: 外观类仅负责协调子系统调用,不实现具体业务逻辑。
2. 最少知识原则(迪米特法则): 客户端仅与外观类交互,减少对子系统的直接依赖。
3. 与中介者模式的区别:
- 外观模式关注外部与子系统的交互,中介者模式关注子系统内部的通信。
4. 与抽象工厂模式的结合:
- 外观类可内部使用抽象工厂创建子系统实例,进一步解耦客户端与具体实现。
5. 适用场景扩展:
- 在IoC容器或依赖注入框架中,外观模式可简化服务注册与调用流程。
- 在GUI开发中,外观类可封装复杂控件的初始化逻辑(如创建图表时配置数据源、样式、交互事件)。