Java常见的23种设计模式

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); }
}
相关推荐
只会AI搜索得coder2 分钟前
sqlite3 sqlcipher加密,解密,集成springboot,读取sqlcipher加密工具
java·spring boot·sqlite
NetX行者12 分钟前
详解正则表达式中的?:、?= 、 ?! 、?<=、?<!
开发语言·前端·javascript·正则表达式
流云一号14 分钟前
Python实现贪吃蛇三
开发语言·前端·python
小白教程16 分钟前
如何处理Python爬取视频时的反爬机制?
开发语言·python·音视频·python爬虫
LIUDAN'S WORLD32 分钟前
C++零基础实践教程 函数 数组、字符串与 Vector
开发语言·c++·算法
cg501733 分钟前
Spring Boot 中的自动配置原理
java·前端·数据库
热爱编程的OP39 分钟前
Numpy常用库方法总结
开发语言·python·numpy
cliffordl1 小时前
ReportLab 导出 PDF(文档创建)
开发语言·python·pdf
纪元A梦1 小时前
华为OD机试真题——跳格子3(2025A卷:200分)Java/python/JavaScript/C++/C语言/GO六种最佳实现
java·javascript·c++·python·华为od·go·华为od机试题
水w1 小时前
【Python爬虫】简单案例介绍2
开发语言·爬虫·python