1. 行为型模式概述
行为型模式是设计模式中最庞大的一类,它关注对象之间的职责分配和算法抽象。与创建型和结构型模式不同,行为型模式主要解决的是"对象如何协作完成单个对象无法完成的任务"以及"如何分配职责使代码更灵活"的问题。
在Java中,行为型模式通常表现为对象间的通信机制。它们通过定义清晰的交互方式来降低对象间的耦合度,使得系统更易于扩展和维护。行为型模式特别适合处理那些流程复杂、状态多变、算法需要灵活变更的业务场景。
2. 责任链模式详解
2.1 模式定义与结构
责任链模式(Chain of Responsibility)使多个对象都有机会处理请求,从而避免请求发送者与接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递请求,直到有对象处理它为止。
典型结构包含:
- Handler:定义处理请求的接口,通常包含一个处理方法和一个设置后继者的方法
- ConcreteHandler:具体处理者,处理它负责的请求,可以访问后继者
- Client:向链上的具体处理者对象提交请求
java复制public abstract class Handler {
protected Handler successor;
public void setSuccessor(Handler successor) {
this.successor = successor;
}
public abstract void handleRequest(Request request);
}
2.2 实际应用场景
责任链模式在Java中有着广泛的应用:
- Servlet过滤器链:每个Filter都可以决定是否将请求传递给下一个Filter
- 异常处理机制:从具体异常到父类异常的捕获过程
- 审批流程系统:多级审批,每个审批人都有权处理或转交
- 日志系统:不同级别的日志由不同的处理器处理
2.3 实现要点与注意事项
实现责任链模式时需要注意:
- 链的构建方式:可以在客户端硬编码,也可以通过配置文件动态构建
- 请求的传递:确保每个处理器正确处理或传递请求,避免循环引用
- 性能考虑:长链可能导致性能问题,必要时可以引入缓存机制
提示:在Spring框架中,可以通过实现HandlerInterceptor接口来构建责任链式的拦截器
3. 命令模式深度解析
3.1 模式核心思想
命令模式(Command)将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作。
关键角色包括:
- Command:声明执行操作的接口
- ConcreteCommand:将一个接收者对象绑定于一个动作
- Invoker:要求命令执行请求
- Receiver:知道如何实施与执行一个请求相关的操作
java复制public interface Command {
void execute();
void undo();
}
public class LightOnCommand implements Command {
private Light light;
public LightOnCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.on();
}
@Override
public void undo() {
light.off();
}
}
3.2 典型应用案例
命令模式特别适用于以下场景:
- GUI按钮和菜单项:将用户操作封装为命令对象
- 事务系统:实现原子操作和回滚机制
- 宏命令:组合多个命令形成复合命令
- 线程池:将任务封装为命令对象提交给线程池
3.3 高级应用技巧
- 命令队列:实现命令的异步执行
- 日志和恢复:记录命令执行历史,支持系统恢复
- 撤销/重做:通过维护命令栈实现多级撤销
- 智能命令:命令对象自己实现执行逻辑,而非委托给接收者
4. 解释器模式实践指南
4.1 模式适用场景
解释器模式(Interpreter)给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。
最佳适用场景:
- 当有一个语言需要解释执行
- 文法比较简单(复杂文法建议使用解析器生成器)
- 效率不是关键问题
4.2 模式实现示例
以简单的布尔表达式解释器为例:
java复制public interface Expression {
boolean interpret(String context);
}
public class TerminalExpression implements Expression {
private String data;
public TerminalExpression(String data) {
this.data = data;
}
@Override
public boolean interpret(String context) {
return context.contains(data);
}
}
public class OrExpression implements Expression {
private Expression expr1;
private Expression expr2;
public OrExpression(Expression expr1, Expression expr2) {
this.expr1 = expr1;
this.expr2 = expr2;
}
@Override
public boolean interpret(String context) {
return expr1.interpret(context) || expr2.interpret(context);
}
}
4.3 实际应用考量
- 性能优化:解释器模式可能产生大量小对象,考虑使用享元模式共享终结符
- 扩展性:文法规则变更时需要修改代码,不适合频繁变化的语法
- 替代方案:对于复杂语法,考虑使用编译器/解释器生成工具如ANTLR
5. 迭代器模式与Java集合
5.1 模式基本原理
迭代器模式(Iterator)提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露该对象的内部表示。
Java集合框架中广泛使用了迭代器模式:
java复制public interface Iterator<E> {
boolean hasNext();
E next();
default void remove() {
throw new UnsupportedOperationException("remove");
}
}
5.2 自定义迭代器实现
实现一个简单的集合迭代器:
java复制public class Book {
private String name;
// 构造方法、getter/setter省略
}
public class BookShelf implements Iterable<Book> {
private Book[] books;
private int last = 0;
public BookShelf(int maxsize) {
this.books = new Book[maxsize];
}
public Book getBookAt(int index) {
return books[index];
}
public void appendBook(Book book) {
this.books[last] = book;
last++;
}
public int getLength() {
return last;
}
@Override
public Iterator<Book> iterator() {
return new BookShelfIterator(this);
}
}
public class BookShelfIterator implements Iterator<Book> {
private BookShelf bookShelf;
private int index;
public BookShelfIterator(BookShelf bookShelf) {
this.bookShelf = bookShelf;
this.index = 0;
}
@Override
public boolean hasNext() {
return index < bookShelf.getLength();
}
@Override
public Book next() {
Book book = bookShelf.getBookAt(index);
index++;
return book;
}
}
5.3 迭代器的高级应用
- 并行迭代:支持多线程安全遍历
- 过滤迭代器:只返回满足特定条件的元素
- 延迟加载迭代器:按需加载元素,减少内存消耗
- 不可变迭代器:防止在迭代过程中修改集合
6. 中介者模式解耦实践
6.1 模式核心价值
中介者模式(Mediator)用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
典型应用场景:
- 图形用户界面中组件间的复杂交互
- 聊天室系统中用户间的消息传递
- 航空管制系统中飞机与塔台的通信
6.2 模式实现示例
实现一个简单的聊天室中介者:
java复制public interface ChatMediator {
void sendMessage(String msg, User user);
void addUser(User user);
}
public class ChatMediatorImpl implements ChatMediator {
private List<User> users;
public ChatMediatorImpl() {
this.users = new ArrayList<>();
}
@Override
public void sendMessage(String msg, User user) {
for(User u : users) {
// 消息不应该发送给自己
if(u != user) {
u.receive(msg);
}
}
}
@Override
public void addUser(User user) {
this.users.add(user);
}
}
public abstract class User {
protected ChatMediator mediator;
protected String name;
public User(ChatMediator med, String name) {
this.mediator = med;
this.name = name;
}
public abstract void send(String msg);
public abstract void receive(String msg);
}
public class UserImpl extends User {
public UserImpl(ChatMediator med, String name) {
super(med, name);
}
@Override
public void send(String msg) {
System.out.println(this.name + ": Sending Message=" + msg);
mediator.sendMessage(msg, this);
}
@Override
public void receive(String msg) {
System.out.println(this.name + ": Received Message:" + msg);
}
}
6.3 模式应用建议
- 控制中介者复杂度:避免中介者变成"上帝对象"
- 结合观察者模式:使用事件机制实现松耦合通知
- 分布式中介者:在微服务架构中作为服务间协调器
- 性能优化:对于高频交互,考虑引入批处理机制
7. 备忘录模式与对象状态管理
7.1 模式基本原理
备忘录模式(Memento)在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。
关键参与者:
- Originator:创建并在Memento中存储状态
- Memento:存储Originator的内部状态
- Caretaker:负责保存好备忘录,但不能对备忘录的内容进行操作或检查
7.2 模式实现示例
实现文本编辑器的撤销功能:
java复制public class TextEditor {
private String text;
public void setText(String text) {
this.text = text;
}
public String getText() {
return text;
}
public TextMemento save() {
return new TextMemento(text);
}
public void restore(TextMemento memento) {
this.text = memento.getSavedText();
}
public static class TextMemento {
private final String text;
public TextMemento(String text) {
this.text = text;
}
private String getSavedText() {
return text;
}
}
}
public class History {
private Stack<TextEditor.TextMemento> states = new Stack<>();
public void save(TextEditor editor) {
states.push(editor.save());
}
public void undo(TextEditor editor) {
if(!states.isEmpty()) {
editor.restore(states.pop());
}
}
}
7.3 应用注意事项
- 状态存储开销:大对象的状态保存可能消耗大量内存
- 序列化支持:考虑使用序列化机制简化备忘录实现
- 增量备忘录:只保存变化的部分而非整个状态
- 多级撤销:通过栈结构支持多步撤销操作
8. 观察者模式与事件驱动
8.1 模式核心概念
观察者模式(Observer)定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
Java中的实现方式:
- 自定义观察者接口(传统方式)
- 使用java.util.Observable和Observer(已过时)
- 使用PropertyChangeListener(JavaBeans规范)
- 使用RxJava等响应式编程库
8.2 Java内置观察者实现
java复制public class NewsPublisher {
private String news;
private List<NewsSubscriber> subscribers = new ArrayList<>();
public void addSubscriber(NewsSubscriber subscriber) {
subscribers.add(subscriber);
}
public void removeSubscriber(NewsSubscriber subscriber) {
subscribers.remove(subscriber);
}
public void setNews(String news) {
this.news = news;
notifySubscribers();
}
private void notifySubscribers() {
for(NewsSubscriber subscriber : subscribers) {
subscriber.update(news);
}
}
}
public interface NewsSubscriber {
void update(String news);
}
public class EmailSubscriber implements NewsSubscriber {
private String email;
public EmailSubscriber(String email) {
this.email = email;
}
@Override
public void update(String news) {
System.out.println("Sending email to " + email + ": " + news);
}
}
8.3 现代Java中的观察者模式
- JavaBeans属性变更监听:
java复制public class Model {
private PropertyChangeSupport support = new PropertyChangeSupport(this);
public void addPropertyChangeListener(PropertyChangeListener pcl) {
support.addPropertyChangeListener(pcl);
}
public void removePropertyChangeListener(PropertyChangeListener pcl) {
support.removePropertyChangeListener(pcl);
}
private String value;
public void setValue(String newValue) {
String oldValue = this.value;
this.value = newValue;
support.firePropertyChange("value", oldValue, newValue);
}
}
- Spring事件机制:
java复制// 定义事件
public class CustomEvent extends ApplicationEvent {
public CustomEvent(Object source) {
super(source);
}
}
// 发布事件
@Component
public class EventPublisher {
@Autowired
private ApplicationEventPublisher eventPublisher;
public void publish() {
eventPublisher.publishEvent(new CustomEvent(this));
}
}
// 监听事件
@Component
public class EventListener {
@EventListener
public void handleCustomEvent(CustomEvent event) {
// 处理事件
}
}
9. 状态模式与复杂状态管理
9.1 模式定义与优势
状态模式(State)允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类。
主要优点:
- 将与特定状态相关的行为局部化,并且将不同状态的行为分割开来
- 使得状态转换显式化
- 减少条件判断语句,提高代码可维护性
9.2 订单状态管理示例
java复制public interface OrderState {
void next(Order order);
void previous(Order order);
void printStatus();
}
public class NewOrder implements OrderState {
@Override
public void next(Order order) {
order.setState(new Processing());
}
@Override
public void previous(Order order) {
System.out.println("The order is in its initial state.");
}
@Override
public void printStatus() {
System.out.println("Order is NEW.");
}
}
public class Processing implements OrderState {
@Override
public void next(Order order) {
order.setState(new Shipped());
}
@Override
public void previous(Order order) {
order.setState(new NewOrder());
}
@Override
public void printStatus() {
System.out.println("Order is PROCESSING.");
}
}
public class Order {
private OrderState currentState;
public Order() {
currentState = new NewOrder();
}
public void setState(OrderState state) {
currentState = state;
}
public void nextState() {
currentState.next(this);
}
public void previousState() {
currentState.previous(this);
}
public void printStatus() {
currentState.printStatus();
}
}
9.3 状态模式高级应用
- 状态机框架:结合Spring State Machine等框架
- 分布式状态管理:在微服务架构中保持状态一致性
- 状态持久化:将状态保存到数据库并在恢复时重建
- 并发状态管理:处理多线程环境下的状态变更
10. 策略模式与算法封装
10.1 模式核心思想
策略模式(Strategy)定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。策略模式使得算法可独立于使用它的客户而变化。
主要优点:
- 算法可以自由切换
- 避免使用多重条件判断
- 扩展性良好
10.2 支付策略示例
java复制public interface PaymentStrategy {
void pay(int amount);
}
public class CreditCardPayment implements PaymentStrategy {
private String name;
private String cardNumber;
private String cvv;
public CreditCardPayment(String name, String cardNumber, String cvv) {
this.name = name;
this.cardNumber = cardNumber;
this.cvv = cvv;
}
@Override
public void pay(int amount) {
System.out.println(amount + " paid with credit card.");
}
}
public class ShoppingCart {
private PaymentStrategy paymentStrategy;
public void setPaymentStrategy(PaymentStrategy strategy) {
this.paymentStrategy = strategy;
}
public void checkout(int amount) {
paymentStrategy.pay(amount);
}
}
10.3 Java中的策略模式应用
- Comparator接口:集合排序的不同策略
- 线程池拒绝策略:ThreadPoolExecutor的四种内置拒绝策略
- Spring的ResourceLoader:不同资源位置的加载策略
- 安全认证策略:多种认证方式的灵活切换
11. 模板方法模式与算法骨架
11.1 模式定义与结构
模板方法模式(Template Method)定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
关键点:
- 抽象类定义模板方法和基本方法
- 具体子类实现特定的步骤
- 通过钩子方法提供额外扩展点
11.2 数据库操作模板示例
java复制public abstract class DatabaseTemplate {
// 模板方法
public final void executeQuery() {
connect();
setConnectionParameters();
prepareStatement();
executeStatement();
processResults();
closeConnection();
}
protected abstract void setConnectionParameters();
protected abstract void prepareStatement();
protected abstract void executeStatement();
protected abstract void processResults();
private void connect() {
System.out.println("Default connection established");
}
private void closeConnection() {
System.out.println("Default connection closed");
}
// 钩子方法
protected boolean shouldLog() {
return false;
}
}
public class MySQLQuery extends DatabaseTemplate {
@Override
protected void setConnectionParameters() {
System.out.println("Setting MySQL connection parameters");
}
@Override
protected void prepareStatement() {
System.out.println("Preparing MySQL statement");
}
@Override
protected void executeStatement() {
System.out.println("Executing MySQL query");
}
@Override
protected void processResults() {
System.out.println("Processing MySQL results");
}
@Override
protected boolean shouldLog() {
return true;
}
}
11.3 模板方法模式应用建议
- 框架设计:提供扩展点让用户自定义特定步骤
- 算法复用:多个类似算法共享公共结构
- 控制反转:父类控制流程,子类提供实现
- 钩子方法:提供额外控制点影响模板方法行为
12. 访问者模式与数据结构操作
12.1 模式基本原理
访问者模式(Visitor)表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
核心角色:
- Visitor:为每个具体元素类声明一个访问操作
- ConcreteVisitor:实现每个由Visitor声明的操作
- Element:定义一个accept操作,以Visitor为参数
- ObjectStructure:能枚举它的元素,可以提供一个高层接口允许访问者访问它的元素
12.2 文档处理示例
java复制public interface DocumentVisitor {
void visit(TextElement text);
void visit(ImageElement image);
void visit(TableElement table);
}
public class WordCountVisitor implements DocumentVisitor {
private int wordCount = 0;
@Override
public void visit(TextElement text) {
wordCount += text.getText().split("\\s+").length;
}
@Override
public void visit(ImageElement image) {
// 图片不计入字数
}
@Override
public void visit(TableElement table) {
// 表格内容可能已经包含在文本元素中
}
public int getWordCount() {
return wordCount;
}
}
public interface DocumentElement {
void accept(DocumentVisitor visitor);
}
public class TextElement implements DocumentElement {
private String text;
public TextElement(String text) {
this.text = text;
}
public String getText() {
return text;
}
@Override
public void accept(DocumentVisitor visitor) {
visitor.visit(this);
}
}
public class Document {
private List<DocumentElement> elements = new ArrayList<>();
public void addElement(DocumentElement element) {
elements.add(element);
}
public void accept(DocumentVisitor visitor) {
for(DocumentElement element : elements) {
element.accept(visitor);
}
}
}
12.3 访问者模式应用考量
- 双重分发机制:通过两次方法调用实现动态绑定
- 开闭原则:易于新增操作,但难以新增元素类型
- 访问者状态:可以在访问者中累积状态
- 替代方案:对于简单结构,考虑迭代器+策略模式组合
13. 行为型模式综合对比
13.1 各模式适用场景对比
| 模式名称 | 主要目的 | 典型应用场景 | 复杂度 |
|---|---|---|---|
| 责任链 | 解耦请求发送者和接收者 | 审批流程、异常处理 | 中 |
| 命令 | 封装请求为对象 | 事务系统、GUI操作 | 中 |
| 解释器 | 实现特定语法解释 | 规则引擎、查询语言 | 高 |
| 迭代器 | 提供集合遍历方式 | 集合框架、树遍历 | 低 |
| 中介者 | 集中对象交互 | 聊天系统、UI组件交互 | 高 |
| 备忘录 | 保存和恢复对象状态 | 撤销操作、快照 | 中 |
| 观察者 | 对象状态变更通知 | 事件系统、MVC | 低 |
| 状态 | 封装状态相关行为 | 订单状态机、游戏AI | 中 |
| 策略 | 封装可互换算法 | 支付方式、排序算法 | 低 |
| 模板方法 | 定义算法骨架 | 框架扩展点、流程控制 | 低 |
| 访问者 | 分离数据结构与操作 | 编译器、文档处理 | 高 |
13.2 模式选择指南
- 对象交互复杂:考虑中介者或观察者模式
- 算法需要灵活切换:策略模式是最佳选择
- 需要支持撤销操作:备忘录模式必不可少
- 处理多种状态:状态模式可以消除条件分支
- 定义操作流程:模板方法提供标准结构
- 遍历复杂数据结构:迭代器或访问者模式
13.3 模式组合应用
- 组合模式+访问者模式:处理树形结构的各种操作
- 观察者模式+中介者模式:构建事件驱动的分布式系统
- 策略模式+工厂模式:动态创建和切换算法
- 状态模式+备忘录模式:实现可持久化的状态机
14. Java框架中的行为型模式应用
14.1 Spring框架中的行为模式
- 模板方法模式:
- JdbcTemplate
- RestTemplate
- TransactionTemplate
- 策略模式:
- ResourceLoader的不同实现
- 多种CacheManager实现
- 观察者模式:
- ApplicationEvent机制
- @EventListener注解
- 责任链模式:
- Spring Security的过滤器链
- HandlerInterceptor链
14.2 Java集合框架中的行为模式
- 迭代器模式:
- java.util.Iterator接口
- 增强for循环的实现基础
- 策略模式:
- Comparator接口
- 各种Queue的实现策略
- 访问者模式:
- java.nio.file.FileVisitor
- 文件树遍历API
14.3 Java并发包中的行为模式
- 策略模式:
- RejectedExecutionHandler(线程池拒绝策略)
- ThreadFactory(线程创建策略)
- 观察者模式:
- Future和CompletionService
- 异步计算结果通知
- 命令模式:
- Runnable和Callable接口
- 将任务封装为命令对象
15. 行为型模式最佳实践
15.1 设计原则应用
- 开闭原则:
- 策略模式和命令模式支持在不修改现有代码的情况下扩展新行为
- 访问者模式使得新增操作变得容易
- 单一职责原则:
- 状态模式将不同状态的行为分离到不同类中
- 命令模式将请求封装为独立对象
- 迪米特法则:
- 中介者模式减少对象间的直接通信
- 观察者模式通过抽象接口进行通知
15.2 性能优化建议
- 责任链模式:
- 对处理器进行排序,高频处理器放在链前端
- 引入缓存机制避免重复处理
- 观察者模式:
- 使用线程池处理通知事件
- 考虑事件合并,减少通知频率
- 访问者模式:
- 对稳定数据结构使用访问者模式
- 考虑使用ASM等字节码工具优化性能
15.3 测试与维护建议
- 策略模式:
- 为每种策略编写独立测试用例
- 使用依赖注入简化策略替换
- 状态模式:
- 测试所有状态转换路径
- 记录状态转换日志便于调试
- 模板方法模式:
- 测试模板方法的整体流程
- 为每个钩子方法编写文档说明其用途
16. 行为型模式常见误区
16.1 过度设计问题
- 滥用设计模式:
- 简单条件判断就能解决的问题不需要状态模式
- 直接方法调用比命令模式更简单时不要使用命令模式
- 模式组合复杂度过高:
- 避免创建包含太多模式的"超级模式"
- 保持每个类的单一职责
16.2 实现陷阱
- 观察者模式的内存泄漏:
- 忘记取消注册观察者
- 观察者持有被观察者的强引用
- 状态模式的无效状态转换:
- 缺少状态转换验证
- 未处理所有可能的转换路径
- 访问者模式的循环依赖:
- 访问者和元素之间的双向依赖
- 新增元素类型需要修改所有访问者
16.3 替代方案考量
- 函数式编程替代策略模式:
- 使用Lambda表达式代替策略接口
- Java 8+的函数式接口简化实现
- 枚举替代状态模式:
- 对于简单状态机,考虑使用枚举+方法
- 枚举类型天然支持状态转换
- 流式API替代迭代器模式:
- Java 8 Stream API提供更强大的集合操作
- 减少显式迭代器使用的需要
17. 行为型模式演进趋势
17.1 响应式编程的影响
- 观察者模式的扩展:
- RxJava和Reactor库提供强大的观察者模式实现
- 支持背压、错误处理和操作符链
- 命令模式的异步化:
- CompletableFuture和反应式流支持异步命令执行
- 非阻塞IO改变命令执行方式
17.2 函数式编程的融合
- 策略模式的Lambda实现:
- 使用函数接口代替策略接口
- 减少样板代码
- 模板方法的高阶函数实现:
- 通过函数组合实现算法骨架
- 更灵活的步骤替换机制
17.3 微服务架构下的应用
- 中介者模式的分布式实现:
- 使用消息队列作为服务间中介
- 事件溯源模式扩展观察者模式
- 命令模式的跨服务应用:
- Saga模式实现分布式事务
- CQRS模式分离读写操作
18. 行为型模式面试精要
18.1 高频面试问题
- 模式识别:
- "Spring的事件机制使用了什么设计模式?"
- "Java集合框架的iterator()方法体现了什么模式?"
- 模式比较:
- "策略模式和状态模式有何异同?"
- "观察者模式和发布-订阅模式有什么区别?"
- 模式实现:
- "如何实现一个支持撤销的操作?"
- "设计一个多级审批系统,你会使用什么模式?"
18.2 问题解答技巧
- 结合JDK和框架实例:
- 回答时引用Java集合、Spring等标准实现
- 展示对Java生态的深入理解
- 强调设计原则:
- 说明模式如何遵循SOLID原则
- 分析模式的优缺点和权衡
- 提供多种解决方案:
- 比较不同模式的适用场景
- 讨论在特定约束下的最佳选择
18.3 实战编码示例
- 状态模式问题:
"设计一个电梯状态控制系统,支持空闲、运行、维护等状态"
java复制public interface ElevatorState {
void move();
void stop();
void repair();
void maintenance();
}
public class Elevator {
private ElevatorState currentState;
// 状态转换方法和业务方法
// ...
}
// 实现各种具体状态类
- 观察者模式问题:
"实现一个股票价格变动通知系统"
java复制public class Stock {
private double price;
private List<StockObserver> observers = new ArrayList<>();
public void setPrice(double price) {
this.price = price;
notifyObservers();
}
// 注册、通知等方法
// ...
}
public interface StockObserver {
void update(double price);
}
19. 行为型模式性能调优
19.1 责任链模式优化
- 处理器缓存:
- 缓存处理器处理结果
- 避免重复处理相同请求
- 并行处理:
- 对无依赖的处理器使用并行流
- 注意线程安全问题
19.2 观察者模式优化
- 异步通知:
- 使用线程池处理观察者通知
- 注意观察者执行顺序要求
- 批量通知:
- 合并多个变更事件
- 减少通知频率
19.3 访问者模式优化
- 访问者缓存:
- 缓存元素类型与访问方法的映射
- 减少反射开销
- 访问者组合:
- 将多个访问者组合为一个
- 减少遍历次数
20. 行为型模式调试技巧
20.1 状态模式调试
- 状态日志:
- 记录所有状态转换
- 输出转换前后的状态信息
- 非法状态检测:
- 验证状态转换条件
- 抛出明确的非法状态异常
20.2 观察者模式调试
- 观察者追踪:
- 记录所有注册的观察者
- 验证通知是否送达
- 事件溯源:
- 记录所有事件历史
- 支持事件重放
20.3 策略模式调试
- 策略标识:
- 为每个策略提供有意义的toString()
- 日志中记录使用的策略
- 策略验证:
- 验证策略选择的正确性
- 检查策略执行前提条件
21. 行为型模式与设计原则
21.1 单一职责原则
- 策略模式:
- 每个策略类只负责一种算法实现
- 分离算法定义与使用
- 状态模式:
- 每个状态类只负责该状态的行为
- 分离状态逻辑与上下文
21.2 开闭原则
- 访问者模式:
- 易于添加新操作
- 不影响现有元素类
- 命令模式:
- 可以添加新命令类型
- 不修改调用者代码
21.3 依赖倒置原则
- 观察者模式:
- 依赖抽象观察者接口
- 不依赖具体观察者
- 策略模式:
- 依赖抽象策略接口
- 运行时注入具体策略
22. 行为型模式代码坏味道
22.1 过长条件判断
java复制// 坏味道
if (state == "NEW") {
// 处理新订单
} else if (state == "PROCESSING") {
// 处理中的订单
} else if (state == "SHIPPED") {
// 已发货订单
}
// 重构为状态模式
public interface OrderState {
void handle();
}
22.2 过度耦合
java复制// 坏味道
class A {
private B b;
private C c;
public void process() {
b.doSomething();
c.doSomethingElse();
// 协调B和C的交互
}
}
// 重构为中介者模式
class Mediator {
private B b;
private C c;
public void coordinate() {
b.doSomething();
c.doSomethingElse();
}
}
22.3 重复算法结构
java复制// 坏味道
class ReportGenerator {
void generatePDF() {
setup();
// PDF生成逻辑
cleanup();
}
void generateHTML() {
setup();
// HTML生成逻辑
cleanup();
}
}
// 重构为模板方法模式
abstract class ReportGenerator {
final void generate() {
setup();
doGenerate();
cleanup();
}
abstract void doGenerate();
}
23. 行为型模式重构指南
23.1 重构为策略模式
- 识别变化点:
- 找出经常变更的算法或行为
- 提取接口:
- 定义策略接口
- 创建具体策略:
- 将每种算法实现为独立类
- 注入策略:
- 通过构造器或方法注入策略
23.2 重构为观察者模式
- 识别被观察者:
- 找出状态变化需要通知其他对象的类
- 定义观察者接口:
- 声明更新方法
- 实现订阅机制:
- 添加注册/注销观察者的方法
- 添加通知逻辑:
- 在状态变更时通知观察者
23.3 重构为状态模式
- 识别状态相关行为:
- 找出与对象状态相关的条件判断
