Java常见的23种设计模式
大家好,我是钢板兽!
本文将系统梳理 Java 的设计模式,涵盖创建型、结构型和行为型三大类,结合定义、原理、优点、应用场景、示例代码,帮助你初步了解常见的23种设计模式。
一、设计模式分类
根据模式的目的,Java 的设计模式被分为三大类:创建型模式、结构型模式和行为型模式。
- 创建型模式(Creational Patterns)目的是解决"对象如何创建"的问题,封装对象的创建逻辑,解耦使用者与构造细节。
- 结构型模式(Structural Patterns)目的是解决"类或对象之间如何组合"的问题,强调组合结构,提升系统的灵活性与可维护性。
- 行为型模式(Behavioral Patterns)目的是解决"对象之间如何交互"的问题,关注算法、职责、流程的封装与解耦。

二、创建型模式(5种)
1. 单例模式(Singleton)
- 定义: 保证一个类只有一个实例,并提供全局访问点。
- 原理: 构造函数私有化,使用静态变量存储实例,通过静态方法获取实例。
- 优点: 控制资源使用,防止多个实例导致冲突,线程安全。
- 应用场景: 日志工具类、线程池、配置中心、数据库连接池。
- 示例代码:
java
public class Singleton {
private static volatile Singleton instance;
// 私有构造函数,防止外部 new
private Singleton() {}
// 双重检查锁,确保线程安全且延迟加载
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
2. 工厂方法模式(Factory Method)
在Java中,工厂模式是一种广泛使用的设计模式,它属于创建型模式,旨在解决对象创建过程中的耦合问题,提高代码的复用性和扩展性。工厂模式通过定义一个共同的接口或抽象类来创建对象,客户端通过调用这个接口或抽象类来获取具体对象,而无需知道具体类的实现细节。工厂模式通常分为三种类型:简单工厂模式、工厂方法模式和抽象工厂模式。
- 定义: 定义一个用于创建对象的接口,让子类决定实例化哪一个类。
- 原理: 抽象工厂接口 + 多个实现类封装创建逻辑。
- 优点: 解耦对象创建与使用,符合开闭原则,便于扩展。
- 应用场景: 日志框架 Appender、JDBC 中的 Connection 驱动。
- 示例代码:
java
// 产品接口
public interface Product {
void use();
}
// 具体产品类
public class ProductA implements Product {
public void use() {
System.out.println("使用产品 A");
}
}
// 工厂接口
public interface Factory {
Product create();
}
// 具体工厂类
public class FactoryA implements Factory {
public Product create() {
return new ProductA();
}
}
3. 抽象工厂模式(Abstract Factory)
- 定义: 提供一个创建一系列相关或依赖对象的接口,而无需指定具体类。
- 原理: 多个产品族的接口,多个工厂实现创建这些产品。
- 优点: 保证产品族的一致性,便于产品切换,隔离具体类。
- 应用场景: GUI 跨平台 UI 控件、数据库访问 API(切换数据库供应商)。
- 示例代码:
java
// 抽象产品接口
interface Button {
void paint();
}
// 具体产品
class WinButton implements Button {
public void paint() { System.out.println("Windows 按钮"); }
}
class MacButton implements Button {
public void paint() { System.out.println("Mac 按钮"); }
}
// 抽象工厂
interface GUIFactory {
Button createButton();
}
// 具体工厂
class WinFactory implements GUIFactory {
public Button createButton() { return new WinButton(); }
}
class MacFactory implements GUIFactory {
public Button createButton() { return new MacButton(); }
}
关于工厂方法模式和抽象工厂模式的区别,工厂方法模式关注单个对象的创建,而抽象工厂模式关注一系列相关产品的创建。详解可以看这篇文章:https://blog.csdn.net/Liu_y_xin/article/details/140571412。
4. 原型模式(Prototype)
- 定义: 使用已有对象复制出新对象,而非 new。
- 原理: 对象实现
Cloneable
接口并重写clone()
方法。 - 优点: 避免重复构造,提升性能,便于复杂对象快速复制。
- 应用场景: 对象池、大量对象创建(如游戏角色、地图元素)。
- 示例代码:
java
public class Document implements Cloneable {
private String content;
public Document(String content) {
this.content = content;
}
@Override
public Document clone() throws CloneNotSupportedException {
return (Document) super.clone();
}
public String getContent() {
return content;
}
}
5. 建造者模式(Builder)
- 定义: 将一个复杂对象的构建与它的表示分离,使构建过程可独立于表示。
- 原理: 使用链式 API 封装每一步设置,最终构造完整对象。
- 优点: 创建过程清晰、灵活,适合构造具有多个参数的对象。
- 应用场景: HTTP 请求构造、复杂对象配置、SQL 语句拼装。
- 示例代码:
java
public class User {
private String name;
private int age;
private String email;
// 私有构造
private User(Builder builder) {
this.name = builder.name;
this.age = builder.age;
this.email = builder.email;
}
public static class Builder {
private String name;
private int age;
private String email;
public Builder setName(String name) {
this.name = name; return this;
}
public Builder setAge(int age) {
this.age = age; return this;
}
public Builder setEmail(String email) {
this.email = email; return this;
}
public User build() {
return new User(this);
}
}
}
// 使用方式:
User user = new User.Builder()
.setName("Tom")
.setAge(30)
.setEmail("[email protected]")
.build();
三、结构型模式
1. 适配器模式(Adapter Pattern)
- 定义: 将一个类的接口转换成客户端期望的另一个接口。
- 原理: 通过组合(对象适配)或继承(类适配)方式进行接口适配。
- 优点: 实现系统间的解耦,复用已有类。
- 应用场景: 接入第三方 SDK、老接口改造、新旧系统兼容。
- 示例代码:
java
interface Target {
void request();
}
class Adaptee {
public void specificRequest() {
System.out.println("Adaptee 原始方法");
}
}
class Adapter implements Target {
private Adaptee adaptee = new Adaptee();
public void request() {
adaptee.specificRequest();
}
}
2. 装饰器模式(Decorator Pattern)
- 定义: 动态地为对象添加额外功能,而不改变其结构。
- 原理: 使用组合方式包装原对象,并在方法中前后增强。
- 优点: 比继承更灵活,支持行为增强,符合开闭原则。
- 应用场景: Java IO、日志增强、权限控制。
- 示例代码:
java
interface Component {
void operation();
}
class ConcreteComponent implements Component {
public void operation() {
System.out.println("基础操作");
}
}
class Decorator implements Component {
private Component component;
public Decorator(Component component) {
this.component = component;
}
public void operation() {
System.out.println("增强前");
component.operation();
System.out.println("增强后");
}
}
3. 代理模式(Proxy Pattern)
- 定义: 为其他对象提供一种代理以控制对它的访问。
- 原理: 使用代理类包装目标对象,控制其访问逻辑。
- 优点: 增强目标对象功能,控制访问权限,支持懒加载等。
- 应用场景: AOP、RPC 框架、缓存代理、安全控制。
- 示例代码:
java
interface Subject {
void request();
}
class RealSubject implements Subject {
public void request() {
System.out.println("真实请求");
}
}
class ProxySubject implements Subject {
private RealSubject realSubject = new RealSubject();
public void request() {
System.out.println("访问控制、权限校验");
realSubject.request();
}
}
4. 外观模式(Facade Pattern)
- 定义: 为子系统中的一组接口提供统一入口,简化使用。
- 原理: 封装复杂子系统的多个组件,统一暴露简单接口。
- 优点: 降低系统耦合、隐藏系统内部实现细节。
- 应用场景: Spring JdbcTemplate 封装 JDBC;系统集成平台。
- 示例代码:
java
class SubSystemA {
void stepA() { System.out.println("步骤 A"); }
}
class SubSystemB {
void stepB() { System.out.println("步骤 B"); }
}
class Facade {
private SubSystemA a = new SubSystemA();
private SubSystemB b = new SubSystemB();
public void operate() {
a.stepA();
b.stepB();
}
}
5. 桥接模式(Bridge Pattern)
- 定义: 将抽象与实现分离,使它们可以独立变化。
- 原理: 抽象类依赖于实现接口而不是具体实现,组合实现。
- 优点: 解耦抽象与实现,支持维度扩展。
- 应用场景: 不同设备和消息类型的组合场景。
- 示例代码:
java
// 发送消息的行为接口(实现部分的抽象),可以有多种实现方式,如邮件发送、短信发送等
interface MessageSender {
void send(String msg);
}
// 实现接口的具体类:邮件发送器
class EmailSender implements MessageSender {
public void send(String msg) {
System.out.println("发送邮件: " + msg);
}
}
// 抽象消息类(抽象部分的抽象),它持有一个 MessageSender 实例,桥接到发送实现部分
abstract class Message {
protected MessageSender sender; // 实现部分的引用
// 构造方法注入发送器实现(桥接实现)
public Message(MessageSender sender) {
this.sender = sender;
}
// 抽象方法:由具体子类实现具体的消息发送方式
public abstract void sendMessage(String msg);
}
// 扩展抽象类:文本消息,实际的业务逻辑放在这里,而非 EmailSender 中
class TextMessage extends Message {
// 构造时指定使用的消息发送方式(如 EmailSender)
public TextMessage(MessageSender sender) {
super(sender);
}
// 实现抽象方法:发送文本消息,实质上调用的是桥接的 sender
public void sendMessage(String msg) {
sender.send(msg);
}
}
6. 组合模式(Composite Pattern)
- 定义: 将对象组合成树形结构以表示部分-整体层次。
- 原理: 统一叶子节点与容器节点接口,递归处理结构。
- 优点: 客户端操作一致,支持递归遍历。
- 应用场景: 文件系统、组织架构树、菜单结构。
- 示例代码:
java
interface Component {
void display();
}
class Leaf implements Component {
private String name;
public Leaf(String name) { this.name = name; }
public void display() { System.out.println("叶子: " + name); }
}
class Composite implements Component {
private List<Component> children = new ArrayList<>();
private String name;
public Composite(String name) { this.name = name; }
public void add(Component c) { children.add(c); }
public void display() {
System.out.println("组合节点: " + name);
for (Component c : children) c.display();
}
}
7. 享元模式(Flyweight Pattern)
- 定义: 通过共享技术有效支持大量细粒度对象的复用。
- 原理: 分离内在状态(共享)与外在状态(调用时传入),使用工厂控制对象复用。
- 优点: 减少内存使用,提高系统性能。
- 应用场景: 字符串常量池、数据库连接池、线程池。
- 示例代码:
java
class Flyweight {
private String intrinsic;
public Flyweight(String intrinsic) {
this.intrinsic = intrinsic;
}
public void operate(String extrinsic) {
System.out.println("共享对象: " + intrinsic + ",外部状态: " + extrinsic);
}
}
class FlyweightFactory {
private static final Map<String, Flyweight> pool = new HashMap<>();
public static Flyweight getFlyweight(String key) {
return pool.computeIfAbsent(key, k -> new Flyweight(k));
}
}
四、行为型模式
1. 策略模式(Strategy Pattern)
- 定义: 定义一系列算法,将每个算法封装起来,使它们可以互换。
- 原理: 将算法抽象为接口,运行时注入不同实现。
- 优点: 解耦算法选择逻辑,符合开闭原则。
- 应用场景: 支付策略、排序策略、日志策略。
- 示例代码:
java
// 抽象策略接口:定义统一的操作方法,所有具体策略类都需要实现这个接口
interface Strategy {
int doOperation(int a, int b);
}
// 具体策略类:加法实现
class Add implements Strategy {
// 实现策略方法:执行加法运算
public int doOperation(int a, int b) {
return a + b;
}
}
// 上下文类:用于持有并调用某个策略对象
class Context {
private Strategy strategy; // 当前使用的策略对象(即算法实现)
// 构造方法注入策略,实现运行时策略切换
public Context(Strategy strategy) {
this.strategy = strategy;
}
// 执行策略封装的方法,具体行为由传入的策略对象决定
public int execute(int a, int b) {
return strategy.doOperation(a, b);
}
}
使用示例:
java
public class Main {
public static void main(String[] args) {
Strategy addStrategy = new Add(); // 创建加法策略
Context context = new Context(addStrategy); // 注入策略到上下文
int result = context.execute(10, 5); // 执行策略方法
System.out.println("结果:" + result); // 输出:结果:15
}
}
2. 模板方法模式(Template Method)
- 定义: 定义一个操作中算法的骨架,将一些步骤延迟到子类中。
- 原理: 抽象类定义流程,子类实现具体步骤。
- 优点: 复用公共代码,子类灵活扩展部分行为。
- 应用场景: JDBC Template、测试框架。
- 示例代码:
java
abstract class AbstractClass {
public final void execute() {
step1(); step2();
}
protected abstract void step1();
protected abstract void step2();
}
class SubClass extends AbstractClass {
protected void step1() { System.out.println("步骤1"); }
protected void step2() { System.out.println("步骤2"); }
}
3. 观察者模式(Observer)
- 定义: 当对象状态发生变化时,自动通知依赖它的对象。
- 原理: 被观察者维护观察者列表,状态变更时遍历调用。
- 优点: 实现一对多依赖,松耦合。
- 应用场景: 事件监听器、发布订阅系统。
- 示例代码:
java
interface Observer {
void update(String msg);
}
class ConcreteObserver implements Observer {
public void update(String msg) {
System.out.println("收到消息: " + msg);
}
}
class Subject {
private List<Observer> observers = new ArrayList<>();
public void attach(Observer o) { observers.add(o); }
public void notifyAll(String msg) {
for (Observer o : observers) o.update(msg);
}
}
4. 责任链模式(Chain of Responsibility)
- 定义: 将请求沿处理者链传递,直到有对象处理它。
- 原理: 每个处理器包含对下一个处理器的引用。
- 优点: 请求发送者与接收者解耦。
- 应用场景: Servlet Filter、审批流。
- 示例代码:
java
// 抽象处理器类:定义责任链的基础结构
abstract class Handler {
// 持有下一个处理器的引用,实现链式传递
protected Handler next;
// 设置下一个处理器(链条的连接点)
public void setNext(Handler next) {
this.next = next;
}
// 抽象处理方法,交由子类实现具体逻辑
public abstract void handle(String request);
}
// 具体处理器:进行权限校验处理
class AuthHandler extends Handler {
@Override
public void handle(String request) {
// 执行本处理器的逻辑:权限校验
System.out.println("权限校验");
// 如果有下一个处理器,则传递请求
if (next != null) {
next.handle(request);
}
}
}
5. 状态模式(State Pattern)
- 定义: 允许对象在状态变化时改变行为。
- 原理: 将状态封装成类,并在环境类中切换。
- 优点: 避免大量 if-else,提高状态切换可维护性。
- 应用场景: 工作流引擎、订单流程控制。
- 示例代码:
java
interface State {
void handle();
}
class StartState implements State {
public void handle() { System.out.println("开始状态"); }
}
class Context {
private State state;
public void setState(State state) { this.state = state; }
public void request() { state.handle(); }
}
6. 命令模式(Command Pattern)
- 定义: 将请求封装成对象,支持参数化与撤销操作。
- 原理: 将调用者与执行者解耦,封装命令对象。
- 优点: 支持操作记录、撤销、事务。
- 应用场景: 操作日志、菜单命令、事务控制。
- 示例代码:
java
interface Command {
void execute();
}
class Receiver {
public void action() { System.out.println("执行操作"); }
}
class ConcreteCommand implements Command {
private Receiver receiver;
public ConcreteCommand(Receiver r) { this.receiver = r; }
public void execute() { receiver.action(); }
}
7. 迭代器模式(Iterator Pattern)
- 定义: 提供一种顺序访问集合元素的方法。
- 原理: 将迭代逻辑与集合对象解耦。
- 优点: 简化集合遍历逻辑。
- 应用场景: Java 集合框架中的 Iterator。
- 示例代码:
java
Iterator<String> it = list.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
8. 中介者模式(Mediator Pattern)
- 定义: 用中介对象封装对象交互,避免对象间过度耦合。
- 原理: 统一交互协调者,所有交互通过中介进行。
- 优点: 降低类之间的依赖,简化对象协作。
- 应用场景: GUI 控件交互、聊天系统。
- 示例代码:
java
interface Mediator {
void notify(String event);
}
class Button {
private Mediator mediator;
public Button(Mediator m) { this.mediator = m; }
public void click() { mediator.notify("click"); }
}
9. 备忘录模式(Memento Pattern)
- 定义: 保存对象的内部状态,以便恢复。
- 原理: 状态快照保存于 Memento 对象中。
- 优点: 实现撤销回滚,不破坏封装。
- 应用场景: 编辑器撤销、事务恢复。
- 示例代码:
java
class Memento {
private String state;
public Memento(String state) { this.state = state; }
public String getState() { return state; }
}
class Originator {
private String state;
public void setState(String state) { this.state = state; }
public Memento save() { return new Memento(state); }
public void restore(Memento m) { state = m.getState(); }
}
10. 解释器模式(Interpreter Pattern)
- 定义: 定义语言的文法,并构建解释器解释语句。
- 原理: 使用抽象语法树(AST)递归解释结构。
- 优点: 可扩展语言规则,易于实现 DSL。
- 应用场景: 表达式求值器、SQL解析器。
- 示例代码:
java
interface Expression {
int interpret();
}
class Number implements Expression {
private int value;
public Number(int value) { this.value = value; }
public int interpret() { return value; }
}
11. 访问者模式(Visitor Pattern)
- 定义: 在不修改对象结构的前提下定义新的操作。
- 原理: 将操作抽离成访问者类,由元素结构接纳执行。
- 优点: 增加新操作易于扩展,符合开闭原则。
- 应用场景: 编译器 AST、对象结构分析。
- 示例代码:
java
interface Visitor {
void visit(ElementA e);
}
interface Element {
void accept(Visitor v);
}
class ElementA implements Element {
public void accept(Visitor v) { v.visit(this); }
}
。
- 优点: 可扩展语言规则,易于实现 DSL。
- 应用场景: 表达式求值器、SQL解析器。
- 示例代码:
java
interface Expression {
int interpret();
}
class Number implements Expression {
private int value;
public Number(int value) { this.value = value; }
public int interpret() { return value; }
}
11. 访问者模式(Visitor Pattern)
- 定义: 在不修改对象结构的前提下定义新的操作。
- 原理: 将操作抽离成访问者类,由元素结构接纳执行。
- 优点: 增加新操作易于扩展,符合开闭原则。
- 应用场景: 编译器 AST、对象结构分析。
- 示例代码:
java
interface Visitor {
void visit(ElementA e);
}
interface Element {
void accept(Visitor v);
}
class ElementA implements Element {
public void accept(Visitor v) { v.visit(this); }
}