设计模式详解——外观模式

设计模式详解------外观模式:一键封装复杂子系统,调用更简单

一、外观模式概述

1. 模式定义

外观模式(Facade Pattern) ,也叫门面模式 ,是一种结构型设计模式

它提供一个统一的高层接口,用来封装子系统中一组复杂的接口调用,让客户端使用更简单,同时降低客户端与子系统的耦合。

简单理解:

  • 子系统 = 一堆复杂零件
  • 外观 = 统一控制面板/开关
  • 客户端 = 只按开关,不用管内部怎么运行

2. 核心思想

  • 对外简化调用 ,对内封装复杂
  • 客户端只与外观类交互,不直接接触子系统
  • 遵循迪米特法则(最少知道原则)
  • 不新增功能,只做整合、封装、转发

3. 主要角色

  1. 外观类(Facade)
    对外提供统一入口,内部组合并调用多个子系统模块。
  2. 子系统(SubSystem)
    实际业务逻辑,可能是多个类、多个接口、多个服务。
  3. 客户端(Client)
    通过外观类使用功能,不直接调用子系统。

二、适用场景

  1. 一个流程需要调用多个模块/服务,步骤繁琐
  2. 希望降低客户端与复杂系统的耦合
  3. 对外提供简洁统一API,隐藏底层实现
  4. 系统分层、模块解耦(Controller → Facade → Service)
  5. 第三方SDK、复杂工具类封装

典型业务场景:

  • 下单流程(扣库存+创建订单+扣余额+发消息)
  • 支付流程(验签+扣款+通知+日志)
  • 项目启动初始化(加载配置+连接DB+初始化缓存)

三、实战代码实现(模拟商城下单)

场景说明

一次下单需要调用:

  1. 库存系统 StockService
  2. 订单系统 OrderService
  3. 支付系统 PayService
  4. 消息系统 MessageService

客户端不想关心这么多类,我们用外观类统一封装。

1. 子系统类(多个)

java 复制代码
// 库存服务
public class StockService {
    public boolean deductStock(Long skuId) {
        System.out.println("扣除商品库存:" + skuId);
        return true;
    }
}

// 订单服务
public class OrderService {
    public Long createOrder(Long userId, Long skuId) {
        System.out.println("创建订单:userId=" + userId + ", skuId=" + skuId);
        return 1001L;
    }
}

// 支付服务
public class PayService {
    public boolean pay(Long orderId, int amount) {
        System.out.println("支付订单:" + orderId + ",金额:" + amount);
        return true;
    }
}

// 消息通知服务
public class MessageService {
    public void sendMsg(Long userId, String msg) {
        System.out.println("发送消息给用户" + userId + ":" + msg);
    }
}

2. 外观类(核心)

java 复制代码
/**
 * 下单外观类:封装整个下单流程
 */
public class OrderFacade {

    // 组合所有子系统
    private StockService stockService = new StockService();
    private OrderService orderService = new OrderService();
    private PayService payService = new PayService();
    private MessageService messageService = new MessageService();

    /**
     * 统一对外下单入口
     */
    public boolean placeOrder(Long userId, Long skuId, int amount) {
        // 1. 扣库存
        stockService.deductStock(skuId);
        // 2. 创建订单
        Long orderId = orderService.createOrder(userId, skuId);
        // 3. 支付
        payService.pay(orderId, amount);
        // 4. 发通知
        messageService.sendMsg(userId, "下单成功,订单号:" + orderId);

        return true;
    }
}

3. 客户端调用

java 复制代码
public class Client {
    public static void main(String[] args) {
        // 只和外观类交互
        OrderFacade orderFacade = new OrderFacade();
        orderFacade.placeOrder(1001L, 2001L, 99);
    }
}

4. 运行结果

复制代码
扣除商品库存:2001
创建订单:userId=1001, skuId=2001
支付订单:1001,金额:99
发送消息给用户1001:下单成功,订单号:1001

四、外观模式优缺点

优点

  1. 简化调用,客户端代码更清爽
  2. 解耦:客户端不依赖子系统细节
  3. 保护子系统,减少误调用风险
  4. 符合迪米特法则,最少知道原则
  5. 便于分层、统一收口、统一日志/权限控制

缺点

  1. 外观类可能过度膨胀,变成超级大类
  2. 不符合开闭原则:新增子流程需要修改外观类
  3. 过度封装会降低灵活性(需要精细控制时不方便)

五、经典应用场景

1. Spring 中的 Facade

  • JdbcTemplateRedisTemplate 封装复杂JDBC/Redis操作
  • Spring MVC 前端控制器 DispatcherServlet 本质也是外观
  • 微服务中的 API网关 也是外观思想的体现

2. 业务架构

  • Controller 不直接调用 N 个 Service,而是调用一个 XxxFacade
  • 第三方接口封装:外部只调一个方法,内部调用多个接口

3. Tomcat/Servlet 容器

Request、Response 封装底层 Socket 复杂操作,对外提供简单API


六、外观模式 VS 适配器模式 VS 装饰器模式(面试必问)

模式 核心目的 接口变化 作用
外观模式 简化复杂调用 定义新的简单接口 封装、整合、收口
适配器模式 接口不兼容 转换接口 兼容、适配、桥接
装饰器模式 增强功能 保持原接口 增强、叠加、扩展

一句话区分

  • 外观:把复杂变简单
  • 适配器:把不能用变能用
  • 装饰器:把普通变强大

七、总结

  1. 外观模式 = 统一入口 + 封装复杂流程
  2. 核心价值:简化调用、降低耦合、保护子系统
  3. 不新增业务逻辑,只做转发与编排
  4. 项目中非常常用,是业务分层、接口收口的最佳实践之一
  5. 遵循原则:迪米特法则、单一职责

一句话记忆:复杂流程一团乱,外观门面挡后面;客户端只点一下,内部细节全不管!

如果你需要,我可以继续按这个格式写:代理模式 / 桥接模式 / 组合模式 / 享元模式,保持统一风格方便你直接发 CSDN 博客。

相关推荐
Rsun045516 分钟前
设计模式应该怎么学
java·开发语言·设计模式
_MyFavorite_2 小时前
JAVA重点基础、进阶知识及易错点总结(31)设计模式基础(单例、工厂)
java·开发语言·设计模式
_MyFavorite_13 小时前
JAVA重点基础、进阶知识及易错点总结(32)设计模式(建造者、原型)
java·python·设计模式
妙蛙种子31113 小时前
【Java设计模式 | 创建者模式】单例模式
java·开发语言·后端·单例模式·设计模式
武藤一雄1 天前
C# 异步回调与等待机制
前端·microsoft·设计模式·微软·c#·.netcore
he___H1 天前
Spring中的设计模式
java·spring·设计模式
程序员小寒1 天前
JavaScript设计模式(八):命令模式实现与应用
前端·javascript·设计模式·ecmascript·命令模式
程序员榴莲1 天前
设计模式之GoF设计模式(单例模式
单例模式·设计模式
砍光二叉树2 天前
【设计模式】行为型-解释器模式
设计模式·解释器模式
砍光二叉树2 天前
【设计模式】行为型-备忘录模式
设计模式·备忘录模式