结构型 简单

外观模式

Facade Pattern

为子系统中的一组接口提供一个一致的界面。外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

概述

外观模式是一种结构型设计模式,能为复杂系统、库或框架提供一个简单(但有限)的接口。它将客户端与复杂的子系统解耦,使得客户端只需要与外观类交互,而不需要了解子系统内部的复杂实现。

适用场景

  • 当需要为一个复杂的子系统提供一个简单的接口时
  • 当需要将子系统与客户端解耦,减少它们之间的依赖时
  • 当需要构建分层系统时,使用外观模式定义每层的入口点
  • 当需要简化客户端与多个复杂子系统之间的交互时
  • 当需要对外隐藏子系统的复杂性和实现细节时

优点

  • +让自己的代码独立于复杂子系统,降低耦合度
  • +减少了客户端需要处理的对象数量,简化调用过程
  • +使子系统更易于使用,降低学习成本
  • +将子系统的变化隔离在内部,不影响客户端代码
  • +可以提供一个简化的接口同时保留完整功能的底层访问

缺点

  • 外观可能成为与程序中所有类都耦合的上帝对象
  • 在某些情况下,外观可能限制了客户端对底层子系统的灵活使用
  • 如果设计不当,外观类可能变得过于臃肿

结构

classDiagram class Facade { -SubsystemA subsystemA -SubsystemB subsystemB -SubsystemC subsystemC +operation() +operation2() } class SubsystemA { +operationA() +operationA2() } class SubsystemB { +operationB() +operationB2() } class SubsystemC { +operationC() +operationC2() } class Client { +main() } Facade --> SubsystemA : uses Facade --> SubsystemB : uses Facade --> SubsystemC : uses Client ..> Facade : uses style Facade fill:#e3f2fd,stroke:#1976d2,stroke-width:2px style SubsystemA fill:#fff3e0,stroke:#f57c00,stroke-width:1px style SubsystemB fill:#fff3e0,stroke:#f57c00,stroke-width:1px style SubsystemC fill:#fff3e0,stroke:#f57c00,stroke-width:1px style Client fill:#f5f5f5,stroke:#616161,stroke-width:1px

交互演示

为复杂子系统提供简化接口
Client
简化调用
Facade简化接口
🏠
SubsystemA
SubsystemB
SubsystemC

点击"一键操作",外观模式会协调所有子系统完成复杂操作

生活类比

外观模式就像是现实世界中的各种简化接口和服务窗口

餐厅服务员

你不需要直接与厨师、调酒师、清洁工交流,只需要告诉服务员你的需求,他会帮你协调一切。服务员就是餐厅子系统的外观。

智能家居遥控器

智能家居系统包含灯光、空调、窗帘、音响等多个子系统。遥控器(外观)提供一个统一的按钮来设置"观影模式",自动调节所有设备。

银行柜台

银行后台有账户管理、贷款审批、风险评估等复杂子系统。客户只需要在柜台(外观)办理业务,无需了解后台的复杂流程。

代码实现

Example.java

实际应用

Spring JDBC - JdbcTemplate

Spring 的 JdbcTemplate 为 JDBC 操作提供了简化的外观,隐藏了 Connection、Statement、ResultSet 等复杂对象的创建和管理。

Example.java

Java Servlet - HttpServletRequest

HttpServletRequest 和 HttpServletResponse 作为 Servlet 容器的外观,简化了 HTTP 请求和响应的处理。

Example.java

SLF4J 日志门面

SLF4J 作为各种日志框架(Logback、Log4j)的外观,提供统一的日志接口,使应用程序可以在不同日志实现间无缝切换。

Example.java

练习

1

外观模式的主要目的是什么?

2

外观模式会阻止客户端直接访问子系统类

3

以下哪个是外观模式的典型应用场景?