行为型模式通过责任链传递请求、命令封装操作、策略切换算法、观察者通知状态变化及模板方法定义骨架等,解耦对象交互,动态分配职责,提升系统灵活性和扩展性,适用于算法、通信与流程管理场景。
1. 责任链模式(Chain of Responsibility)
定义
多个对象依次处理请求,直到有对象处理它为止。
类图
┌───────────────────┐ ┌───────────────────┐
│ Handler │<>─────│ Handler │
├───────────────────┤ ├───────────────────┤
│ +nextHandler │ │ +setNext() │
│ +handleRequest() │ │ +handleRequest() │
└─────────┬─────────┘ └─────────┬─────────┘
△ △
│ │
┌───────────────────┐ ┌───────────────────┐
│ ConcreteHandlerA │ │ ConcreteHandlerB │
├───────────────────┤ ├───────────────────┤
│ +handleRequest() │ │ +handleRequest() │
└───────────────────┘ └───────────────────┘
Java 实现
// 抽象处理者
abstract class Handler {
protected Handler next;
public void setNext(Handler next) {
this.next = next;
}
public abstract void handleRequest(int request);
}
// 具体处理者A
class ConcreteHandlerA extends Handler {
@Override
public void handleRequest(int request) {
if (request <= 10) {
System.out.println("HandlerA 处理请求: " + request);
} else if (next != null) {
next.handleRequest(request);
}
}
}
// 具体处理者B
class ConcreteHandlerB extends Handler {
@Override
public void handleRequest(int request) {
if (request > 10 && request <= 20) {
System.out.println("HandlerB 处理请求: " + request);
} else if (next != null) {
next.handleRequest(request);
}
}
}
// 客户端调用
public class Client {
public static void main(String[] args) {
Handler chain = new ConcreteHandlerA();
chain.setNext(new ConcreteHandlerB());
chain.handleRequest(5); // HandlerA处理
chain.handleRequest(15); // HandlerB处理
chain.handleRequest(25); // 无处理
}
}
适用场景
- HTTP 请求过滤器链
- 审批流程(如报销多级审批)
优缺点
- 优点:解耦请求发送者和接收者,动态调整责任链。
- 缺点:请求可能未被处理,调试较复杂。
2. 命令模式(Command)
定义
将请求封装为对象,支持请求的排队、撤销和日志记录。
类图
┌───────────────────┐ ┌───────────────────┐
│ Command │ │ Invoker │
├───────────────────┤ ├───────────────────┤
│ +execute() │ │ +setCommand() │
│ +undo() │ │ +executeCommand() │
└──────┬────────────┘ └───────────────────┘
△
│
┌───────────────────┐
│ ConcreteCommand │
├───────────────────┤
│ -receiver │
│ +execute() │
└──────┬────────────┘
△
│
┌───────────────────┐
│ Receiver │
├───────────────────┤
│ +action() │
└───────────────────┘
Java 实现
// 接收者(实际执行操作)
class Light {
public void turnOn() { System.out.println("灯已打开"); }
public void turnOff() { System.out.println("灯已关闭"); }
}
// 抽象命令
interface Command {
void execute();
void undo();
}
// 具体命令
class TurnOnCommand implements Command {
private Light light;
public TurnOnCommand(Light light) { this.light = light; }
@Override
public void execute() { light.turnOn(); }
@Override
public void undo() { light.turnOff(); }
}
// 调用者(触发命令)
class RemoteControl {
private Command command;
public void setCommand(Command command) { this.command = command; }
public void pressButton() { command.execute(); }
public void pressUndo() { command.undo(); }
}
// 客户端调用
public class Client {
public static void main(String[] args) {
Light light = new Light();
Command cmd = new TurnOnCommand(light);
RemoteControl remote = new RemoteControl();
remote.setCommand(cmd);
remote.pressButton(); // 输出: 灯已打开
remote.pressUndo(); // 输出: 灯已关闭
}
}
适用场景
- GUI 按钮操作封装
- 事务回滚、操作历史记录
优缺点
- 优点:解耦操作调用者和执行者,支持扩展。
- 缺点:每个命令需单独实现类,代码量大。
3. 解释器模式(Interpreter)
定义
为特定语法规则定义解释器,用于解析表达式。
类图
┌───────────────────┐ ┌───────────────────┐
│ AbstractExpression│<>─────│ TerminalExpression│
├───────────────────┤ ├───────────────────┤
│ +interpret() │ │ +interpret() │
└─────────┬─────────┘ └───────────────────┘
△
│
┌───────────────────┐
│ NonTerminalExpression │
├───────────────────┤
│ +interpret() │
└───────────────────┘
Java 实现
// 抽象表达式
interface Expression {
boolean interpret(String context);
}
// 终结符表达式
class TerminalExpression implements Expression {
private String data;
public TerminalExpression(String data) { this.data = data; }
@Override
public boolean interpret(String context) {
return context.contains(data);
}
}
// 非终结符表达式(AND逻辑)
class AndExpression implements Expression {
private Expression expr1;
private Expression expr2;
public AndExpression(Expression e1, Expression e2) {
this.expr1 = e1;
this.expr2 = e2;
}
@Override
public boolean interpret(String context) {
return expr1.interpret(context) && expr2.interpret(context);
}
}
// 客户端调用
public class Client {
public static void main(String[] args) {
Expression john = new TerminalExpression("John");
Expression married = new TerminalExpression("Married");
Expression isMarriedJohn = new AndExpression(john, married);
System.out.println(isMarriedJohn.interpret("John Married")); // true
}
}
适用场景
- SQL 解析、正则表达式引擎
- 数学公式计算器
优缺点
- 优点:易于扩展新语法规则。
- 缺点:复杂语法会导致类数量爆炸。
4. 迭代器模式(Iterator)
定义
提供一种顺序访问集合元素的方法,无需暴露内部结构。
类图
┌───────────────────┐ ┌───────────────────┐
│ Aggregate │<>─────│ Iterator │
├───────────────────┤ ├───────────────────┤
│ +createIterator() │ │ +hasNext() │
└───────────────────┘ │ +next() │
△ └─────────┬─────────┘
│ △
│ │
┌───────────────────┐ ┌───────────────────┐
│ ConcreteAggregate │ │ ConcreteIterator │
├───────────────────┤ ├───────────────────┤
│ +createIterator() │ │ +hasNext() │
└───────────────────┘ │ +next() │
└───────────────────┘
Java 实现
// 自定义集合接口
interface MyCollection<T> {
MyIterator<T> createIterator();
}
// 具体集合
class MyList<T> implements MyCollection<T> {
private List<T> items = new ArrayList<>();
public void add(T item) { items.add(item); }
@Override
public MyIterator<T> createIterator() {
return new MyListIterator<>(items);
}
}
// 迭代器接口
interface MyIterator<T> {
boolean hasNext();
T next();
}
// 具体迭代器
class MyListIterator<T> implements MyIterator<T> {
private List<T> items;
private int index = 0;
public MyListIterator(List<T> items) { this.items = items; }
@Override
public boolean hasNext() { return index < items.size(); }
@Override
public T next() { return items.get(index++); }
}
// 客户端调用
public class Client {
public static void main(String[] args) {
MyList<String> list = new MyList<>();
list.add("A");
list.add("B");
MyIterator<String> it = list.createIterator();
while (it.hasNext()) {
System.out.println(it.next());
}
}
}
适用场景
- Java 集合框架的
Iterator - 遍历复杂数据结构(树、图)
优缺点
- 优点:隐藏集合内部实现,支持多种遍历方式。
- 缺点:增加类的数量。
5. 中介者模式(Mediator)
定义
通过中介者对象减少对象间的直接耦合。
类图
┌───────────────────┐ ┌───────────────────┐
│ Mediator │ │ Colleague │
├───────────────────┤ ├───────────────────┤
│ +notify() │ │ -mediator │
└──────┬────────────┘ │ +send() │
△ └─────────┬─────────┘
│ △
│ │
┌───────────────────┐ ┌───────────────────┐
│ ConcreteMediator │ │ ConcreteColleague │
├───────────────────┤ ├───────────────────┤
│ +notify() │ │ +send() │
└───────────────────┘ └───────────────────┘
Java 实现
// 中介者接口
interface ChatMediator {
void sendMessage(String msg, User user);
void addUser(User user);
}
// 具体中介者(聊天室)
class ChatRoom implements ChatMediator {
private List<User> users = new ArrayList<>();
@Override
public void addUser(User user) { users.add(user); }
@Override
public void sendMessage(String msg, User sender) {
for (User u : users) {
if (u != sender) u.receive(msg);
}
}
}
// 同事类(用户)
abstract class User {
protected ChatMediator mediator;
protected String name;
public User(ChatMediator m, String name) {
this.mediator = m;
this.name = name;
}
public abstract void send(String msg);
public void receive(String msg) {
System.out.println(name + " 收到消息: " + msg);
}
}
// 具体同事类
class ChatUser extends User {
public ChatUser(ChatMediator m, String name) { super(m, name); }
@Override
public void send(String msg) {
System.out.println(name + " 发送消息: " + msg);
mediator.sendMessage(msg, this);
}
}
// 客户端调用
public class Client {
public static void main(String[] args) {
ChatMediator mediator = new ChatRoom();
User alice = new ChatUser(mediator, "Alice");
User bob = new ChatUser(mediator, "Bob");
mediator.addUser(alice);
mediator.addUser(bob);
alice.send("Hello!"); // Bob收到消息
}
}
适用场景
- 聊天室、事件调度系统
- 减少对象间网状依赖关系
优缺点
- 优点:集中控制交互逻辑,降低耦合。
- 缺点:中介者可能变得臃肿。
6. 备忘录模式(Memento)
定义
保存对象状态以便后续恢复。
类图
┌───────────────────┐ ┌───────────────────┐
│ Originator │ │ Memento │
├───────────────────┤ ├───────────────────┤
│ +createMemento() │ │ -state │
│ +restore() │ └───────────────────┘
└──────┬────────────┘ △
│ │
│ ┌───────┴───────┐
│ │ Caretaker │
│ ├───────────────┤
└───────────────────────│ -mementos │
└───────────────┘
Java 实现
// 发起人(需要保存状态的对象)
class Editor {
private String content;
public void write(String content) { this.content = content; }
public String getContent() { return content; }
public EditorMemento save() { return new EditorMemento(content); }
public void restore(EditorMemento memento) { content = memento.getContent(); }
}
// 备忘录(保存状态)
class EditorMemento {
private final String content;
public EditorMemento(String content) { this.content = content; }
public String getContent() { return content; }
}
// 管理者(保存备忘录历史)
class History {
private List<EditorMemento> mementos = new ArrayList<>();
public void push(EditorMemento m) { mementos.add(m); }
public EditorMemento pop() { return mementos.remove(mementos.size() - 1); }
}
// 客户端调用
public class Client {
public static void main(String[] args) {
Editor editor = new Editor();
History history = new History();
editor.write("Version 1");
history.push(editor.save());
editor.write("Version 2");
editor.restore(history.pop()); // 回退到Version 1
}
}
适用场景
- 文本编辑器撤销操作
- 游戏存档/读档
优缺点
- 优点:状态保存与恢复解耦。
- 缺点:频繁保存可能占用内存。
7. 观察者模式(Observer)
定义
定义对象间的一对多依赖,状态变化时通知所有依赖者。
类图
┌───────────────────┐ ┌───────────────────┐
│ Subject │<>─────│ Observer │
├───────────────────┤ ├───────────────────┤
│ +attach() │ │ +update() │
│ +detach() │ └───────────────────┘
│ +notify() │ △
└──────┬────────────┘ │
△ │
│ │
┌───────────────────┐ ┌───────────────────┐
│ ConcreteSubject │ │ ConcreteObserver │
├───────────────────┤ ├───────────────────┤
│ +getState() │ │ +update() │
└───────────────────┘ └───────────────────┘
Java 实现
// 主题接口
interface Subject {
void attach(Observer o);
void detach(Observer o);
void notifyObservers();
}
// 具体主题(温度传感器)
class TemperatureSensor implements Subject {
private List<Observer> observers = new ArrayList<>();
private float temperature;
public void setTemperature(float temp) {
this.temperature = temp;
notifyObservers();
}
@Override
public void attach(Observer o) { observers.add(o); }
@Override
public void detach(Observer o) { observers.remove(o); }
@Override
public void notifyObservers() {
for (Observer o : observers) o.update(temperature);
}
}
// 观察者接口
interface Observer {
void update(float temperature);
}
// 具体观察者(显示屏)
class Display implements Observer {
@Override
public void update(float temperature) {
System.out.println("当前温度: " + temperature);
}
}
// 客户端调用
public class Client {
public static void main(String[] args) {
TemperatureSensor sensor = new TemperatureSensor();
Display display = new Display();
sensor.attach(display);
sensor.setTemperature(25.5f); // 触发通知
}
}
适用场景
- 事件驱动系统(如 GUI 按钮点击)
- 实时数据监控
优缺点
- 优点:支持松耦合通信。
- 缺点:观察者可能收到不相关通知。
8. 状态模式(State)
定义
允许对象在其内部状态改变时改变行为。
类图
┌───────────────────┐ ┌───────────────────┐
│ Context │<>─────│ State │
├───────────────────┤ ├───────────────────┤
│ +request() │ │ +handle() │
└──────┬────────────┘ └─────────┬─────────┘
△ △
│ │
┌───────────────────┐ ┌───────────────────┐
│ ConcreteStateA │ │ ConcreteStateB │
├───────────────────┤ ├───────────────────┤
│ +handle() │ │ +handle() │
└───────────────────┘ └───────────────────┘
Java 实现
// 状态接口
interface OrderState {
void handle(OrderContext context);
}
// 具体状态:已下单
class OrderedState implements OrderState {
@Override
public void handle(OrderContext context) {
System.out.println("订单
8. 策略模式(Strategy)
定义
定义一组算法族,封装每个算法,并使它们可以互相替换,让算法的变化独立于客户端。
类图
复制
┌───────────────────┐ ┌───────────────────┐
│ Strategy │<>─────│ Context │
├───────────────────┤ ├───────────────────┤
│ +execute() │ │ -strategy │
└──────┬────────────┘ │ +setStrategy() │
△ │ +executeStrategy()│
│ └───────────────────┘
┌───────────────────┐
│ ConcreteStrategyA │
├───────────────────┤
│ +execute() │
└───────────────────┘
Java 实现
java
复制
// 策略接口
interface SortingStrategy {
void sort(int[] data);
}
// 具体策略:快速排序
class QuickSort implements SortingStrategy {
@Override
public void sort(int[] data) {
System.out.println("使用快速排序");
// 具体排序实现
}
}
// 具体策略:归并排序
class MergeSort implements SortingStrategy {
@Override
public void sort(int[] data) {
System.out.println("使用归并排序");
// 具体排序实现
}
}
// 上下文类(封装策略)
class Sorter {
private SortingStrategy strategy;
public void setStrategy(SortingStrategy strategy) {
this.strategy = strategy;
}
public void executeSort(int[] data) {
strategy.sort(data);
}
}
// 客户端调用
public class Client {
public static void main(String[] args) {
Sorter sorter = new Sorter();
sorter.setStrategy(new QuickSort());
sorter.executeSort(new int[]{5, 2, 9}); // 输出: 使用快速排序
}
}
适用场景
- 支付方式选择(支付宝、微信、信用卡等)
- 动态切换算法(如排序、压缩算法)
优缺点
- 优点:算法可扩展性强,符合开闭原则。
- 缺点:策略类数量增加,客户端需理解不同策略差异。
10. 模板方法模式(Template Method)
定义
定义算法的骨架,将某些步骤延迟到子类中实现。
类图
复制
┌───────────────────┐
│ AbstractClass │
├───────────────────┤
│ +templateMethod() │
│ +step1() │
│ +step2() │
└──────┬────────────┘
△
│
┌───────────────────┐
│ ConcreteClass │
├───────────────────┤
│ +step1() │
│ +step2() │
└───────────────────┘
Java 实现
java
复制
// 抽象模板类
abstract class Beverage {
// 模板方法(定义算法骨架)
public final void prepare() {
boilWater();
brew();
pourInCup();
addCondiments();
}
// 固定步骤(通用实现)
private void boilWater() {
System.out.println("烧水");
}
private void pourInCup() {
System.out.println("倒入杯子");
}
// 抽象步骤(由子类实现)
abstract void brew();
abstract void addCondiments();
}
// 具体子类:咖啡
class Coffee extends Beverage {
@Override
void brew() {
System.out.println("冲泡咖啡粉");
}
@Override
void addCondiments() {
System.out.println("加糖和牛奶");
}
}
// 客户端调用
public class Client {
public static void main(String[] args) {
Beverage coffee = new Coffee();
coffee.prepare();
// 输出顺序:烧水 → 冲泡咖啡粉 → 倒入杯子 → 加糖和牛奶
}
}
适用场景
- JDBC 模板(固定流程:连接 → 执行 → 关闭)
- 工作流框架(如审批流程的固定步骤)
优缺点
- 优点:代码复用,避免重复代码。
- 缺点:算法骨架难以修改,可能限制灵活性。
11. 访问者模式(Visitor)
定义
在不修改类结构的前提下,为类添加新的操作。
类图
复制
┌───────────────────┐ ┌───────────────────┐
│ Visitor │ │ Element │
├───────────────────┤ ├───────────────────┤
│ +visitA() │ │ +accept(Visitor) │
│ +visitB() │ └─────────┬─────────┘
└──────┬────────────┘ △
△ │
│ │
┌───────────────────┐ ┌───────────────────┐
│ ConcreteVisitor │ │ ConcreteElementA │
├───────────────────┤ ├───────────────────┤
│ +visitA() │ │ +accept(Visitor) │
└───────────────────┘ └───────────────────┘
Java 实现
java
复制
// 元素接口
interface DocumentElement {
void accept(Visitor visitor);
}
// 具体元素:文本段落
class TextElement implements DocumentElement {
private String content;
public TextElement(String content) { this.content = content; }
public String getContent() { return content; }
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
}
// 具体元素:图片
class ImageElement implements DocumentElement {
private String url;
public ImageElement(String url) { this.url = url; }
public String getUrl() { return url; }
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
}
// 访问者接口
interface Visitor {
void visit(TextElement text);
void visit(ImageElement image);
}
// 具体访问者:统计字数
class WordCountVisitor implements Visitor {
private int wordCount = 0;
@Override
public void visit(TextElement text) {
wordCount += text.getContent().split(" ").length;
}
@Override
public void visit(ImageElement image) {
// 图片不统计字数
}
public int getWordCount() { return wordCount; }
}
// 客户端调用
public class Client {
public static void main(String[] args) {
List<DocumentElement> elements = new ArrayList<>();
elements.add(new TextElement("Hello World"));
elements.add(new ImageElement("photo.jpg"));
WordCountVisitor visitor = new WordCountVisitor();
for (DocumentElement e : elements) {
e.accept(visitor);
}
System.out.println("总字数: " + visitor.getWordCount()); // 输出: 总字数: 2
}
}
适用场景
- 编译器语法树分析(如类型检查、代码优化)
- 复杂对象结构的统计或导出操作
优缺点
- 优点:新增操作无需修改元素类,符合开闭原则。
- 缺点:元素类结构需稳定,新增元素类型需修改所有访问者。