【设计模式】一文掌握11种行为型设计模式:3W学习法 + Java实战 + 开源框架解析

Scroll Down

一文掌握行为型模式 —— 3W 学习法总结 + Java 实战

设计模式是软件开发的精髓,行为型模式(Behavioral Patterns)关注对象之间的交互和职责分配。本文将用 3W 学习法(What、Why、How)系统总结 行为型模式,结合 UML 图、Java 代码示例开源框架实战,帮助你真正掌握这些模式。


1. 策略模式(Strategy Pattern)

🟢 What:是什么?

策略模式定义了一组算法,将它们封装起来,使它们可以互换,客户端可以动态选择不同的算法执行逻辑。

🔴 Why:为什么需要?

  • 避免 if-elseswitch-case 代码臃肿。
  • 允许运行时动态更换策略,提高灵活性。

🟡 How:如何实现?

UML 类图

+----------------+         +----------------+
|   Context      |         |  Strategy      |
|---------------|         |----------------|
| strategy:Strategy |<>----| +algorithm()  |
| +setStrategy()|         |----------------|
+----------------+         +----------------+
           |
           |  implements
           v
+-----------------+   +-----------------+
|  ConcreteStrategyA |   |  ConcreteStrategyB |
|-----------------|   |-----------------|
| +algorithm()    |   | +algorithm()    |
+-----------------+   +-----------------+

Java 代码示例

// 策略接口
interface Strategy {
    void execute();
}

// 具体策略 A
class ConcreteStrategyA implements Strategy {
    public void execute() {
        System.out.println("执行策略 A");
    }
}

// 具体策略 B
class ConcreteStrategyB implements Strategy {
    public void execute() {
        System.out.println("执行策略 B");
    }
}

// 上下文
class Context {
    private Strategy strategy;
    public void setStrategy(Strategy strategy) { this.strategy = strategy; }
    public void executeStrategy() { strategy.execute(); }
}

// 测试
public class StrategyPatternDemo {
    public static void main(String[] args) {
        Context context = new Context();
        context.setStrategy(new ConcreteStrategyA());
        context.executeStrategy();  // 输出:执行策略 A

        context.setStrategy(new ConcreteStrategyB());
        context.executeStrategy();  // 输出:执行策略 B
    }
}

🌍 在开源框架中的应用

  • Spring:Spring 的 Resource 解析器使用策略模式,如 FileSystemResourceClassPathResource
  • JDKComparator 也是策略模式的体现,如 Collections.sort(list, comparator)

2. 观察者模式(Observer Pattern)

🟢 What:是什么?

观察者模式定义了对象间的一对多依赖关系,当一个对象状态改变时,所有依赖它的对象都会收到通知并自动更新。

🔴 Why:为什么需要?

  • 解耦主题(Subject)与观察者(Observer)。
  • 广泛用于事件驱动编程,如 GUI 事件监听、消息推送。

🟡 How:如何实现?

UML 类图

+---------------+
| Subject       |
|---------------|
| +attach()     |
| +detach()     |
| +notify()     |
+---------------+
       |
       |  implements
       v
+---------------+          +----------------+
| ConcreteSubject |<>------|  Observer      |
|---------------|          |----------------|
| state         |          | +update()      |
+---------------+          +----------------+
                                      |
                                      | implements
                                      v
                      +------------------------+
                      | ConcreteObserver        |
                      |------------------------|
                      | +update()               |
                      +------------------------+

Java 代码示例

import java.util.*;

// 观察者接口
interface Observer {
    void update(String message);
}

// 具体观察者
class ConcreteObserver implements Observer {
    private String name;
    public ConcreteObserver(String name) { this.name = name; }
    public void update(String message) {
        System.out.println(name + " 收到通知:" + message);
    }
}

// 主题
class Subject {
    private List<Observer> observers = new ArrayList<>();
    public void attach(Observer observer) { observers.add(observer); }
    public void detach(Observer observer) { observers.remove(observer); }
    public void notifyObservers(String message) {
        for (Observer observer : observers) {
            observer.update(message);
        }
    }
}

// 测试
public class ObserverPatternDemo {
    public static void main(String[] args) {
        Subject subject = new Subject();
        Observer obs1 = new ConcreteObserver("Observer A");
        Observer obs2 = new ConcreteObserver("Observer B");
        subject.attach(obs1);
        subject.attach(obs2);
        subject.notifyObservers("Hello, World!"); 
        // 输出:
        // Observer A 收到通知:Hello, World!
        // Observer B 收到通知:Hello, World!
    }
}

🌍 在开源框架中的应用

  • Spring:Spring 事件监听机制 ApplicationListener 采用观察者模式。
  • RxJava:ReactiveX 的 Observer 设计符合观察者模式。

3. 责任链模式(Chain of Responsibility)

🟢 What:是什么?

责任链模式允许多个对象处理请求,每个对象可以选择处理请求或传递给下一个处理者。

🔴 Why:为什么需要?

  • 提高系统灵活性,请求发送方无需关注处理者的具体执行逻辑。
  • 适用于拦截器、过滤器等场景。

🟡 How:如何实现?

UML 类图

+---------------+
| Handler       |
|---------------|
| +setNext()    |
| +handle()     |
+---------------+
       |
       |  implements
       v
+-----------------+     +-----------------+
| ConcreteHandlerA | --> | ConcreteHandlerB |
|-----------------|     |-----------------|
| +handle()       |     | +handle()       |
+-----------------+     +-----------------+

Java 代码示例

// 处理者接口
abstract class Handler {
    protected Handler next;
    public void setNext(Handler next) { this.next = next; }
    public abstract void handleRequest(int level);
}

// 具体处理者A
class HandlerA extends Handler {
    public void handleRequest(int level) {
        if (level < 5) {
            System.out.println("HandlerA 处理请求");
        } else if (next != null) {
            next.handleRequest(level);
        }
    }
}

// 具体处理者B
class HandlerB extends Handler {
    public void handleRequest(int level) {
        System.out.println("HandlerB 处理请求");
    }
}

// 测试
public class ChainPatternDemo {
    public static void main(String[] args) {
        Handler handlerA = new HandlerA();
        Handler handlerB = new HandlerB();
        handlerA.setNext(handlerB);
        
        handlerA.handleRequest(3);  // HandlerA 处理请求
        handlerA.handleRequest(8);  // HandlerB 处理请求
    }
}

🌍 在开源框架中的应用

  • Spring MVCHandlerInterceptor 实现请求处理链。
  • Java ServletFilterChain 采用责任链模式。

4. 命令模式(Command Pattern)

🟢 What:是什么?

命令模式将请求封装为对象,使得请求发送者和请求执行者解耦,并支持请求的存储、撤销、恢复等操作。

🔴 Why:为什么需要?

  • 解耦请求的发送者和执行者,方便扩展和修改。
  • 支持 撤销(undo)、重做(redo) 机制。

🟡 How:如何实现?

UML 类图

+---------------+
| Command      |
|---------------|
| +execute()   |
+---------------+
      ^
      |
+----------------+    +----------------+
| ConcreteCommand |    | Receiver       |
|----------------|    |----------------|
| - receiver    |---->| +action()      |
| +execute()    |    +----------------+
+----------------+
      |
      v
+---------------+
| Invoker      |
|---------------|
| +setCommand()|
| +invoke()    |
+---------------+

Java 代码示例

// 命令接口
interface Command {
    void execute();
}

// 具体命令
class LightOnCommand implements Command {
    private Light light;
    public LightOnCommand(Light light) { this.light = light; }
    public void execute() { light.turnOn(); }
}

// 具体命令
class LightOffCommand implements Command {
    private Light light;
    public LightOffCommand(Light light) { this.light = light; }
    public void execute() { light.turnOff(); }
}

// 接收者
class Light {
    public void turnOn() { System.out.println("灯打开了"); }
    public void turnOff() { System.out.println("灯关闭了"); }
}

// 调用者
class RemoteControl {
    private Command command;
    public void setCommand(Command command) { this.command = command; }
    public void pressButton() { command.execute(); }
}

// 测试
public class CommandPatternDemo {
    public static void main(String[] args) {
        Light light = new Light();
        Command lightOn = new LightOnCommand(light);
        Command lightOff = new LightOffCommand(light);

        RemoteControl remote = new RemoteControl();
        remote.setCommand(lightOn);
        remote.pressButton();  // 输出:灯打开了

        remote.setCommand(lightOff);
        remote.pressButton();  // 输出:灯关闭了
    }
}

🌍 在开源框架中的应用

  • Spring:Spring 的 TransactionTemplate 事务管理本质上是命令模式。
  • JDKRunnablerun() 方法也是命令模式的体现。

5. 模板方法模式(Template Method Pattern)

🟢 What:是什么?

模板方法模式定义一个算法的框架,将具体实现延迟到子类。

🔴 Why:为什么需要?

  • 代码复用,避免重复实现通用逻辑。
  • 保证执行步骤的一致性。

🟡 How:如何实现?

UML 类图

+-----------------+
| AbstractClass   |
|-----------------|
| +templateMethod() |
| +primitiveOperation1() |
| +primitiveOperation2() |
+-----------------+
      |
      v
+-----------------+
| ConcreteClass   |
|-----------------|
| +primitiveOperation1() |
| +primitiveOperation2() |
+-----------------+

Java 代码示例

// 抽象类
abstract class Game {
    abstract void initialize();
    abstract void startPlay();
    abstract void endPlay();

    // 模板方法
    public final void play() {
        initialize();
        startPlay();
        endPlay();
    }
}

// 具体类
class Football extends Game {
    void initialize() { System.out.println("足球比赛初始化"); }
    void startPlay() { System.out.println("足球比赛开始"); }
    void endPlay() { System.out.println("足球比赛结束"); }
}

// 测试
public class TemplateMethodDemo {
    public static void main(String[] args) {
        Game game = new Football();
        game.play();
    }
}

🌍 在开源框架中的应用

  • SpringJdbcTemplate 使用模板方法封装数据库操作。
  • JUnit@Before@After 也是模板方法模式的体现。

6. 状态模式(State Pattern)

🟢 What:是什么?

状态模式允许对象在 不同状态 下表现出不同的行为,状态转换由对象本身控制。

🔴 Why:为什么需要?

  • 解决大量 if-else 状态判断问题。
  • 使状态切换更加直观和可扩展。

🟡 How:如何实现?

UML 类图

+-----------------+
| Context        |
|-----------------|
| state: State   |
| +setState()    |
| +request()     |
+-----------------+
      |
      v
+-----------------+
| State          |
|-----------------|
| +handle()      |
+-----------------+
      |
      v
+-----------------+   +-----------------+
| ConcreteStateA  |   | ConcreteStateB  |
|-----------------|   |-----------------|
| +handle()      |   | +handle()       |
+-----------------+   +-----------------+

Java 代码示例

// 状态接口
interface State {
    void handle(Context context);
}

// 具体状态 A
class StateA implements State {
    public void handle(Context context) {
        System.out.println("当前状态:A,切换到 B");
        context.setState(new StateB());
    }
}

// 具体状态 B
class StateB implements State {
    public void handle(Context context) {
        System.out.println("当前状态:B,切换到 A");
        context.setState(new StateA());
    }
}

// 上下文
class Context {
    private State state;
    public Context(State state) { this.state = state; }
    public void setState(State state) { this.state = state; }
    public void request() { state.handle(this); }
}

// 测试
public class StatePatternDemo {
    public static void main(String[] args) {
        Context context = new Context(new StateA());
        context.request(); // 当前状态:A,切换到 B
        context.request(); // 当前状态:B,切换到 A
    }
}

🌍 在开源框架中的应用

  • Spring:Spring 的 StateMachine 框架用于实现状态机模式。
  • Java NIOChannelOPENCLOSED 状态间切换。

7. 备忘录模式(Memento Pattern)

🟢 What:是什么?

备忘录模式用于保存对象的 快照,允许在未来恢复对象的状态。

🔴 Why:为什么需要?

  • 实现 撤销(Undo)恢复(Redo) 机制。
  • 保护对象封装性,防止外部直接访问内部状态。

🟡 How:如何实现?

UML 类图

+-----------------+
| Originator      |    负责创建备忘录并恢复状态
|-----------------|
| +createMemento()|
| +restore()      |
+-----------------+
      |
      v
+-----------------+
| Memento        |    备忘录对象,存储 Originator 的状态
|-----------------|
| -state         |
| +getState()    |
+-----------------+
      |
      v
+-----------------+
| CareTaker      |    备忘录管理者,负责存储多个备忘录
|-----------------|
| +addMemento()  |
| +getMemento()  |
+-----------------+

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 saveState() { return new Memento(state); }
    public void restoreState(Memento memento) { this.state = memento.getState(); }
    public void showState() { System.out.println("当前状态:" + state); }
}

// 备忘录管理者
class CareTaker {
    private List<Memento> history = new ArrayList<>();
    public void addMemento(Memento memento) { history.add(memento); }
    public Memento getMemento(int index) { return history.get(index); }
}

// 测试
public class MementoPatternDemo {
    public static void main(String[] args) {
        Originator originator = new Originator();
        CareTaker careTaker = new CareTaker();

        originator.setState("状态1");
        careTaker.addMemento(originator.saveState());

        originator.setState("状态2");
        careTaker.addMemento(originator.saveState());

        originator.setState("状态3");

        originator.showState(); // 当前状态:状态3

        // 恢复到状态1
        originator.restoreState(careTaker.getMemento(0));
        originator.showState(); // 当前状态:状态1
    }
}

🌍 在开源框架中的应用

  • IDE:IntelliJ IDEA 的 撤销(Ctrl+Z) 功能。
  • 数据库事务:MySQL binlog 记录状态。

8. 迭代器模式(Iterator Pattern)

🟢 What:是什么?

迭代器模式用于顺序访问 集合内部元素,而不暴露集合内部结构。

🔴 Why:为什么需要?

  • 统一遍历方式,避免使用 forwhile 操作集合。
  • 支持 多种遍历策略(如正序、倒序)。

🟡 How:如何实现?

UML 类图

+-----------------+
| Iterator       |    迭代器接口
|-----------------|
| +hasNext()     |
| +next()        |
+-----------------+
      |
      v
+-----------------+
| ConcreteIterator|    具体迭代器
|-----------------|
| -list          |
| -index         |
+-----------------+
      |
      v
+-----------------+
| Aggregate      |    集合接口
|-----------------|
| +createIterator() |
+-----------------+
      |
      v
+-----------------+
| ConcreteAggregate |  具体集合
|-----------------|
| -list          |
+-----------------+

Java 代码示例

// 迭代器接口
interface Iterator<T> {
    boolean hasNext();
    T next();
}

// 具体迭代器
class ConcreteIterator<T> implements Iterator<T> {
    private List<T> list;
    private int index = 0;

    public ConcreteIterator(List<T> list) { this.list = list; }

    public boolean hasNext() { return index < list.size(); }
    public T next() { return list.get(index++); }
}

// 集合接口
interface Aggregate<T> {
    Iterator<T> createIterator();
}

// 具体集合
class ConcreteAggregate<T> implements Aggregate<T> {
    private List<T> list = new ArrayList<>();
    public void add(T element) { list.add(element); }
    public Iterator<T> createIterator() { return new ConcreteIterator<>(list); }
}

// 测试
public class IteratorPatternDemo {
    public static void main(String[] args) {
        ConcreteAggregate<String> collection = new ConcreteAggregate<>();
        collection.add("A");
        collection.add("B");
        collection.add("C");

        Iterator<String> iterator = collection.createIterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());  // 输出:A B C
        }
    }
}

🌍 在开源框架中的应用

  • JDKIterator<T> 遍历 ListSetMap
  • SpringBeanFactory 内部迭代 Bean 定义。

9. 访问者模式(Visitor Pattern)

🟢 What:是什么?

访问者模式用于 分离对象数据结构和操作行为,即 “数据 + 操作” 分离

🔴 Why:为什么需要?

  • 解耦数据结构与操作,方便扩展新操作。
  • 适用于 结构稳定但操作多变 的场景。

🟡 How:如何实现?

UML 类图

+-----------------+
| Visitor        |    访问者接口
|-----------------|
| +visitElementA()|
| +visitElementB()|
+-----------------+
      |
      v
+-----------------+
| ConcreteVisitor|    具体访问者
|-----------------|
| +visitElementA()|
| +visitElementB()|
+-----------------+
      |
      v
+-----------------+
| Element        |    元素接口
|-----------------|
| +accept()      |
+-----------------+
      |
      v
+-----------------+
| ConcreteElementA|  具体元素
|-----------------|
| +accept()      |
+-----------------+

Java 代码示例

// 访问者接口
interface Visitor {
    void visit(ElementA element);
    void visit(ElementB element);
}

// 具体访问者
class ConcreteVisitor implements Visitor {
    public void visit(ElementA element) { System.out.println("访问元素 A"); }
    public void visit(ElementB element) { System.out.println("访问元素 B"); }
}

// 元素接口
interface Element {
    void accept(Visitor visitor);
}

// 具体元素 A
class ElementA implements Element {
    public void accept(Visitor visitor) { visitor.visit(this); }
}

// 具体元素 B
class ElementB implements Element {
    public void accept(Visitor visitor) { visitor.visit(this); }
}

// 测试
public class VisitorPatternDemo {
    public static void main(String[] args) {
        Visitor visitor = new ConcreteVisitor();
        Element a = new ElementA();
        Element b = new ElementB();
        a.accept(visitor);
        b.accept(visitor);
    }
}

🌍 在开源框架中的应用

  • ASM:JVM 字节码解析访问器。
  • Spring AOPMethodInterceptor 访问 JoinPoint

10. 中介者模式(Mediator Pattern)

🟢 What:是什么?

中介者模式是一种 对象行为型模式,用于 封装对象之间的交互,避免对象之间的直接引用。

🔴 Why:为什么需要?

  • 避免对象之间 紧耦合,降低系统复杂度。
  • 让对象间的交互 集中到一个中介者中,提高扩展性和可维护性。

🟡 How:如何实现?

UML 类图

+----------------+
| Mediator      |    抽象中介者
|---------------|
| +send()       |
+----------------+
      ▲
      │
+--------------------+
| ConcreteMediator |    具体中介者
|--------------------|
| +register()       |
| +send()           |
+--------------------+
    ▲      ▲
    │      │
+-------------+   +-------------+
| ColleagueA  |   | ColleagueB  |   具体同事类
|-------------|   |-------------|
| +send()     |   | +send()     |
| +receive()  |   | +receive()  |
+-------------+   +-------------+

Java 代码实战

// 抽象中介者
interface Mediator {
    void send(String message, Colleague colleague);
}

// 具体中介者
class ConcreteMediator implements Mediator {
    private ColleagueA colleagueA;
    private ColleagueB colleagueB;

    public void registerColleagueA(ColleagueA colleague) { this.colleagueA = colleague; }
    public void registerColleagueB(ColleagueB colleague) { this.colleagueB = colleague; }

    public void send(String message, Colleague sender) {
        if (sender == colleagueA) {
            colleagueB.receive(message);
        } else {
            colleagueA.receive(message);
        }
    }
}

// 抽象同事类
abstract class Colleague {
    protected Mediator mediator;
    public Colleague(Mediator mediator) { this.mediator = mediator; }
}

// 具体同事类 A
class ColleagueA extends Colleague {
    public ColleagueA(Mediator mediator) { super(mediator); }
    public void send(String message) { mediator.send(message, this); }
    public void receive(String message) { System.out.println("A 收到消息:" + message); }
}

// 具体同事类 B
class ColleagueB extends Colleague {
    public ColleagueB(Mediator mediator) { super(mediator); }
    public void send(String message) { mediator.send(message, this); }
    public void receive(String message) { System.out.println("B 收到消息:" + message); }
}

// 测试
public class MediatorPatternDemo {
    public static void main(String[] args) {
        ConcreteMediator mediator = new ConcreteMediator();
        ColleagueA a = new ColleagueA(mediator);
        ColleagueB b = new ColleagueB(mediator);

        mediator.registerColleagueA(a);
        mediator.registerColleagueB(b);

        a.send("你好,B!");
        b.send("你好,A!");
    }
}

🌍 在开源框架中的应用

  • Spring MVCDispatcherServlet 作为中介者,协调 Controller、View 之间的交互。
  • NettyChannelPipeline 作为中介者管理多个 ChannelHandler 组件。

11. 解释器模式(Interpreter Pattern)

🟢 What:是什么?

解释器模式用于 设计自定义语言、表达式,提供一种解释这些语言的方式。

🔴 Why:为什么需要?

  • 用于构建 简单的脚本引擎、数学表达式解析
  • 解耦解析逻辑,避免 if-else 逻辑复杂度。

🟡 How:如何实现?

UML 类图

+----------------+
| AbstractExpression | 抽象表达式
|----------------|
| +interpret()   |
+----------------+
      ▲
      │
+---------------+  +---------------+
| TerminalExpr  |  | NonTerminalExpr |  终结表达式 & 非终结表达式
|---------------|  |---------------|
| +interpret()  |  | +interpret()  |
+---------------+  +---------------+

Java 代码实战

import java.util.*;

// 抽象表达式
interface Expression {
    int interpret(Map<String, Integer> context);
}

// 变量表达式(终结符表达式)
class VariableExpression implements Expression {
    private String name;
    public VariableExpression(String name) { this.name = name; }
    public int interpret(Map<String, Integer> context) { return context.getOrDefault(name, 0); }
}

// 加法表达式(非终结符表达式)
class AddExpression implements Expression {
    private Expression left, right;
    public AddExpression(Expression left, Expression right) {
        this.left = left;
        this.right = right;
    }
    public int interpret(Map<String, Integer> context) {
        return left.interpret(context) + right.interpret(context);
    }
}

// 减法表达式(非终结符表达式)
class SubtractExpression implements Expression {
    private Expression left, right;
    public SubtractExpression(Expression left, Expression right) {
        this.left = left;
        this.right = right;
    }
    public int interpret(Map<String, Integer> context) {
        return left.interpret(context) - right.interpret(context);
    }
}

// 测试
public class InterpreterPatternDemo {
    public static void main(String[] args) {
        // 解析表达式:a + b - c
        Expression a = new VariableExpression("a");
        Expression b = new VariableExpression("b");
        Expression c = new VariableExpression("c");

        Expression add = new AddExpression(a, b);
        Expression subtract = new SubtractExpression(add, c);

        // 变量赋值
        Map<String, Integer> context = new HashMap<>();
        context.put("a", 5);
        context.put("b", 3);
        context.put("c", 2);

        System.out.println("计算结果:" + subtract.interpret(context));  // 输出:6
    }
}

🌍 在开源框架中的应用

  • Spring Expression Language(SpEL):支持 #{bean.method()} 解析。
  • ANTLR:Java 解析器框架,用于构建 DSL 语言解析器。

总结

以下是 11种行为型设计模式 的对比分析:

模式 定义 目标 优点 缺点 应用场景
策略模式 定义一系列算法,允许在运行时选择其中一个。 解耦算法和使用者,支持算法的动态替换。 便于扩展新的算法,符合开闭原则。 可能导致大量的策略类,增加系统复杂度。 需要在不同条件下使用不同算法的场景,例如支付方式选择。
模板方法模式 定义算法的骨架,将一些步骤延迟到子类实现。 保证算法结构不变,将变化的部分抽象成方法。 提高代码复用,方便子类扩展。 子类无法改变算法的结构,存在一定的限制。 数据处理、文件解析等通用算法框架。
责任链模式 将请求沿着处理链传递,直到有对象处理该请求为止。 动态地将请求传递给处理链中的对象,解耦发送者与接收者。 责任分担清晰,灵活可扩展,符合开闭原则。 增加新的责任对象时,可能导致链条过长,影响性能。 事件处理、权限检查、日志管理等。
命令模式 将请求封装为对象,从而使用户可以用不同的请求对客户进行参数化。 将请求和执行者解耦,能够动态地处理请求。 解耦请求与处理者,支持命令撤销和重做。 会增加系统中命令类的数量。 GUI 按钮的事件处理,事务管理等。
观察者模式 定义对象间的一对多依赖关系,一个对象状态发生变化时,所有依赖者都会收到通知并自动更新。 解耦被观察者与观察者之间的关系,通知机制。 可以灵活的添加和删除观察者,符合开闭原则。 可能导致系统中多次的更新通知,性能问题。 UI 更新、订阅-发布模型、事件监听等。
状态模式 当一个对象的内部状态改变时,它的行为也随之改变。 解耦状态变化对对象行为的影响。 简化复杂条件语句,易于扩展新的状态。 会导致状态类增多,系统复杂度提高。 游戏状态管理、工作流引擎等。
备忘录模式 保存对象的状态,以便在需要时恢复。 实现对象的状态恢复,保证封装性。 可以恢复到某个历史状态,易于实现撤销操作。 存储多个历史状态会占用内存,可能导致存储开销。 编辑器撤销操作、数据库事务、恢复操作等。
迭代器模式 提供一种顺序访问集合元素的方法,而不暴露集合的内部表示。 统一遍历方式,避免外部代码直接操作集合。 可以遍历任何类型的集合,增加遍历方式的灵活性。 遍历时无法直接操作集合数据,可能增加系统的复杂度。 集合遍历、数据库记录操作等。
访问者模式 为对象结构中的元素定义新的操作,而不改变元素的类。 解耦对象结构与操作的实现。 方便对已有元素进行扩展操作,符合开闭原则。 需要提前定义好所有操作,增加了扩展操作的复杂度。 需要对类进行不同操作的场景,如编译器、解析器等。
中介者模式 通过一个中介对象来解耦多个对象之间的交互。 降低对象间的耦合度,集中管理交互逻辑。 易于管理对象之间的复杂交互关系,符合开闭原则。 中介者可能变得过于庞大,成为系统的瓶颈。 组件之间需要协作的场景,如消息系统、事件管理等。
解释器模式 设计一个解释器来解释表达式的语法规则,并计算其结果。 提供一个表达式的解释框架,适用于简单语言的解析。 支持复杂表达式解析,便于扩展新的语法规则。 处理性能可能较低,适合于简单表达式的场景。 计算机语言、正则表达式、SQL查询等解析。

对比总结

  • 设计复杂度:如 状态模式访问者模式 相对复杂,可能需要更多的类和结构。其他如 策略模式模板方法模式 相对简单易理解。
  • 应用范围:某些模式如 观察者模式迭代器模式 在日常开发中应用广泛,尤其是在 事件驱动集合遍历 中。其他如 解释器模式备忘录模式 适用场景较窄,更多用于特殊需求。
  • 扩展性:大多数行为型模式都符合 开闭原则,如 策略模式访问者模式命令模式,这些模式便于扩展新功能。

通过这些对比,开发者可以根据具体需求选择合适的模式来应对系统中的复杂行为。

至此,我们完整总结了 行为型模式的 11 种模式,并提供了 UML、Java 代码实战、开源框架应用

  1. 策略模式:Spring BeanFactory
  2. 模板方法模式:Spring JdbcTemplate
  3. 责任链模式:Servlet FilterChain
  4. 命令模式:Spring TransactionCommand
  5. 观察者模式:Spring ApplicationListener
  6. 状态模式:Spring StateMachine
  7. 备忘录模式:IDE 撤销
  8. 迭代器模式:JDK Iterator
  9. 访问者模式:Spring AOP
  10. 中介者模式:Spring MVC DispatcherServlet
  11. 解释器模式:Spring SpEL 解析器

这篇总结适合作为 Spring 开源框架源码学习指南 🚀🚀🚀