一、结构型模式
在面向对象的世界里,如何优雅地组织类与对象、构建更大的结构,是每一位开发者都会反复思考的问题。直接堆砌类和继承固然简单,但当业务复杂度上升、类间关系变得盘根错节时,这种方式就会让代码变得臃肿、难以维护。
结构型设计模式正是为了解决这一痛点而诞生的一套思想体系。它们关注如何将类或对象按某种布局组合成更大的结构,通过组合、代理、适配和装饰等手段,让代码更具灵活性、可复用性和可维护性。
在 Java 开发中,结构型模式主要包含以下 7 种经典实现:
二、外观模式
2.1 介绍
为子系统中的一组接口提供一个统一的高层入口,让外部通过这个入口访问子系统,而不必直接和复杂的内部模块交互。
2.2 角色
-
外观角色:为多个子系统对外提供一个共同的接口。
-
子系统角色:实现系统的部分功能,客户可以通过外观角色访问它。
三、代码实现
为了方便理解,本文类名采用中文
3.1 子系统角色
public class 灯 {
public void on() {
System.out.println("开灯…");
}
public void off() {
System.out.println("关灯…");
}
}
public class 空调 {
public void on() {
System.out.println("空调开始工作…");
}
public void off() {
System.out.println("空调停止工作…");
}
}
3.2 外观角色
public class 智能助手 {
private 灯 light;
private 空调 airConditioner;
public 智能助手() {
this.light = new 灯();
this.airConditioner = new 空调();
}
public void on(){
this.light.on();
this.airConditioner.on();
}
public void off(){
this.light.off();
this.airConditioner.off();
}
}
3.3 客户端
public class 客户端 {
public static void main(String[] args) {
智能助手 smartApplication = new 智能助手();
smartApplication.on();
smartApplication.off();
}
}
四、优缺点
4.1 优点
- 简化调用,降低学习成本客户端无需了解复杂子系统的内部结构,只需调用外观类的统一接口。
- 解耦客户端与子系统子系统内部的修改不会影响客户端代码,只有外观类需要适配调整,符合 “开闭原则”。
- 统一控制业务流程外观类可封装子系统的调用顺序和逻辑,避免客户端重复编写相同流程。
4.2 缺点
- 可能违背 “单一职责原则”若过度依赖外观类,会使其成为 “万能类”,承载过多业务逻辑,后续维护成本高。
- 增加系统复杂度(过度使用时)若子系统本身简单,引入外观类会多一层冗余封装,反而增加代码量。
- 灵活性受限外观类封装的是固定流程,若客户端需要个性化操作,要么修改外观类,要么绕过外观类直接调用子系统,破坏封装。
五、使用场景
-
对分层结构系统构建时,使用外观模式定义子系统中每层的入口点可以简化子系统之间的依赖关系。
-
当一个复杂系统的子系统很多时,外观模式可以为系统设计一个简单的接口供外界访问。
-
当客户端与多个子系统之间存在很大的联系时,引入外观模式可将它们分离,从而提高子系统的独立性和可移植性。
六、对比
6.1 与适配器模式对比
Java 设计模式・适配器模式篇:从思想到代码实现-CSDN博客
两者都 封装接口
| 核心目标 | 为复杂子系统提供统一、简化的入口 | 转换接口(把不兼容的接口转成兼容的) |
| 解决的问题 | 客户端调用太复杂(步骤多、依赖多) | 接口不匹配(比如老接口叫open(),新接口要start()) |
| 通俗例子 | 智能音箱(封装灯、电视、空调的操作,统一说 “打开”) | 电源适配器(把国标插头转成欧标,让插头适配插座) |
| 关系性质 | 对多个子系统的 “聚合 + 简化” | 对单个接口的 “转换 + 适配” |
6.2 对比代理模式
两者都 “封装目标对象”,但意图不同:
| 核心目标 | 简化多个子系统的调用 | 为单个对象提供 “代理访问”(如控制权限、懒加载) |
| 操作对象 | 多个子系统类 | 单个目标类 |
| 通俗例子 | 酒店总机(帮你转接餐厅、客房、前台) | 明星经纪人(替明星对接商务,控制访问) |
6.3 对比工具类
| 核心设计目的 | 为复杂子系统提供统一、简化的访问入口,核心是「解耦客户端与子系统」 | 提供通用的、可复用的静态方法,核心是「代码复用」,无 “解耦子系统” 的目的 |
| 面向对象特性 | 通常是实例类(可实例化),持有子系统对象的引用,封装子系统的交互逻辑 | 几乎都是静态工具类(私有构造器,不可实例化),无状态、无成员变量 |
| 与子系统的关系 | 紧密关联特定子系统,是子系统的 “门面”,会编排子系统的调用流程 | 无绑定的子系统,方法通常是通用的(如字符串处理、日期转换),不依赖特定业务 / 子系统 |
| 是否包含业务逻辑 | 可包含业务 / 流程逻辑 | 仅包含通用工具逻辑,无业务属性 |
七、源码举例
public class Collections {
…
public static <T> List<T> synchronizedList(List<T> list) {
return (list instanceof RandomAccess ?
new SynchronizedRandomAccessList<>(list) :
new SynchronizedList<>(list));
}
….
// 线程安全List的子系统
static class SynchronizedList<E>
extends SynchronizedCollection<E>
implements List<E> {
…
}
…
}
java.util.Collections 是工具类形态的外观类,所有核心方法都是静态方法,封装了集合子系统的复杂操作
八、其他相关设计模式
8.1 单例模式
Java 设计模式・单例模式篇:从思想到代码实现-CSDN博客
8.2 简单工厂+工厂方法+抽象工厂模式
Java 设计模式・工厂模式篇:从思想到代码实现-CSDN博客
8.3 建造者模式
Java 设计模式・建造者模式篇:从思想到代码实现-CSDN博客
8.4 原型模式
Java 设计模式・原型模式篇:从思想到代码实现-CSDN博客
8.5 代理模式
Java 设计模式・代理模式篇:从思想到代码实现-CSDN博客
8.6 适配器模式
Java 设计模式・适配器模式篇:从思想到代码实现-CSDN博客
8.7 装饰器模式
Java 设计模式・装饰器模式篇:从思想到代码实现-CSDN博客
8.8 桥接模式
Java 设计模式・桥接模式篇:从思想到代码实现-CSDN博客
8.9 外观模式
本篇





