🕺 行为型设计模式:对象协作的舞蹈家
💡 温馨提示:本文将以轻松有趣的方式带你探索行为型设计模式的世界,就像在观看一场精彩的"对象舞蹈表演"一样!
🚪 传送门:在开始我们的"对象协作之旅"之前,建议先通过这个 🎨 Java设计模式详解:让代码优雅如诗的秘密武器 了解设计模式的基础概念和整体架构,然后通过 🏭 创建型设计模式:对象诞生的艺术与智慧 学习对象创建的艺术,再通过 🏗️ 结构型设计模式:代码架构的魔法师 了解对象组合的艺术,这样能让你更好地理解本文内容!就像跳舞要先学会走路一样!💃
🕺 行为型设计模式整体架构
TypeError: Cannot read properties of undefined (reading 'v')
🎪 引言:为什么我们需要行为型设计模式?
🕺 场景:混乱的对象舞蹈现场 🕺
┌─────────────────────────────────────┐
│ 💻 程序员小王的一天 💻 │
│ │
│ 😵 对象间通信像鸡同鸭讲! │
│ 🔥 算法选择像选择困难症! │
│ 🐛 状态管理像迷宫一样复杂! │
│ │
│ 💡 突然,行为型设计模式舞者出现了! │
│ 🕺 "让我来编排你们的协作舞蹈!" │
└─────────────────────────────────────┘
行为型设计模式就像是"对象协作"的标准舞蹈编排,让对象之间的通信变得优雅、灵活、高效。
本文将带你探索十一种行为型设计模式,就像观看十一个不同的"对象舞蹈表演"一样精彩!
🎯 本文你将学到什么?
🎬 行为型设计模式舞蹈团 🎬
┌─────────────────────────────────────┐
│ 🕺 十一位协作舞者登场! │
│ │
│ 👀 观察者:一对多通知机制 │
│ 🎯 策略者:算法选择专家 │
│ 📝 命令者:请求封装大师 │
│ 🔄 状态者:状态变化艺术家 │
│ 📋 模板者:算法框架设计师 │
│ 🔍 迭代者:集合遍历专家 │
│ ⛓️ 责任链:请求处理链 │
│ 🤝 中介者:对象交互协调员 │
│ 👁️ 访问者:元素操作专家 │
│ 💾 备忘录:状态保存专家 │
│ 🗣️ 解释器:语言解释专家 │
│ │
│ 🚀 准备好开始舞蹈之旅了吗? │
└─────────────────────────────────────┘
👀 第一部分:观察者模式(Observer Pattern)
👀 观察者舞者的登场 👀
┌─────────────────────────────────────┐
│ 👀 观察者:我是一对多通知专家! │
│ │
│ 📢 主题:"我有新消息!" │
│ 👀 观察者:"我来通知大家!" │
│ 📢 主题:"状态变化了!" │
│ 👀 观察者:"我来更新大家!" │
│ │
│ 💡 核心思想:一对多通知机制 │
└─────────────────────────────────────┘
🏗️ 观察者模式UML类图
TypeError: Cannot read properties of undefined (reading 'x')
⏱️ 观察者模式时序图
1.1 🎭 什么是观察者模式?
一句话理解:当一个对象状态改变时,自动通知所有依赖它的对象,就像新闻发布一样!
定义:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
应用场景:事件处理系统、消息推送、数据绑定、日志记录、GUI事件处理
1.2 🛠️ 观察者模式的实现
1.2.1 🏗️ 基本结构
💡 小贴士:观察者模式就像新闻发布系统,主题是新闻社,观察者是各个新闻频道!
核心组件:
- Subject(主题):被观察的对象,维护观察者列表
- Observer(观察者):观察主题的对象,接收通知
- ConcreteSubject(具体主题):具体的被观察对象
- ConcreteObserver(具体观察者):具体的观察者实现
1.2.2 🚀 多种实现方式
实现方式 | 特点 | 推荐度 |
---|---|---|
推模式 | 主题主动推送数据给观察者 | ⭐⭐⭐⭐ |
拉模式 | 观察者主动从主题获取数据 | ⭐⭐⭐ |
事件驱动 | 基于事件的松耦合实现 | ⭐⭐⭐⭐⭐ |
推模式实现:
// 推模式:主题主动推送数据给观察者
public interface PushObserver {
void update(String data); // 直接接收数据
}
public class PushSubject {
private List<PushObserver> observers = new ArrayList<>();
private String state;
public void setState(String state) {
this.state = state;
notifyObservers(); // 推送状态给所有观察者
}
public void notifyObservers() {
for (PushObserver observer : observers) {
observer.update(state); // 直接推送数据
}
}
public void addObserver(PushObserver observer) {
observers.add(observer);
}
}
public class PushConcreteObserver implements PushObserver {
private String name;
public PushConcreteObserver(String name) {
this.name = name;
}
@Override
public void update(String data) {
System.out.println(name + " 收到推送数据: " + data);
}
}
拉模式实现:
// 拉模式:观察者主动从主题获取数据
public interface PullObserver {
void update(); // 不传递数据,观察者自己获取
}
public class PullSubject {
private List<PullObserver> observers = new ArrayList<>();
private String state;
public void setState(String state) {
this.state = state;
notifyObservers();
}
public void notifyObservers() {
for (PullObserver observer : observers) {
observer.update(); // 只通知,不传递数据
}
}
public String getState() {
return state; // 观察者通过此方法获取数据
}
public void addObserver(PullObserver observer) {
observers.add(observer);
}
}
public class PullConcreteObserver implements PullObserver {
private String name;
private PullSubject subject;
public PullConcreteObserver(String name, PullSubject subject) {
this.name = name;
this.subject = subject;
}
@Override
public void update() {
String data = subject.getState(); // 主动拉取数据
System.out.println(name + " 拉取到数据: " + data);
}
}
事件驱动实现:
// 事件驱动:基于事件的松耦合实现
public class NewsEvent {
private String news;
private long timestamp;
public NewsEvent(String news) {
this.news = news;
this.timestamp = System.currentTimeMillis();
}
public String getNews() { return news; }
public long getTimestamp() { return timestamp; }
}
public interface EventObserver {
void onEvent(NewsEvent event);
}
public class EventSubject {
private Map<String, List<EventObserver>> eventObservers = new HashMap<>();
public void addObserver(String eventType, EventObserver observer) {
eventObservers.computeIfAbsent(eventType, k -> new ArrayList<>()).add(observer);
}
public void publishEvent(String eventType, NewsEvent event) {
List<EventObserver> observers = eventObservers.get(eventType);
if (observers != null) {
for (EventObserver observer : observers) {
observer.onEvent(event);
}
}
}
}
public class EventConcreteObserver implements EventObserver {
private String name;
public EventConcreteObserver(String name) {
this.name = name;
}
@Override
public void onEvent(NewsEvent event) {
System.out.println(name + " 收到事件: " + event.getNews() +
" (时间: " + new Date(event.getTimestamp()) + ")");
}
}
1.2.3 🎯 标准实现示例
// 观察者接口 - 定义观察者的行为
public interface Observer {
void update(String message);
}
// 主题接口 - 定义主题的行为
public interface Subject {
void registerObserver(Observer observer); // 注册观察者
void removeObserver(Observer observer); // 移除观察者
void notifyObservers(); // 通知所有观察者
}
// 具体主题 - 实现主题接口
public class ConcreteSubject implements Subject {
private List<Observer> observers = new ArrayList<>(); // 观察者列表
private String state; // 主题状态
@Override
public void registerObserver(Observer observer) {
observers.add(observer);
System.out.println("观察者 " + observer + " 已注册");
}
@Override
public void removeObserver(Observer observer) {
observers.remove(observer);
System.out.println("观察者 " + observer + " 已移除");
}
@Override
public void notifyObservers() {
System.out.println("主题状态变化,通知所有观察者...");
for (Observer observer : observers) {
observer.update(state);
}
}
// 设置状态并通知观察者
public void setState(String state) {
this.state = state;
System.out.println("主题状态设置为: " + state);
notifyObservers(); // 状态变化时自动通知
}
}
// 具体观察者 - 实现观察者接口
public class ConcreteObserver implements Observer {
private String name; // 观察者名称
public ConcreteObserver(String name) {
this.name = name;
}
@Override
public void update(String message) {
System.out.println(name + " 收到通知: " + message);
}
@Override
public String toString() {
return name;
}
}
1.2.4 📰 实际应用示例
💡 场景:新闻社发布新闻,各个新闻频道自动接收并报道!
问题:新闻社需要及时通知所有订阅的新闻频道
// 新闻发布系统 - 具体主题
public class NewsAgency implements Subject {
private List<Observer> observers = new ArrayList<>(); // 新闻频道列表
private String news; // 最新新闻
@Override
public void registerObserver(Observer observer) {
observers.add(observer);
System.out.println("新闻频道 " + observer + " 已订阅");
}
@Override
public void removeObserver(Observer observer) {
observers.remove(observer);
System.out.println("新闻频道 " + observer + " 已取消订阅");
}
@Override
public void notifyObservers() {
System.out.println("📢 新闻社发布新闻,通知所有频道...");
for (Observer observer : observers) {
observer.update(news);
}
}
// 发布新闻
public void publishNews(String news) {
this.news = news;
System.out.println("📰 新闻社发布新闻: " + news);
notifyObservers();
}
}
// 新闻频道 - 具体观察者
public class NewsChannel implements Observer {
private String name; // 频道名称
public NewsChannel(String name) {
this.name = name;
}
@Override
public void update(String news) {
System.out.println("📺 " + name + " 频道报道: " + news);
}
@Override
public String toString() {
return name;
}
}
// 使用示例
public class ObserverPatternDemo {
public static void main(String[] args) {
// 创建新闻社
NewsAgency newsAgency = new NewsAgency();
// 创建新闻频道
NewsChannel cctv = new NewsChannel("CCTV");
NewsChannel bbc = new NewsChannel("BBC");
NewsChannel cnn = new NewsChannel("CNN");
// 频道订阅新闻社
newsAgency.registerObserver(cctv);
newsAgency.registerObserver(bbc);
newsAgency.registerObserver(cnn);
System.out.println("\n=== 发布第一条新闻 ===");
newsAgency.publishNews("重大新闻:人工智能技术取得突破性进展!");
System.out.println("\n=== BBC取消订阅 ===");
newsAgency.removeObserver(bbc);
System.out.println("\n=== 发布第二条新闻 ===");
newsAgency.publishNews("科技新闻:新型电动汽车即将上市!");
}
}
🎯 第二部分:策略模式(Strategy Pattern)
🎯 策略舞者的登场 🎯
┌─────────────────────────────────────┐
│ 🎯 策略者:我是算法选择专家! │
│ │
│ 💰 客户:"我要用支付宝支付!" │
│ 🎯 策略者:"我来切换策略!" │
│ 💰 客户:"我要用微信支付!" │
│ 🎯 策略者:"继续切换策略!" │
│ │
│ 💡 核心思想:算法可以互相替换 │
└─────────────────────────────────────┘
🏗️ 策略模式UML类图
TypeError: Cannot read properties of undefined (reading 'x')
⏱️ 策略模式时序图
2.1 🎭 什么是策略模式?
一句话理解:定义一系列算法,让它们可以互相替换,就像选择不同的支付方式一样!
定义:定义一系列的算法,把它们一个个封装起来,并且使它们可以互相替换。
应用场景:支付方式选择、排序算法选择、压缩算法选择、游戏角色技能选择
2.2 🛠️ 策略模式的实现
2.2.1 🏗️ 基本结构
💡 小贴士:策略模式就像游戏中的技能选择,玩家可以根据需要切换不同的技能!
核心组件:
- Strategy(策略):算法的抽象接口
- ConcreteStrategy(具体策略):具体的算法实现
- Context(上下文):使用策略的客户端
2.2.2 🚀 多种实现方式
实现方式 | 特点 | 推荐度 |
---|---|---|
接口策略 | 通过接口定义策略 | ⭐⭐⭐⭐⭐ |
枚举策略 | 使用枚举简化策略 | ⭐⭐⭐⭐ |
函数式策略 | 使用Lambda表达式 | ⭐⭐⭐⭐⭐ |
接口策略实现:
// 接口策略:通过接口定义策略
public interface SortStrategy {
void sort(int[] array);
}
public class BubbleSortStrategy implements SortStrategy {
@Override
public void sort(int[] array) {
System.out.println("使用冒泡排序");
for (int i = 0; i < array.length - 1; i++) {
for (int j = 0; j < array.length - 1 - i; j++) {
if (array[j] > array[j + 1]) {
int temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
}
}
}
}
public class QuickSortStrategy implements SortStrategy {
@Override
public void sort(int[] array) {
System.out.println("使用快速排序");
quickSort(array, 0, array.length - 1);
}
private void quickSort(int[] array, int low, int high) {
if (low < high) {
int pi = partition(array, low, high);
quickSort(array, low, pi - 1);
quickSort(array, pi + 1, high);
}
}
private int partition(int[] array, int low, int high) {
int pivot = array[high];
int i = low - 1;
for (int j = low; j < high; j++) {
if (array[j] <= pivot) {
i++;
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
int temp = array[i + 1];
array[i + 1] = array[high];
array[high] = temp;
return i + 1;
}
}
public class SortContext {
private SortStrategy strategy;
public void setStrategy(SortStrategy strategy) {
this.strategy = strategy;
}
public void executeSort(int[] array) {
strategy.sort(array);
}
}
枚举策略实现:
// 枚举策略:使用枚举简化策略
public enum SortStrategyEnum {
BUBBLE_SORT {
@Override
public void sort(int[] array) {
System.out.println("使用冒泡排序");
for (int i = 0; i < array.length - 1; i++) {
for (int j = 0; j < array.length - 1 - i; j++) {
if (array[j] > array[j + 1]) {
int temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
}
}
}
},
QUICK_SORT {
@Override
public void sort(int[] array) {
System.out.println("使用快速排序");
quickSort(array, 0, array.length - 1);
}
private void quickSort(int[] array, int low, int high) {
if (low < high) {
int pi = partition(array, low, high);
quickSort(array, low, pi - 1);
quickSort(array, pi + 1, high);
}
}
private int partition(int[] array, int low, int high) {
int pivot = array[high];
int i = low - 1;
for (int j = low; j < high; j++) {
if (array[j] <= pivot) {
i++;
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
int temp = array[i + 1];
array[i + 1] = array[high];
array[high] = temp;
return i + 1;
}
},
MERGE_SORT {
@Override
public void sort(int[] array) {
System.out.println("使用归并排序");
mergeSort(array, 0, array.length - 1);
}
private void mergeSort(int[] array, int left, int right) {
if (left < right) {
int mid = (left + right) / 2;
mergeSort(array, left, mid);
mergeSort(array, mid + 1, right);
merge(array, left, mid, right);
}
}
private void merge(int[] array, int left, int mid, int right) {
int[] temp = new int[right - left + 1];
int i = left, j = mid + 1, k = 0;
while (i <= mid && j <= right) {
if (array[i] <= array[j]) {
temp[k++] = array[i++];
} else {
temp[k++] = array[j++];
}
}
while (i <= mid) temp[k++] = array[i++];
while (j <= right) temp[k++] = array[j++];
for (i = 0; i < k; i++) {
array[left + i] = temp[i];
}
}
};
public abstract void sort(int[] array);
}
public class EnumSortContext {
private SortStrategyEnum strategy;
public void setStrategy(SortStrategyEnum strategy) {
this.strategy = strategy;
}
public void executeSort(int[] array) {
strategy.sort(array);
}
}
函数式策略实现:
// 函数式策略:使用Lambda表达式
@FunctionalInterface
public interface SortFunction {
void sort(int[] array);
}
public class FunctionalSortContext {
private SortFunction sortFunction;
public void setSortFunction(SortFunction sortFunction) {
this.sortFunction = sortFunction;
}
public void executeSort(int[] array) {
sortFunction.sort(array);
}
// 预定义的排序策略
public static final SortFunction BUBBLE_SORT = array -> {
System.out.println("使用冒泡排序");
for (int i = 0; i < array.length - 1; i++) {
for (int j = 0; j < array.length - 1 - i; j++) {
if (array[j] > array[j + 1]) {
int temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
}
}
};
public static final SortFunction QUICK_SORT = array -> {
System.out.println("使用快速排序");
quickSort(array, 0, array.length - 1);
};
private static void quickSort(int[] array, int low, int high) {
if (low < high) {
int pi = partition(array, low, high);
quickSort(array, low, pi - 1);
quickSort(array, pi + 1, high);
}
}
private static int partition(int[] array, int low, int high) {
int pivot = array[high];
int i = low - 1;
for (int j = low; j < high; j++) {
if (array[j] <= pivot) {
i++;
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
int temp = array[i + 1];
array[i + 1] = array[high];
array[high] = temp;
return i + 1;
}
}
2.2.3 🎯 标准实现示例
// 策略接口 - 定义算法的抽象
public interface Strategy {
void algorithmInterface();
}
// 具体策略A - 实现算法A
public class ConcreteStrategyA implements Strategy {
@Override
public void algorithmInterface() {
System.out.println("🎯 执行策略A的算法");
}
}
// 具体策略B - 实现算法B
public class ConcreteStrategyB implements Strategy {
@Override
public void algorithmInterface() {
System.out.println("🎯 执行策略B的算法");
}
}
// 上下文 - 使用策略的客户端
public class Context {
private Strategy strategy; // 当前使用的策略
public Context(Strategy strategy) {
this.strategy = strategy;
}
// 设置策略
public void setStrategy(Strategy strategy) {
this.strategy = strategy;
System.out.println("🔄 策略已切换");
}
// 执行策略
public void contextInterface() {
System.out.println("🚀 开始执行策略...");
strategy.algorithmInterface();
}
}
2.2.4 💰 实际应用示例
💡 场景:电商平台支持多种支付方式,用户可以根据需要选择不同的支付策略!
问题:需要支持多种支付方式,并且可以灵活切换
// 支付策略接口 - 定义支付行为的抽象
public interface PaymentStrategy {
void pay(double amount);
}
// 支付宝支付策略
public class AlipayStrategy implements PaymentStrategy {
@Override
public void pay(double amount) {
System.out.println("💰 使用支付宝支付: " + amount + " 元");
System.out.println("📱 跳转到支付宝支付页面...");
System.out.println("✅ 支付宝支付成功!");
}
}
// 微信支付策略
public class WechatStrategy implements PaymentStrategy {
@Override
public void pay(double amount) {
System.out.println("💰 使用微信支付: " + amount + " 元");
System.out.println("📱 跳转到微信支付页面...");
System.out.println("✅ 微信支付成功!");
}
}
// 银行卡支付策略
public class BankCardStrategy implements PaymentStrategy {
@Override
public void pay(double amount) {
System.out.println("💰 使用银行卡支付: " + amount + " 元");
System.out.println("💳 请输入银行卡信息...");
System.out.println("✅ 银行卡支付成功!");
}
}
// 购物车 - 使用支付策略的上下文
public class ShoppingCart {
private PaymentStrategy paymentStrategy; // 当前支付策略
// 设置支付策略
public void setPaymentStrategy(PaymentStrategy paymentStrategy) {
this.paymentStrategy = paymentStrategy;
System.out.println("🔄 支付方式已切换");
}
// 结账
public void checkout(double amount) {
if (paymentStrategy == null) {
System.out.println("❌ 请先选择支付方式!");
return;
}
System.out.println("🛒 开始结账,金额: " + amount + " 元");
paymentStrategy.pay(amount);
System.out.println("🎉 订单完成!");
}
}
// 使用示例
public class StrategyPatternDemo {
public static void main(String[] args) {
// 创建购物车
ShoppingCart cart = new ShoppingCart();
// 创建不同的支付策略
PaymentStrategy alipay = new AlipayStrategy();
PaymentStrategy wechat = new WechatStrategy();
PaymentStrategy bankCard = new BankCardStrategy();
System.out.println("=== 使用支付宝支付 ===");
cart.setPaymentStrategy(alipay);
cart.checkout(100.0);
System.out.println("\n=== 使用微信支付 ===");
cart.setPaymentStrategy(wechat);
cart.checkout(200.0);
System.out.println("\n=== 使用银行卡支付 ===");
cart.setPaymentStrategy(bankCard);
cart.checkout(300.0);
}
}
📝 第三部分:命令模式(Command Pattern)
📝 命令舞者的登场 📝
┌─────────────────────────────────────┐
│ 📝 命令者:我是请求封装大师! │
│ │
│ 🎮 遥控器:"我要开灯!" │
│ 📝 命令者:"我来封装请求!" │
│ 🎮 遥控器:"我要关灯!" │
│ 📝 命令者:"继续封装请求!" │
│ │
│ 💡 核心思想:将请求封装为对象 │
└─────────────────────────────────────┘
🏗️ 命令模式UML类图
TypeError: Cannot read properties of undefined (reading 'x')
⏱️ 命令模式时序图
3.1 🎭 什么是命令模式?
一句话理解:将请求封装为对象,支持撤销和重做,就像遥控器一样!
定义:将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化。
应用场景:遥控器系统、撤销/重做功能、宏命令、日志记录、事务处理
3.2 🛠️ 命令模式的实现
3.2.1 🏗️ 基本结构
💡 小贴士:命令模式就像遥控器,每个按钮对应一个命令,可以轻松实现撤销重做!
核心组件:
- Command(命令):封装请求的接口
- ConcreteCommand(具体命令):具体的命令实现
- Receiver(接收者):执行命令的对象
- Invoker(调用者):使用命令的客户端
3.2.2 🚀 多种实现方式
实现方式 | 特点 | 推荐度 |
---|---|---|
简单命令 | 一个命令对应一个接收者 | ⭐⭐⭐⭐ |
宏命令 | 一个命令包含多个子命令 | ⭐⭐⭐⭐⭐ |
撤销重做 | 支持命令的撤销和重做 | ⭐⭐⭐⭐⭐ |
简单命令实现:
// 简单命令:一个命令对应一个接收者
public interface SimpleCommand {
void execute();
}
public class Light {
public void turnOn() {
System.out.println("电灯打开");
}
public void turnOff() {
System.out.println("电灯关闭");
}
}
public class LightOnCommand implements SimpleCommand {
private Light light;
public LightOnCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.turnOn();
}
}
public class LightOffCommand implements SimpleCommand {
private Light light;
public LightOffCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.turnOff();
}
}
public class SimpleRemoteControl {
private SimpleCommand command;
public void setCommand(SimpleCommand command) {
this.command = command;
}
public void pressButton() {
command.execute();
}
}
宏命令实现:
// 宏命令:一个命令包含多个子命令
public interface MacroCommand extends SimpleCommand {
void addCommand(SimpleCommand command);
void removeCommand(SimpleCommand command);
}
public class MacroCommandImpl implements MacroCommand {
private List<SimpleCommand> commands = new ArrayList<>();
@Override
public void addCommand(SimpleCommand command) {
commands.add(command);
}
@Override
public void removeCommand(SimpleCommand command) {
commands.remove(command);
}
@Override
public void execute() {
System.out.println("执行宏命令,包含 " + commands.size() + " 个子命令");
for (SimpleCommand command : commands) {
command.execute();
}
}
}
public class TV {
public void turnOn() {
System.out.println("电视打开");
}
public void turnOff() {
System.out.println("电视关闭");
}
}
public class Stereo {
public void turnOn() {
System.out.println("音响打开");
}
public void turnOff() {
System.out.println("音响关闭");
}
public void setVolume(int volume) {
System.out.println("音响音量设置为: " + volume);
}
}
public class TVOnCommand implements SimpleCommand {
private TV tv;
public TVOnCommand(TV tv) {
this.tv = tv;
}
@Override
public void execute() {
tv.turnOn();
}
}
public class StereoOnCommand implements SimpleCommand {
private Stereo stereo;
public StereoOnCommand(Stereo stereo) {
this.stereo = stereo;
}
@Override
public void execute() {
stereo.turnOn();
stereo.setVolume(11);
}
}
撤销重做实现:
// 撤销重做:支持命令的撤销和重做
public interface UndoableCommand extends SimpleCommand {
void undo();
}
public class LightOnCommandWithUndo implements UndoableCommand {
private Light light;
public LightOnCommandWithUndo(Light light) {
this.light = light;
}
@Override
public void execute() {
light.turnOn();
}
@Override
public void undo() {
light.turnOff();
}
}
public class LightOffCommandWithUndo implements UndoableCommand {
private Light light;
public LightOffCommandWithUndo(Light light) {
this.light = light;
}
@Override
public void execute() {
light.turnOff();
}
@Override
public void undo() {
light.turnOn();
}
}
public class CeilingFan {
public static final int HIGH = 3;
public static final int MEDIUM = 2;
public static final int LOW = 1;
public static final int OFF = 0;
private String location;
private int speed;
public CeilingFan(String location) {
this.location = location;
this.speed = OFF;
}
public void high() {
speed = HIGH;
System.out.println(location + " 风扇设置为高速");
}
public void medium() {
speed = MEDIUM;
System.out.println(location + " 风扇设置为中速");
}
public void low() {
speed = LOW;
System.out.println(location + " 风扇设置为低速");
}
public void off() {
speed = OFF;
System.out.println(location + " 风扇关闭");
}
public int getSpeed() {
return speed;
}
}
public class CeilingFanHighCommand implements UndoableCommand {
private CeilingFan ceilingFan;
private int prevSpeed;
public CeilingFanHighCommand(CeilingFan ceilingFan) {
this.ceilingFan = ceilingFan;
}
@Override
public void execute() {
prevSpeed = ceilingFan.getSpeed();
ceilingFan.high();
}
@Override
public void undo() {
switch (prevSpeed) {
case CeilingFan.HIGH:
ceilingFan.high();
break;
case CeilingFan.MEDIUM:
ceilingFan.medium();
break;
case CeilingFan.LOW:
ceilingFan.low();
break;
default:
ceilingFan.off();
break;
}
}
}
public class RemoteControlWithUndo {
private UndoableCommand[] onCommands;
private UndoableCommand[] offCommands;
private UndoableCommand undoCommand;
public RemoteControlWithUndo() {
onCommands = new UndoableCommand[7];
offCommands = new UndoableCommand[7];
UndoableCommand noCommand = new NoCommand();
for (int i = 0; i < 7; i++) {
onCommands[i] = noCommand;
offCommands[i] = noCommand;
}
undoCommand = noCommand;
}
public void setCommand(int slot, UndoableCommand onCommand, UndoableCommand offCommand) {
onCommands[slot] = onCommand;
offCommands[slot] = offCommand;
}
public void onButtonWasPushed(int slot) {
onCommands[slot].execute();
undoCommand = onCommands[slot];
}
public void offButtonWasPushed(int slot) {
offCommands[slot].execute();
undoCommand = offCommands[slot];
}
public void undoButtonWasPushed() {
undoCommand.undo();
}
}
public class NoCommand implements UndoableCommand {
@Override
public void execute() {
// 什么都不做
}
@Override
public void undo() {
// 什么都不做
}
}
3.2.3 🎯 标准实现示例
// 命令接口 - 定义命令的行为
public interface Command {
void execute();
void undo();
}
// 接收者 - 执行具体操作的对象
public class Receiver {
public void action() {
System.out.println("接收者执行操作");
}
public void undoAction() {
System.out.println("接收者撤销操作");
}
}
// 具体命令 - 实现命令接口
public class ConcreteCommand implements Command {
private Receiver receiver;
public ConcreteCommand(Receiver receiver) {
this.receiver = receiver;
}
@Override
public void execute() {
receiver.action();
}
@Override
public void undo() {
receiver.undoAction();
}
}
// 调用者 - 使用命令的客户端
public class Invoker {
private Command command;
public void setCommand(Command command) {
this.command = command;
}
public void executeCommand() {
command.execute();
}
public void undoCommand() {
command.undo();
}
}
3.2.4 🎯 实际应用示例
// 电器接口
public interface Device {
void turnOn();
void turnOff();
}
// 电灯
public class Light implements Device {
@Override
public void turnOn() {
System.out.println("电灯打开");
}
@Override
public void turnOff() {
System.out.println("电灯关闭");
}
}
// 开灯命令
public class LightOnCommand implements Command {
private Light light;
public LightOnCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.turnOn();
}
@Override
public void undo() {
light.turnOff();
}
}
// 关灯命令
public class LightOffCommand implements Command {
private Light light;
public LightOffCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.turnOff();
}
@Override
public void undo() {
light.turnOn();
}
}
// 遥控器
public class RemoteControl {
private Command[] onCommands;
private Command[] offCommands;
private Command undoCommand;
public RemoteControl() {
onCommands = new Command[7];
offCommands = new Command[7];
Command noCommand = new NoCommand();
for (int i = 0; i < 7; i++) {
onCommands[i] = noCommand;
offCommands[i] = noCommand;
}
undoCommand = noCommand;
}
public void setCommand(int slot, Command onCommand, Command offCommand) {
onCommands[slot] = onCommand;
offCommands[slot] = offCommand;
}
public void onButtonWasPushed(int slot) {
onCommands[slot].execute();
undoCommand = onCommands[slot];
}
public void offButtonWasPushed(int slot) {
offCommands[slot].execute();
undoCommand = offCommands[slot];
}
public void undoButtonWasPushed() {
undoCommand.undo();
}
}
🔄 第四部分:状态模式(State Pattern)
🔄 状态舞者的登场 🔄
┌─────────────────────────────────────┐
│ 🔄 状态者:我是状态变化艺术家! │
│ │
│ 🎮 角色:"我现在是正常状态!" │
│ 🔄 状态者:"我来改变行为!" │
│ 🎮 角色:"我现在是受伤状态!" │
│ 🔄 状态者:"继续改变行为!" │
│ │
│ 💡 核心思想:状态影响行为 │
└─────────────────────────────────────┘
🏗️ 状态模式UML类图
TypeError: Cannot read properties of undefined (reading 'x')
⏱️ 状态模式时序图
4.1 🎭 什么是状态模式?
一句话理解:对象的行为随着状态的改变而改变,就像游戏角色的不同状态!
定义:允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。
应用场景:状态机、游戏角色状态、订单状态、工作流状态
4.2 🛠️ 状态模式的实现
4.2.1 🏗️ 基本结构
💡 小贴士:状态模式就像游戏角色的状态变化,不同状态下有不同的行为表现!
核心组件:
- State(状态):状态的抽象接口
- ConcreteState(具体状态):具体的状态实现
- Context(上下文):维护当前状态的对象
4.2.2 🚀 多种实现方式
实现方式 | 特点 | 推荐度 |
---|---|---|
状态接口 | 通过接口定义状态行为 | ⭐⭐⭐⭐⭐ |
状态枚举 | 使用枚举简化状态管理 | ⭐⭐⭐⭐ |
状态机 | 复杂状态转换逻辑 | ⭐⭐⭐⭐⭐ |
状态接口实现:
// 状态接口:通过接口定义状态行为
public interface VendingMachineState {
void insertCoin();
void ejectCoin();
void selectProduct();
void dispense();
}
public class NoCoinState implements VendingMachineState {
private VendingMachine vendingMachine;
public NoCoinState(VendingMachine vendingMachine) {
this.vendingMachine = vendingMachine;
}
@Override
public void insertCoin() {
System.out.println("投币成功");
vendingMachine.setState(vendingMachine.getHasCoinState());
}
@Override
public void ejectCoin() {
System.out.println("没有投币,无法退币");
}
@Override
public void selectProduct() {
System.out.println("请先投币");
}
@Override
public void dispense() {
System.out.println("请先投币");
}
}
public class HasCoinState implements VendingMachineState {
private VendingMachine vendingMachine;
public HasCoinState(VendingMachine vendingMachine) {
this.vendingMachine = vendingMachine;
}
@Override
public void insertCoin() {
System.out.println("已经投币,请选择商品");
}
@Override
public void ejectCoin() {
System.out.println("退币成功");
vendingMachine.setState(vendingMachine.getNoCoinState());
}
@Override
public void selectProduct() {
System.out.println("选择商品成功");
vendingMachine.setState(vendingMachine.getSoldState());
}
@Override
public void dispense() {
System.out.println("请先选择商品");
}
}
public class SoldState implements VendingMachineState {
private VendingMachine vendingMachine;
public SoldState(VendingMachine vendingMachine) {
this.vendingMachine = vendingMachine;
}
@Override
public void insertCoin() {
System.out.println("请等待商品出货");
}
@Override
public void ejectCoin() {
System.out.println("商品已选择,无法退币");
}
@Override
public void selectProduct() {
System.out.println("商品已选择,请等待出货");
}
@Override
public void dispense() {
System.out.println("商品出货");
vendingMachine.releaseProduct();
if (vendingMachine.getCount() > 0) {
vendingMachine.setState(vendingMachine.getNoCoinState());
} else {
vendingMachine.setState(vendingMachine.getSoldOutState());
}
}
}
public class SoldOutState implements VendingMachineState {
private VendingMachine vendingMachine;
public SoldOutState(VendingMachine vendingMachine) {
this.vendingMachine = vendingMachine;
}
@Override
public void insertCoin() {
System.out.println("商品已售罄,无法投币");
}
@Override
public void ejectCoin() {
System.out.println("没有投币,无法退币");
}
@Override
public void selectProduct() {
System.out.println("商品已售罄");
}
@Override
public void dispense() {
System.out.println("商品已售罄");
}
}
public class VendingMachine {
private VendingMachineState noCoinState;
private VendingMachineState hasCoinState;
private VendingMachineState soldState;
private VendingMachineState soldOutState;
private VendingMachineState currentState;
private int count = 0;
public VendingMachine(int count) {
noCoinState = new NoCoinState(this);
hasCoinState = new HasCoinState(this);
soldState = new SoldState(this);
soldOutState = new SoldOutState(this);
this.count = count;
if (count > 0) {
currentState = noCoinState;
} else {
currentState = soldOutState;
}
}
public void insertCoin() {
currentState.insertCoin();
}
public void ejectCoin() {
currentState.ejectCoin();
}
public void selectProduct() {
currentState.selectProduct();
}
public void dispense() {
currentState.dispense();
}
public void setState(VendingMachineState state) {
currentState = state;
}
public void releaseProduct() {
System.out.println("商品从售货机中出来");
count--;
}
public int getCount() {
return count;
}
// Getter methods for states
public VendingMachineState getNoCoinState() { return noCoinState; }
public VendingMachineState getHasCoinState() { return hasCoinState; }
public VendingMachineState getSoldState() { return soldState; }
public VendingMachineState getSoldOutState() { return soldOutState; }
}
状态枚举实现:
// 状态枚举:使用枚举简化状态管理
public enum OrderState {
PENDING {
@Override
public void process(Order order) {
System.out.println("订单待处理,开始处理...");
order.setState(PROCESSING);
}
@Override
public void cancel(Order order) {
System.out.println("订单取消");
order.setState(CANCELLED);
}
@Override
public void ship(Order order) {
System.out.println("订单还未处理,无法发货");
}
@Override
public void deliver(Order order) {
System.out.println("订单还未发货,无法交付");
}
},
PROCESSING {
@Override
public void process(Order order) {
System.out.println("订单正在处理中...");
}
@Override
public void cancel(Order order) {
System.out.println("订单处理中,无法取消");
}
@Override
public void ship(Order order) {
System.out.println("订单处理完成,开始发货");
order.setState(SHIPPED);
}
@Override
public void deliver(Order order) {
System.out.println("订单还未发货,无法交付");
}
},
SHIPPED {
@Override
public void process(Order order) {
System.out.println("订单已发货,无法重新处理");
}
@Override
public void cancel(Order order) {
System.out.println("订单已发货,无法取消");
}
@Override
public void ship(Order order) {
System.out.println("订单已发货");
}
@Override
public void deliver(Order order) {
System.out.println("订单交付完成");
order.setState(DELIVERED);
}
},
DELIVERED {
@Override
public void process(Order order) {
System.out.println("订单已交付,无法重新处理");
}
@Override
public void cancel(Order order) {
System.out.println("订单已交付,无法取消");
}
@Override
public void ship(Order order) {
System.out.println("订单已交付,无法重新发货");
}
@Override
public void deliver(Order order) {
System.out.println("订单已交付");
}
},
CANCELLED {
@Override
public void process(Order order) {
System.out.println("订单已取消,无法处理");
}
@Override
public void cancel(Order order) {
System.out.println("订单已取消");
}
@Override
public void ship(Order order) {
System.out.println("订单已取消,无法发货");
}
@Override
public void deliver(Order order) {
System.out.println("订单已取消,无法交付");
}
};
public abstract void process(Order order);
public abstract void cancel(Order order);
public abstract void ship(Order order);
public abstract void deliver(Order order);
}
public class Order {
private String orderId;
private OrderState state;
public Order(String orderId) {
this.orderId = orderId;
this.state = OrderState.PENDING;
}
public void process() {
state.process(this);
}
public void cancel() {
state.cancel(this);
}
public void ship() {
state.ship(this);
}
public void deliver() {
state.deliver(this);
}
public void setState(OrderState state) {
this.state = state;
}
public OrderState getState() {
return state;
}
public String getOrderId() {
return orderId;
}
}
4.2.3 ⚙️ 状态机实现
// 状态机:复杂状态转换逻辑
public class StateMachine<T> {
private T currentState;
private Map<T, Map<String, T>> transitions = new HashMap<>();
private Map<T, Map<String, Runnable>> actions = new HashMap<>();
public StateMachine(T initialState) {
this.currentState = initialState;
}
public void addTransition(T fromState, String event, T toState) {
transitions.computeIfAbsent(fromState, k -> new HashMap<>()).put(event, toState);
}
public void addAction(T state, String event, Runnable action) {
actions.computeIfAbsent(state, k -> new HashMap<>()).put(event, action);
}
public boolean fire(String event) {
Map<String, T> stateTransitions = transitions.get(currentState);
if (stateTransitions != null && stateTransitions.containsKey(event)) {
// 执行当前状态的退出动作
executeAction(currentState, "exit");
// 执行事件动作
executeAction(currentState, event);
// 转换状态
T newState = stateTransitions.get(event);
currentState = newState;
// 执行新状态的进入动作
executeAction(currentState, "enter");
return true;
}
return false;
}
private void executeAction(T state, String event) {
Map<String, Runnable> stateActions = actions.get(state);
if (stateActions != null) {
Runnable action = stateActions.get(event);
if (action != null) {
action.run();
}
}
}
public T getCurrentState() {
return currentState;
}
}
// 使用状态机的游戏角色状态管理
public enum GameState {
IDLE, WALKING, RUNNING, JUMPING, ATTACKING, DEFENDING, DEAD
}
public class GameCharacter {
private String name;
private StateMachine<GameState> stateMachine;
public GameCharacter(String name) {
this.name = name;
this.stateMachine = new StateMachine<>(GameState.IDLE);
setupStateMachine();
}
private void setupStateMachine() {
// 定义状态转换
stateMachine.addTransition(GameState.IDLE, "walk", GameState.WALKING);
stateMachine.addTransition(GameState.IDLE, "run", GameState.RUNNING);
stateMachine.addTransition(GameState.IDLE, "jump", GameState.JUMPING);
stateMachine.addTransition(GameState.IDLE, "attack", GameState.ATTACKING);
stateMachine.addTransition(GameState.IDLE, "defend", GameState.DEFENDING);
stateMachine.addTransition(GameState.WALKING, "stop", GameState.IDLE);
stateMachine.addTransition(GameState.WALKING, "run", GameState.RUNNING);
stateMachine.addTransition(GameState.WALKING, "jump", GameState.JUMPING);
stateMachine.addTransition(GameState.RUNNING, "stop", GameState.IDLE);
stateMachine.addTransition(GameState.RUNNING, "walk", GameState.WALKING);
stateMachine.addTransition(GameState.RUNNING, "jump", GameState.JUMPING);
stateMachine.addTransition(GameState.JUMPING, "land", GameState.IDLE);
stateMachine.addTransition(GameState.JUMPING, "attack", GameState.ATTACKING);
stateMachine.addTransition(GameState.ATTACKING, "finish", GameState.IDLE);
stateMachine.addTransition(GameState.ATTACKING, "defend", GameState.DEFENDING);
stateMachine.addTransition(GameState.DEFENDING, "finish", GameState.IDLE);
stateMachine.addTransition(GameState.DEFENDING, "attack", GameState.ATTACKING);
// 所有状态都可以转换到死亡状态
for (GameState state : GameState.values()) {
if (state != GameState.DEAD) {
stateMachine.addTransition(state, "die", GameState.DEAD);
}
}
// 定义状态动作
stateMachine.addAction(GameState.IDLE, "enter", () -> System.out.println(name + " 进入待机状态"));
stateMachine.addAction(GameState.WALKING, "enter", () -> System.out.println(name + " 开始行走"));
stateMachine.addAction(GameState.RUNNING, "enter", () -> System.out.println(name + " 开始奔跑"));
stateMachine.addAction(GameState.JUMPING, "enter", () -> System.out.println(name + " 开始跳跃"));
stateMachine.addAction(GameState.ATTACKING, "enter", () -> System.out.println(name + " 开始攻击"));
stateMachine.addAction(GameState.DEFENDING, "enter", () -> System.out.println(name + " 开始防御"));
stateMachine.addAction(GameState.DEAD, "enter", () -> System.out.println(name + " 死亡"));
}
public void walk() {
stateMachine.fire("walk");
}
public void run() {
stateMachine.fire("run");
}
public void jump() {
stateMachine.fire("jump");
}
public void attack() {
stateMachine.fire("attack");
}
public void defend() {
stateMachine.fire("defend");
}
public void stop() {
stateMachine.fire("stop");
}
public void land() {
stateMachine.fire("land");
}
public void finish() {
stateMachine.fire("finish");
}
public void die() {
stateMachine.fire("die");
}
public GameState getCurrentState() {
return stateMachine.getCurrentState();
}
}
4.2.3 🎯 标准实现示例
// 状态接口 - 定义状态的行为
public interface State {
void handle();
}
// 具体状态A - 实现状态A的行为
public class ConcreteStateA implements State {
private Context context;
public ConcreteStateA(Context context) {
this.context = context;
}
@Override
public void handle() {
System.out.println("状态A的处理");
context.setState(new ConcreteStateB(context));
}
}
// 具体状态B - 实现状态B的行为
public class ConcreteStateB implements State {
private Context context;
public ConcreteStateB(Context context) {
this.context = context;
}
@Override
public void handle() {
System.out.println("状态B的处理");
context.setState(new ConcreteStateA(context));
}
}
// 上下文 - 维护当前状态的对象
public class Context {
private State state;
public Context() {
state = new ConcreteStateA(this);
}
public void setState(State state) {
this.state = state;
}
public void request() {
state.handle();
}
}
4.2.4 🎯 实际应用示例
// 售货机状态接口
public interface VendingMachineState {
void insertCoin();
void ejectCoin();
void selectProduct();
void dispense();
}
// 无币状态
public class NoCoinState implements VendingMachineState {
private VendingMachine vendingMachine;
public NoCoinState(VendingMachine vendingMachine) {
this.vendingMachine = vendingMachine;
}
@Override
public void insertCoin() {
System.out.println("投币成功");
vendingMachine.setState(vendingMachine.getHasCoinState());
}
@Override
public void ejectCoin() {
System.out.println("没有投币,无法退币");
}
@Override
public void selectProduct() {
System.out.println("请先投币");
}
@Override
public void dispense() {
System.out.println("请先投币");
}
}
// 有币状态
public class HasCoinState implements VendingMachineState {
private VendingMachine vendingMachine;
public HasCoinState(VendingMachine vendingMachine) {
this.vendingMachine = vendingMachine;
}
@Override
public void insertCoin() {
System.out.println("已经投币,请选择商品");
}
@Override
public void ejectCoin() {
System.out.println("退币成功");
vendingMachine.setState(vendingMachine.getNoCoinState());
}
@Override
public void selectProduct() {
System.out.println("选择商品成功");
vendingMachine.setState(vendingMachine.getSoldState());
}
@Override
public void dispense() {
System.out.println("请先选择商品");
}
}
// 自动售货机
public class VendingMachine {
private VendingMachineState noCoinState;
private VendingMachineState hasCoinState;
private VendingMachineState soldState;
private VendingMachineState currentState;
public VendingMachine() {
noCoinState = new NoCoinState(this);
hasCoinState = new HasCoinState(this);
soldState = new SoldState(this);
currentState = noCoinState;
}
public void insertCoin() {
currentState.insertCoin();
}
public void ejectCoin() {
currentState.ejectCoin();
}
public void selectProduct() {
currentState.selectProduct();
}
public void dispense() {
currentState.dispense();
}
public void setState(VendingMachineState state) {
currentState = state;
}
public VendingMachineState getNoCoinState() {
return noCoinState;
}
public VendingMachineState getHasCoinState() {
return hasCoinState;
}
public VendingMachineState getSoldState() {
return soldState;
}
}
📋 第五部分:模板方法模式(Template Method Pattern)
📋 模板舞者的登场 📋
┌─────────────────────────────────────┐
│ 📋 模板者:我是算法框架设计师! │
│ │
│ 🍵 咖啡:"我要冲泡咖啡!" │
│ 📋 模板者:"我来定义框架!" │
│ 🍵 茶:"我要冲泡茶!" │
│ 📋 模板者:"继续定义框架!" │
│ │
│ 💡 核心思想:算法骨架固定 │
└─────────────────────────────────────┘
🏗️ 模板方法模式UML类图
TypeError: Cannot read properties of undefined (reading 'x')
⏱️ 模板方法模式时序图
5.1 🎭 什么是模板方法模式?
一句话理解:定义算法骨架,让子类实现具体步骤,就像制作饮料的模板!
定义:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。
应用场景:算法框架、代码复用、钩子方法、流程控制
5.2 🛠️ 模板方法模式的实现
5.2.1 🏗️ 基本结构
💡 小贴士:模板方法模式就像烹饪菜谱,定义了步骤框架,具体实现可以灵活变化!
核心组件:
- AbstractClass(抽象类):定义算法框架
- ConcreteClass(具体类):实现具体步骤
- Template Method(模板方法):定义算法骨架
5.2.2 🚀 多种实现方式
实现方式 | 特点 | 推荐度 |
---|---|---|
抽象类 | 通过抽象类定义模板 | ⭐⭐⭐⭐⭐ |
钩子方法 | 提供默认实现的可选方法 | ⭐⭐⭐⭐⭐ |
算法骨架 | 固定算法流程,可变步骤 | ⭐⭐⭐⭐⭐ |
5.2.1 🏗️ 抽象类实现
// 抽象类:通过抽象类定义模板
public abstract class DataProcessor {
// 模板方法,定义算法骨架
public final void process() {
readData();
processData();
writeData();
cleanup();
}
// 抽象方法,子类必须实现
protected abstract void readData();
protected abstract void processData();
protected abstract void writeData();
// 具体方法,所有子类共享
protected void cleanup() {
System.out.println("清理资源");
}
}
public class CSVProcessor extends DataProcessor {
@Override
protected void readData() {
System.out.println("读取CSV文件");
}
@Override
protected void processData() {
System.out.println("处理CSV数据");
}
@Override
protected void writeData() {
System.out.println("写入CSV文件");
}
}
public class JSONProcessor extends DataProcessor {
@Override
protected void readData() {
System.out.println("读取JSON文件");
}
@Override
protected void processData() {
System.out.println("处理JSON数据");
}
@Override
protected void writeData() {
System.out.println("写入JSON文件");
}
}
public class XMLProcessor extends DataProcessor {
@Override
protected void readData() {
System.out.println("读取XML文件");
}
@Override
protected void processData() {
System.out.println("处理XML数据");
}
@Override
protected void writeData() {
System.out.println("写入XML文件");
}
}
5.2.2 🎣 钩子方法实现
// 钩子方法:提供默认实现的可选方法
public abstract class BeverageWithHooks {
// 模板方法
public final void prepareBeverage() {
boilWater();
brew();
pourInCup();
if (customerWantsCondiments()) {
addCondiments();
}
if (customerWantsIce()) {
addIce();
}
if (customerWantsSugar()) {
addSugar();
}
}
// 抽象方法
protected abstract void brew();
protected abstract void addCondiments();
// 具体方法
protected void boilWater() {
System.out.println("烧开水");
}
protected void pourInCup() {
System.out.println("倒入杯中");
}
// 钩子方法 - 默认实现
protected boolean customerWantsCondiments() {
return true; // 默认需要调味品
}
protected boolean customerWantsIce() {
return false; // 默认不需要冰
}
protected boolean customerWantsSugar() {
return true; // 默认需要糖
}
protected void addIce() {
System.out.println("加入冰块");
}
protected void addSugar() {
System.out.println("加入糖");
}
}
public class CoffeeWithHooks extends BeverageWithHooks {
private boolean wantsCondiments = true;
private boolean wantsIce = false;
private boolean wantsSugar = true;
public void setWantsCondiments(boolean wantsCondiments) {
this.wantsCondiments = wantsCondiments;
}
public void setWantsIce(boolean wantsIce) {
this.wantsIce = wantsIce;
}
public void setWantsSugar(boolean wantsSugar) {
this.wantsSugar = wantsSugar;
}
@Override
protected void brew() {
System.out.println("用沸水冲泡咖啡");
}
@Override
protected void addCondiments() {
System.out.println("加入牛奶");
}
@Override
protected boolean customerWantsCondiments() {
return wantsCondiments;
}
@Override
protected boolean customerWantsIce() {
return wantsIce;
}
@Override
protected boolean customerWantsSugar() {
return wantsSugar;
}
}
public class TeaWithHooks extends BeverageWithHooks {
private boolean wantsLemon = true;
public void setWantsLemon(boolean wantsLemon) {
this.wantsLemon = wantsLemon;
}
@Override
protected void brew() {
System.out.println("用沸水浸泡茶叶");
}
@Override
protected void addCondiments() {
if (wantsLemon) {
System.out.println("加入柠檬");
}
}
@Override
protected boolean customerWantsCondiments() {
return wantsLemon;
}
@Override
protected boolean customerWantsSugar() {
return false; // 茶通常不需要糖
}
}
5.2.3 🔄 算法骨架实现
// 算法骨架:固定算法流程,可变步骤
public abstract class AlgorithmSkeleton {
// 模板方法,定义算法骨架
public final void execute() {
initialize();
preprocess();
executeCore();
postprocess();
cleanup();
}
// 抽象方法,子类必须实现
protected abstract void initialize();
protected abstract void executeCore();
// 钩子方法,子类可以选择覆盖
protected void preprocess() {
System.out.println("默认预处理");
}
protected void postprocess() {
System.out.println("默认后处理");
}
protected void cleanup() {
System.out.println("默认清理");
}
// 具体方法,所有子类共享
protected void log(String message) {
System.out.println("日志: " + message);
}
protected void validate() {
System.out.println("验证数据");
}
}
public class SortingAlgorithm extends AlgorithmSkeleton {
private int[] data;
public SortingAlgorithm(int[] data) {
this.data = data;
}
@Override
protected void initialize() {
log("初始化排序算法");
validate();
}
@Override
protected void executeCore() {
log("执行排序");
Arrays.sort(data);
}
@Override
protected void postprocess() {
log("排序完成,结果: " + Arrays.toString(data));
}
}
public class SearchAlgorithm extends AlgorithmSkeleton {
private int[] data;
private int target;
public SearchAlgorithm(int[] data, int target) {
this.data = data;
this.target = target;
}
@Override
protected void initialize() {
log("初始化搜索算法");
validate();
}
@Override
protected void preprocess() {
log("预处理:对数据进行排序");
Arrays.sort(data);
}
@Override
protected void executeCore() {
log("执行二分搜索");
int result = Arrays.binarySearch(data, target);
if (result >= 0) {
log("找到目标值,位置: " + result);
} else {
log("未找到目标值");
}
}
@Override
protected void cleanup() {
log("清理搜索资源");
}
}
public class CompressionAlgorithm extends AlgorithmSkeleton {
private byte[] data;
public CompressionAlgorithm(byte[] data) {
this.data = data;
}
@Override
protected void initialize() {
log("初始化压缩算法");
validate();
}
@Override
protected void executeCore() {
log("执行数据压缩");
// 模拟压缩过程
System.out.println("压缩前大小: " + data.length + " 字节");
System.out.println("压缩后大小: " + (data.length / 2) + " 字节");
}
@Override
protected void postprocess() {
log("压缩完成,计算压缩率");
System.out.println("压缩率: 50%");
}
}
5.2.3 🎯 标准实现示例
// 抽象类 - 定义算法骨架
public abstract class AbstractClass {
// 模板方法 - 定义算法流程
public final void templateMethod() {
primitiveOperation1();
primitiveOperation2();
concreteOperation();
hook();
}
// 抽象方法 - 子类必须实现
protected abstract void primitiveOperation1();
protected abstract void primitiveOperation2();
// 具体方法 - 所有子类共享
protected void concreteOperation() {
System.out.println("具体操作");
}
// 钩子方法 - 子类可选覆盖
protected void hook() {
// 默认实现,子类可以覆盖
}
}
// 具体类A - 实现具体步骤
public class ConcreteClassA extends AbstractClass {
@Override
protected void primitiveOperation1() {
System.out.println("具体类A的操作1");
}
@Override
protected void primitiveOperation2() {
System.out.println("具体类A的操作2");
}
}
// 具体类B - 实现具体步骤并覆盖钩子方法
public class ConcreteClassB extends AbstractClass {
@Override
protected void primitiveOperation1() {
System.out.println("具体类B的操作1");
}
@Override
protected void primitiveOperation2() {
System.out.println("具体类B的操作2");
}
@Override
protected void hook() {
System.out.println("具体类B的钩子方法");
}
}
5.2.4 🎯 实际应用示例
// 饮料抽象类
public abstract class Beverage {
// 模板方法
public final void prepareBeverage() {
boilWater();
brew();
pourInCup();
if (customerWantsCondiments()) {
addCondiments();
}
}
// 抽象方法
protected abstract void brew();
protected abstract void addCondiments();
// 具体方法
protected void boilWater() {
System.out.println("烧开水");
}
protected void pourInCup() {
System.out.println("倒入杯中");
}
// 钩子方法
protected boolean customerWantsCondiments() {
return true;
}
}
// 咖啡
public class Coffee extends Beverage {
@Override
protected void brew() {
System.out.println("用沸水冲泡咖啡");
}
@Override
protected void addCondiments() {
System.out.println("加入糖和牛奶");
}
}
// 茶
public class Tea extends Beverage {
private boolean wantsCondiments = true;
public void setWantsCondiments(boolean wantsCondiments) {
this.wantsCondiments = wantsCondiments;
}
@Override
protected void brew() {
System.out.println("用沸水浸泡茶叶");
}
@Override
protected void addCondiments() {
System.out.println("加入柠檬");
}
@Override
protected boolean customerWantsCondiments() {
return wantsCondiments;
}
}
🔍 第六部分:迭代器模式(Iterator Pattern)
🔍 迭代舞者的登场 🔍
┌─────────────────────────────────────┐
│ 🔍 迭代者:我是集合遍历专家! │
│ │
│ 📚 书架:"我有好多书!" │
│ 🔍 迭代者:"我来遍历它们!" │
│ 📚 书架:"我有不同结构!" │
│ 🔍 迭代者:"继续遍历它们!" │
│ │
│ 💡 核心思想:统一遍历接口 │
└─────────────────────────────────────┘
🏗️ 迭代器模式UML类图
TypeError: Cannot read properties of undefined (reading 'x')
⏱️ 迭代器模式时序图
6.1 🎭 什么是迭代器模式?
一句话理解:提供统一的接口来遍历集合,隐藏内部结构!
定义:提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示。
应用场景:集合遍历、数据结构访问、分页查询、数据库结果集
6.2 🛠️ 迭代器模式的实现
6.2.1 🏗️ 基本结构
💡 小贴士:迭代器模式就像图书馆的图书管理员,统一管理各种书籍的访问方式!
核心组件:
- Iterator(迭代器):定义访问元素的接口
- ConcreteIterator(具体迭代器):实现迭代器接口
- Aggregate(聚合):定义创建迭代器的接口
- ConcreteAggregate(具体聚合):实现聚合接口
6.2.2 🚀 多种实现方式
实现方式 | 特点 | 推荐度 |
---|---|---|
外部迭代器 | 客户端控制迭代过程 | ⭐⭐⭐⭐ |
内部迭代器 | 聚合对象控制迭代过程 | ⭐⭐⭐ |
泛型迭代器 | 支持不同类型的元素 | ⭐⭐⭐⭐⭐ |
外部迭代器实现:
// 外部迭代器:客户端控制迭代过程
public interface ExternalIterator<T> {
boolean hasNext();
T next();
void remove();
}
public interface ExternalAggregate<T> {
ExternalIterator<T> createIterator();
}
public class BookShelf implements ExternalAggregate<Book> {
private List<Book> books = new ArrayList<>();
public void appendBook(Book book) {
books.add(book);
}
public Book getBookAt(int index) {
return books.get(index);
}
public int getLength() {
return books.size();
}
@Override
public ExternalIterator<Book> createIterator() {
return new BookShelfIterator(this);
}
}
public class BookShelfIterator implements ExternalIterator<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() {
if (hasNext()) {
return bookShelf.getBookAt(index++);
}
throw new NoSuchElementException();
}
@Override
public void remove() {
// 实现删除逻辑
throw new UnsupportedOperationException("不支持删除操作");
}
}
public class Book {
private String name;
private String author;
public Book(String name, String author) {
this.name = name;
this.author = author;
}
public String getName() { return name; }
public String getAuthor() { return author; }
@Override
public String toString() {
return "《" + name + "》 by " + author;
}
}
6.2.2 🔄 内部迭代器实现
// 内部迭代器:聚合对象控制迭代过程
public interface InternalIterator<T> {
void iterate(Consumer<T> action);
}
public class BookShelfInternal implements InternalIterator<Book> {
private List<Book> books = new ArrayList<>();
public void appendBook(Book book) {
books.add(book);
}
@Override
public void iterate(Consumer<Book> action) {
for (Book book : books) {
action.accept(book);
}
}
// 提供过滤功能
public void iterateWithFilter(Predicate<Book> filter, Consumer<Book> action) {
for (Book book : books) {
if (filter.test(book)) {
action.accept(book);
}
}
}
// 提供转换功能
public <R> List<R> map(Function<Book, R> mapper) {
List<R> result = new ArrayList<>();
for (Book book : books) {
result.add(mapper.apply(book));
}
return result;
}
}
// 使用示例
public class InternalIteratorDemo {
public static void main(String[] args) {
BookShelfInternal shelf = new BookShelfInternal();
shelf.appendBook(new Book("Java编程思想", "Bruce Eckel"));
shelf.appendBook(new Book("设计模式", "GoF"));
shelf.appendBook(new Book("算法导论", "Thomas H. Cormen"));
// 简单迭代
System.out.println("=== 所有书籍 ===");
shelf.iterate(book -> System.out.println(book));
// 过滤迭代
System.out.println("\n=== Java相关书籍 ===");
shelf.iterateWithFilter(
book -> book.getName().contains("Java"),
book -> System.out.println(book)
);
// 转换迭代
System.out.println("\n=== 书籍名称列表 ===");
List<String> bookNames = shelf.map(Book::getName);
bookNames.forEach(System.out::println);
}
}
泛型迭代器实现:
// 泛型迭代器:支持不同类型的元素
public interface GenericIterator<T> {
boolean hasNext();
T next();
void remove();
void reset();
}
public interface GenericAggregate<T> {
GenericIterator<T> createIterator();
int size();
T get(int index);
void add(T element);
void remove(T element);
}
public class GenericList<T> implements GenericAggregate<T> {
private List<T> elements = new ArrayList<>();
@Override
public GenericIterator<T> createIterator() {
return new GenericListIterator<>(this);
}
@Override
public int size() {
return elements.size();
}
@Override
public T get(int index) {
return elements.get(index);
}
@Override
public void add(T element) {
elements.add(element);
}
@Override
public void remove(T element) {
elements.remove(element);
}
}
public class GenericListIterator<T> implements GenericIterator<T> {
private GenericAggregate<T> aggregate;
private int currentIndex;
public GenericListIterator(GenericAggregate<T> aggregate) {
this.aggregate = aggregate;
this.currentIndex = 0;
}
@Override
public boolean hasNext() {
return currentIndex < aggregate.size();
}
@Override
public T next() {
if (hasNext()) {
return aggregate.get(currentIndex++);
}
throw new NoSuchElementException();
}
@Override
public void remove() {
// 实现删除逻辑
throw new UnsupportedOperationException("不支持删除操作");
}
@Override
public void reset() {
currentIndex = 0;
}
}
// 双向迭代器
public interface BidirectionalIterator<T> extends GenericIterator<T> {
boolean hasPrevious();
T previous();
int nextIndex();
int previousIndex();
}
public class BidirectionalListIterator<T> implements BidirectionalIterator<T> {
private GenericAggregate<T> aggregate;
private int currentIndex;
public BidirectionalListIterator(GenericAggregate<T> aggregate) {
this.aggregate = aggregate;
this.currentIndex = 0;
}
@Override
public boolean hasNext() {
return currentIndex < aggregate.size();
}
@Override
public T next() {
if (hasNext()) {
return aggregate.get(currentIndex++);
}
throw new NoSuchElementException();
}
@Override
public boolean hasPrevious() {
return currentIndex > 0;
}
@Override
public T previous() {
if (hasPrevious()) {
return aggregate.get(--currentIndex);
}
throw new NoSuchElementException();
}
@Override
public int nextIndex() {
return currentIndex;
}
@Override
public int previousIndex() {
return currentIndex - 1;
}
@Override
public void remove() {
throw new UnsupportedOperationException("不支持删除操作");
}
@Override
public void reset() {
currentIndex = 0;
}
}
// 使用示例
public class GenericIteratorDemo {
public static void main(String[] args) {
// 字符串列表
GenericList<String> stringList = new GenericList<>();
stringList.add("Apple");
stringList.add("Banana");
stringList.add("Cherry");
System.out.println("=== 字符串列表 ===");
GenericIterator<String> stringIterator = stringList.createIterator();
while (stringIterator.hasNext()) {
System.out.println(stringIterator.next());
}
// 整数列表
GenericList<Integer> intList = new GenericList<>();
intList.add(1);
intList.add(2);
intList.add(3);
intList.add(4);
intList.add(5);
System.out.println("\n=== 整数列表 ===");
GenericIterator<Integer> intIterator = intList.createIterator();
while (intIterator.hasNext()) {
System.out.println(intIterator.next());
}
// 双向迭代
System.out.println("\n=== 双向迭代 ===");
BidirectionalIterator<Integer> biIterator = new BidirectionalListIterator<>(intList);
while (biIterator.hasNext()) {
System.out.println("前进: " + biIterator.next());
}
while (biIterator.hasPrevious()) {
System.out.println("后退: " + biIterator.previous());
}
}
}
6.2.3 🎯 标准实现示例
// 迭代器接口 - 定义遍历操作
public interface Iterator<T> {
boolean hasNext();
T next();
void remove();
}
// 聚合接口 - 定义创建迭代器的方法
public interface Aggregate<T> {
Iterator<T> createIterator();
}
// 具体聚合 - 实现聚合接口
public class ConcreteAggregate<T> implements Aggregate<T> {
private List<T> items = new ArrayList<>();
public void add(T item) {
items.add(item);
}
public T get(int index) {
return items.get(index);
}
public int size() {
return items.size();
}
@Override
public Iterator<T> createIterator() {
return new ConcreteIterator<>(this);
}
}
// 具体迭代器 - 实现遍历逻辑
public class ConcreteIterator<T> implements Iterator<T> {
private ConcreteAggregate<T> aggregate;
private int current = 0;
public ConcreteIterator(ConcreteAggregate<T> aggregate) {
this.aggregate = aggregate;
}
@Override
public boolean hasNext() {
return current < aggregate.size();
}
@Override
public T next() {
if (hasNext()) {
return aggregate.get(current++);
}
throw new NoSuchElementException();
}
@Override
public void remove() {
// 实现删除逻辑
}
}
6.2.4 🎯 实际应用示例
// 书类
public class Book {
private String name;
private String author;
public Book(String name, String author) {
this.name = name;
this.author = author;
}
public String getName() {
return name;
}
public String getAuthor() {
return author;
}
@Override
public String toString() {
return "《" + name + "》 by " + author;
}
}
// 书架
public class BookShelf implements Aggregate<Book> {
private List<Book> books = new ArrayList<>();
public void appendBook(Book book) {
books.add(book);
}
public Book getBookAt(int index) {
return books.get(index);
}
public int getLength() {
return books.size();
}
@Override
public Iterator<Book> createIterator() {
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() {
if (hasNext()) {
return bookShelf.getBookAt(index++);
}
throw new NoSuchElementException();
}
@Override
public void remove() {
// 实现删除逻辑
}
}
⛓️ 第七部分:责任链模式(Chain of Responsibility Pattern)
⛓️ 责任链舞者的登场 ⛓️
┌─────────────────────────────────────┐
│ ⛓️ 责任链:我是请求处理链! │
│ │
│ 📝 请求:"我要请假3天!" │
│ ⛓️ 责任链:"我来传递请求!" │
│ 📝 请求:"我要请假10天!" │
│ ⛓️ 责任链:"继续传递请求!" │
│ │
│ 💡 核心思想:请求沿链传递 │
└─────────────────────────────────────┘
🏗️ 责任链模式UML类图
TypeError: Cannot read properties of undefined (reading 'x')
⏱️ 责任链模式时序图
7.1 🎭 什么是责任链模式?
一句话理解:请求沿着处理链传递,直到找到合适的处理器!
定义:为解除请求的发送者和接收者之间耦合,而使多个对象都有机会处理这个请求。
应用场景:请求处理、异常处理、过滤器链、审批流程、日志处理
7.2 🛠️ 责任链模式的实现
7.2.1 🏗️ 基本结构
💡 小贴士:责任链模式就像公司审批流程,请求沿着链条传递,直到被处理!
核心组件:
- Handler(处理器):定义处理请求的接口
- ConcreteHandler(具体处理器):实现处理器接口
- Client(客户端):发起请求的对象
7.2.2 🚀 多种实现方式
实现方式 | 特点 | 推荐度 |
---|---|---|
纯责任链 | 请求必须被处理 | ⭐⭐⭐⭐ |
不纯责任链 | 请求可能不被处理 | ⭐⭐⭐ |
动态责任链 | 运行时动态构建链 | ⭐⭐⭐⭐⭐ |
7.2.1 ⛓️ 纯责任链实现
// 纯责任链:请求必须被处理
public abstract class PureHandler {
protected PureHandler successor;
public void setSuccessor(PureHandler successor) {
this.successor = successor;
}
public abstract void handleRequest(int request);
}
public class ConcreteHandlerA extends PureHandler {
@Override
public void handleRequest(int request) {
if (request >= 0 && request < 10) {
System.out.println("处理器A处理请求: " + request);
} else if (successor != null) {
successor.handleRequest(request);
} else {
// 纯责任链:必须有处理器处理请求
System.out.println("默认处理器处理请求: " + request);
}
}
}
public class ConcreteHandlerB extends PureHandler {
@Override
public void handleRequest(int request) {
if (request >= 10 && request < 20) {
System.out.println("处理器B处理请求: " + request);
} else if (successor != null) {
successor.handleRequest(request);
} else {
System.out.println("默认处理器处理请求: " + request);
}
}
}
public class ConcreteHandlerC extends PureHandler {
@Override
public void handleRequest(int request) {
if (request >= 20 && request < 30) {
System.out.println("处理器C处理请求: " + request);
} else if (successor != null) {
successor.handleRequest(request);
} else {
System.out.println("默认处理器处理请求: " + request);
}
}
}
public class DefaultHandler extends PureHandler {
@Override
public void handleRequest(int request) {
System.out.println("默认处理器处理请求: " + request);
}
}
不纯责任链实现:
// 不纯责任链:请求可能不被处理
public abstract class ImpureHandler {
protected ImpureHandler successor;
public void setSuccessor(ImpureHandler successor) {
this.successor = successor;
}
public abstract boolean handleRequest(int request);
}
public class ImpureHandlerA extends ImpureHandler {
@Override
public boolean handleRequest(int request) {
if (request >= 0 && request < 10) {
System.out.println("处理器A处理请求: " + request);
return true; // 请求被处理
} else if (successor != null) {
return successor.handleRequest(request);
} else {
System.out.println("请求未被处理: " + request);
return false; // 请求未被处理
}
}
}
public class ImpureHandlerB extends ImpureHandler {
@Override
public boolean handleRequest(int request) {
if (request >= 10 && request < 20) {
System.out.println("处理器B处理请求: " + request);
return true;
} else if (successor != null) {
return successor.handleRequest(request);
} else {
System.out.println("请求未被处理: " + request);
return false;
}
}
}
public class ImpureHandlerC extends ImpureHandler {
@Override
public boolean handleRequest(int request) {
if (request >= 20 && request < 30) {
System.out.println("处理器C处理请求: " + request);
return true;
} else if (successor != null) {
return successor.handleRequest(request);
} else {
System.out.println("请求未被处理: " + request);
return false;
}
}
}
动态责任链实现:
// 动态责任链:运行时动态构建链
public interface DynamicHandler {
boolean handle(Request request);
void setNext(DynamicHandler next);
DynamicHandler getNext();
}
public class Request {
private String type;
private Object data;
private Map<String, Object> context = new HashMap<>();
public Request(String type, Object data) {
this.type = type;
this.data = data;
}
public String getType() { return type; }
public Object getData() { return data; }
public void setContext(String key, Object value) { context.put(key, value); }
public Object getContext(String key) { return context.get(key); }
}
public class AuthenticationHandler implements DynamicHandler {
private DynamicHandler next;
@Override
public boolean handle(Request request) {
System.out.println("认证处理器处理请求: " + request.getType());
// 模拟认证逻辑
if ("admin".equals(request.getContext("user"))) {
request.setContext("authenticated", true);
System.out.println("认证成功");
return next != null ? next.handle(request) : true;
} else {
System.out.println("认证失败");
return false;
}
}
@Override
public void setNext(DynamicHandler next) {
this.next = next;
}
@Override
public DynamicHandler getNext() {
return next;
}
}
public class AuthorizationHandler implements DynamicHandler {
private DynamicHandler next;
@Override
public boolean handle(Request request) {
System.out.println("授权处理器处理请求: " + request.getType());
// 模拟授权逻辑
if (Boolean.TRUE.equals(request.getContext("authenticated"))) {
request.setContext("authorized", true);
System.out.println("授权成功");
return next != null ? next.handle(request) : true;
} else {
System.out.println("授权失败");
return false;
}
}
@Override
public void setNext(DynamicHandler next) {
this.next = next;
}
@Override
public DynamicHandler getNext() {
return next;
}
}
public class LoggingHandler implements DynamicHandler {
private DynamicHandler next;
@Override
public boolean handle(Request request) {
System.out.println("日志处理器处理请求: " + request.getType());
System.out.println("记录请求日志: " + request.getData());
boolean result = next != null ? next.handle(request) : true;
System.out.println("请求处理结果: " + result);
return result;
}
@Override
public void setNext(DynamicHandler next) {
this.next = next;
}
@Override
public DynamicHandler getNext() {
return next;
}
}
public class BusinessHandler implements DynamicHandler {
private DynamicHandler next;
@Override
public boolean handle(Request request) {
System.out.println("业务处理器处理请求: " + request.getType());
// 模拟业务逻辑
if (Boolean.TRUE.equals(request.getContext("authorized"))) {
System.out.println("执行业务逻辑: " + request.getData());
return true;
} else {
System.out.println("业务处理失败:未授权");
return false;
}
}
@Override
public void setNext(DynamicHandler next) {
this.next = next;
}
@Override
public DynamicHandler getNext() {
return next;
}
}
public class DynamicChainBuilder {
private List<DynamicHandler> handlers = new ArrayList<>();
public DynamicChainBuilder addHandler(DynamicHandler handler) {
handlers.add(handler);
return this;
}
public DynamicHandler build() {
if (handlers.isEmpty()) {
return null;
}
// 构建责任链
for (int i = 0; i < handlers.size() - 1; i++) {
handlers.get(i).setNext(handlers.get(i + 1));
}
return handlers.get(0);
}
}
// 使用示例
public class DynamicChainDemo {
public static void main(String[] args) {
// 动态构建责任链
DynamicChainBuilder builder = new DynamicChainBuilder();
DynamicHandler chain = builder
.addHandler(new LoggingHandler())
.addHandler(new AuthenticationHandler())
.addHandler(new AuthorizationHandler())
.addHandler(new BusinessHandler())
.build();
// 创建请求
Request request = new Request("userAction", "执行用户操作");
request.setContext("user", "admin");
// 处理请求
System.out.println("=== 处理请求 ===");
boolean result = chain.handle(request);
System.out.println("最终结果: " + result);
// 动态修改责任链
System.out.println("\n=== 动态修改责任链 ===");
DynamicChainBuilder newBuilder = new DynamicChainBuilder();
DynamicHandler newChain = newBuilder
.addHandler(new LoggingHandler())
.addHandler(new BusinessHandler())
.build();
Request newRequest = new Request("simpleAction", "简单操作");
boolean newResult = newChain.handle(newRequest);
System.out.println("新链处理结果: " + newResult);
}
}
7.2.3 🎯 标准实现示例
// 处理器抽象类 - 定义处理请求的接口
public abstract class Handler {
protected Handler successor;
public void setSuccessor(Handler successor) {
this.successor = successor;
}
public abstract void handleRequest(int request);
}
// 具体处理器A - 处理特定范围的请求
public class ConcreteHandlerA extends Handler {
@Override
public void handleRequest(int request) {
if (request >= 0 && request < 10) {
System.out.println("处理器A处理请求: " + request);
} else if (successor != null) {
successor.handleRequest(request);
}
}
}
// 具体处理器B - 处理特定范围的请求
public class ConcreteHandlerB extends Handler {
@Override
public void handleRequest(int request) {
if (request >= 10 && request < 20) {
System.out.println("处理器B处理请求: " + request);
} else if (successor != null) {
successor.handleRequest(request);
}
}
}
// 具体处理器C - 处理特定范围的请求
public class ConcreteHandlerC extends Handler {
@Override
public void handleRequest(int request) {
if (request >= 20 && request < 30) {
System.out.println("处理器C处理请求: " + request);
} else if (successor != null) {
successor.handleRequest(request);
} else {
System.out.println("没有处理器能处理请求: " + request);
}
}
}
7.2.4 🎯 实际应用示例
// 请假请求
public class LeaveRequest {
private String name;
private int leaveDays;
private String reason;
public LeaveRequest(String name, int leaveDays, String reason) {
this.name = name;
this.leaveDays = leaveDays;
this.reason = reason;
}
public String getName() {
return name;
}
public int getLeaveDays() {
return leaveDays;
}
public String getReason() {
return reason;
}
}
// 审批者抽象类
public abstract class Approver {
protected Approver successor;
protected String name;
public Approver(String name) {
this.name = name;
}
public void setSuccessor(Approver successor) {
this.successor = successor;
}
public abstract void processRequest(LeaveRequest request);
}
// 组长
public class GroupLeader extends Approver {
public GroupLeader(String name) {
super(name);
}
@Override
public void processRequest(LeaveRequest request) {
if (request.getLeaveDays() <= 3) {
System.out.println("组长 " + name + " 审批员工 " + request.getName() +
" 的请假申请,请假天数:" + request.getLeaveDays() + " 天");
} else if (successor != null) {
successor.processRequest(request);
}
}
}
// 经理
public class Manager extends Approver {
public Manager(String name) {
super(name);
}
@Override
public void processRequest(LeaveRequest request) {
if (request.getLeaveDays() <= 7) {
System.out.println("经理 " + name + " 审批员工 " + request.getName() +
" 的请假申请,请假天数:" + request.getLeaveDays() + " 天");
} else if (successor != null) {
successor.processRequest(request);
}
}
}
🤝 第八部分:中介者模式(Mediator Pattern)
🤝 中介舞者的登场 🤝
┌─────────────────────────────────────┐
│ 🤝 中介者:我是对象交互协调员! │
│ │
│ 👤 用户A:"我要发消息给用户B!" │
│ 🤝 中介者:"我来协调交互!" │
│ 👤 用户B:"我要回复用户A!" │
│ 🤝 中介者:"继续协调交互!" │
│ │
│ 💡 核心思想:集中控制交互 │
└─────────────────────────────────────┘
🏗️ 中介者模式UML类图
TypeError: Cannot read properties of undefined (reading 'x')
⏱️ 中介者模式时序图
8.1 🎭 什么是中介者模式?
一句话理解:通过中介者集中管理对象间的交互,降低耦合度!
定义:用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显式地相互引用。
应用场景:聊天系统、事件总线、服务注册中心、GUI组件交互、工作流引擎
8.2 🛠️ 中介者模式的实现
8.2.1 🏗️ 基本结构
💡 小贴士:中介者模式就像聊天室,所有用户通过中介者进行通信,避免直接耦合!
核心组件:
- Mediator(中介者):定义对象间通信的接口
- ConcreteMediator(具体中介者):实现中介者接口
- Colleague(同事):需要通信的对象
- ConcreteColleague(具体同事):实现同事接口
8.2.2 🚀 多种实现方式
实现方式 | 特点 | 推荐度 |
---|---|---|
简单中介者 | 一对一交互协调 | ⭐⭐⭐⭐ |
复杂中介者 | 多对多交互协调 | ⭐⭐⭐⭐⭐ |
事件中介者 | 基于事件的松耦合 | ⭐⭐⭐⭐⭐ |
8.2.1 🤝 简单中介者实现
// 简单中介者:一对一交互协调
public interface SimpleMediator {
void send(String message, SimpleColleague colleague);
}
public abstract class SimpleColleague {
protected SimpleMediator mediator;
public SimpleColleague(SimpleMediator mediator) {
this.mediator = mediator;
}
public abstract void send(String message);
public abstract void receive(String message);
}
public class SimpleColleagueA extends SimpleColleague {
private String name;
public SimpleColleagueA(String name, SimpleMediator mediator) {
super(mediator);
this.name = name;
}
@Override
public void send(String message) {
System.out.println(name + " 发送消息: " + message);
mediator.send(message, this);
}
@Override
public void receive(String message) {
System.out.println(name + " 收到消息: " + message);
}
public String getName() {
return name;
}
}
public class SimpleColleagueB extends SimpleColleague {
private String name;
public SimpleColleagueB(String name, SimpleMediator mediator) {
super(mediator);
this.name = name;
}
@Override
public void send(String message) {
System.out.println(name + " 发送消息: " + message);
mediator.send(message, this);
}
@Override
public void receive(String message) {
System.out.println(name + " 收到消息: " + message);
}
public String getName() {
return name;
}
}
public class SimpleConcreteMediator implements SimpleMediator {
private SimpleColleagueA colleagueA;
private SimpleColleagueB colleagueB;
public void setColleagueA(SimpleColleagueA colleagueA) {
this.colleagueA = colleagueA;
}
public void setColleagueB(SimpleColleagueB colleagueB) {
this.colleagueB = colleagueB;
}
@Override
public void send(String message, SimpleColleague colleague) {
if (colleague == colleagueA) {
colleagueB.receive(message);
} else if (colleague == colleagueB) {
colleagueA.receive(message);
}
}
}
8.2.2 🔄 复杂中介者实现
// 复杂中介者:多对多交互协调
public interface ComplexMediator {
void send(String message, ComplexColleague sender);
void addColleague(ComplexColleague colleague);
void removeColleague(ComplexColleague colleague);
}
public abstract class ComplexColleague {
protected ComplexMediator mediator;
protected String name;
public ComplexColleague(String name, ComplexMediator mediator) {
this.name = name;
this.mediator = mediator;
}
public abstract void send(String message);
public abstract void receive(String message);
public String getName() {
return name;
}
}
public class ChatUser extends ComplexColleague {
public ChatUser(String name, ComplexMediator mediator) {
super(name, mediator);
}
@Override
public void send(String message) {
System.out.println(name + " 发送消息: " + message);
mediator.send(name + ": " + message, this);
}
@Override
public void receive(String message) {
System.out.println(name + " 收到消息: " + message);
}
}
public class ChatRoom implements ComplexMediator {
private List<ChatUser> users = new ArrayList<>();
@Override
public void addColleague(ComplexColleague colleague) {
if (colleague instanceof ChatUser) {
users.add((ChatUser) colleague);
System.out.println(colleague.getName() + " 加入聊天室");
}
}
@Override
public void removeColleague(ComplexColleague colleague) {
if (colleague instanceof ChatUser) {
users.remove(colleague);
System.out.println(colleague.getName() + " 离开聊天室");
}
}
@Override
public void send(String message, ComplexColleague sender) {
for (ChatUser user : users) {
if (user != sender) {
user.receive(message);
}
}
}
public void broadcast(String message) {
System.out.println("系统广播: " + message);
for (ChatUser user : users) {
user.receive("系统: " + message);
}
}
}
事件中介者实现:
// 事件中介者:基于事件的松耦合
public class Event {
private String type;
private Object data;
private Object source;
public Event(String type, Object data, Object source) {
this.type = type;
this.data = data;
this.source = source;
}
public String getType() { return type; }
public Object getData() { return data; }
public Object getSource() { return source; }
}
public interface EventListener {
void onEvent(Event event);
}
public interface EventMediator {
void subscribe(String eventType, EventListener listener);
void unsubscribe(String eventType, EventListener listener);
void publish(Event event);
}
public class EventBus implements EventMediator {
private Map<String, List<EventListener>> listeners = new HashMap<>();
@Override
public void subscribe(String eventType, EventListener listener) {
listeners.computeIfAbsent(eventType, k -> new ArrayList<>()).add(listener);
System.out.println("订阅事件: " + eventType);
}
@Override
public void unsubscribe(String eventType, EventListener listener) {
List<EventListener> eventListeners = listeners.get(eventType);
if (eventListeners != null) {
eventListeners.remove(listener);
System.out.println("取消订阅事件: " + eventType);
}
}
@Override
public void publish(Event event) {
List<EventListener> eventListeners = listeners.get(event.getType());
if (eventListeners != null) {
for (EventListener listener : eventListeners) {
listener.onEvent(event);
}
}
}
}
public class UIComponent {
private String name;
private EventMediator mediator;
public UIComponent(String name, EventMediator mediator) {
this.name = name;
this.mediator = mediator;
}
public void click() {
System.out.println(name + " 被点击");
Event event = new Event("click", "点击事件", this);
mediator.publish(event);
}
public void change(String value) {
System.out.println(name + " 值改变为: " + value);
Event event = new Event("change", value, this);
mediator.publish(event);
}
public String getName() {
return name;
}
}
public class Button extends UIComponent {
public Button(String name, EventMediator mediator) {
super(name, mediator);
}
}
public class TextField extends UIComponent {
public TextField(String name, EventMediator mediator) {
super(name, mediator);
}
}
public class Label extends UIComponent {
public Label(String name, EventMediator mediator) {
super(name, mediator);
}
}
public class UIEventHandler implements EventListener {
private String name;
public UIEventHandler(String name) {
this.name = name;
}
@Override
public void onEvent(Event event) {
System.out.println(name + " 处理事件: " + event.getType() +
" 数据: " + event.getData() +
" 来源: " + ((UIComponent)event.getSource()).getName());
// 根据事件类型执行不同的处理逻辑
switch (event.getType()) {
case "click":
handleClick(event);
break;
case "change":
handleChange(event);
break;
}
}
private void handleClick(Event event) {
System.out.println("处理点击事件");
}
private void handleChange(Event event) {
System.out.println("处理值改变事件");
}
}
// 使用示例
public class EventMediatorDemo {
public static void main(String[] args) {
EventBus eventBus = new EventBus();
// 创建UI组件
Button button = new Button("提交按钮", eventBus);
TextField textField = new TextField("用户名输入框", eventBus);
Label label = new Label("状态标签", eventBus);
// 创建事件处理器
UIEventHandler clickHandler = new UIEventHandler("点击处理器");
UIEventHandler changeHandler = new UIEventHandler("改变处理器");
// 订阅事件
eventBus.subscribe("click", clickHandler);
eventBus.subscribe("change", changeHandler);
// 模拟用户交互
System.out.println("=== 模拟用户交互 ===");
textField.change("张三");
button.click();
// 取消订阅
eventBus.unsubscribe("click", clickHandler);
System.out.println("\n=== 取消订阅后 ===");
button.click(); // 这次点击不会被处理
}
}
8.2.3 🎯 标准实现示例
// 中介者接口 - 定义同事间交互的方法
public interface Mediator {
void send(String message, Colleague colleague);
}
// 同事抽象类 - 需要交互的对象
public abstract class Colleague {
protected Mediator mediator;
public Colleague(Mediator mediator) {
this.mediator = mediator;
}
public abstract void send(String message);
public abstract void receive(String message);
}
// 具体同事A - 实现同事A的行为
public class ConcreteColleagueA extends Colleague {
public ConcreteColleagueA(Mediator mediator) {
super(mediator);
}
@Override
public void send(String message) {
System.out.println("同事A发送消息: " + message);
mediator.send(message, this);
}
@Override
public void receive(String message) {
System.out.println("同事A收到消息: " + message);
}
}
// 具体同事B - 实现同事B的行为
public class ConcreteColleagueB extends Colleague {
public ConcreteColleagueB(Mediator mediator) {
super(mediator);
}
@Override
public void send(String message) {
System.out.println("同事B发送消息: " + message);
mediator.send(message, this);
}
@Override
public void receive(String message) {
System.out.println("同事B收到消息: " + message);
}
}
// 具体中介者 - 实现交互逻辑
public class ConcreteMediator implements Mediator {
private ConcreteColleagueA colleagueA;
private ConcreteColleagueB colleagueB;
public void setColleagueA(ConcreteColleagueA colleagueA) {
this.colleagueA = colleagueA;
}
public void setColleagueB(ConcreteColleagueB colleagueB) {
this.colleagueB = colleagueB;
}
@Override
public void send(String message, Colleague colleague) {
if (colleague == colleagueA) {
colleagueB.receive(message);
} else if (colleague == colleagueB) {
colleagueA.receive(message);
}
}
}
8.2.4 🎯 实际应用示例
// 聊天室中介者
public class ChatRoom implements Mediator {
private List<User> users = new ArrayList<>();
public void addUser(User user) {
users.add(user);
}
@Override
public void send(String message, Colleague colleague) {
for (User user : users) {
if (user != colleague) {
user.receive(message);
}
}
}
}
// 用户
public class User extends Colleague {
private String name;
public User(String name, Mediator mediator) {
super(mediator);
this.name = name;
}
@Override
public void send(String message) {
System.out.println(name + " 发送消息: " + message);
mediator.send(name + ": " + message, this);
}
@Override
public void receive(String message) {
System.out.println(name + " 收到消息: " + message);
}
public String getName() {
return name;
}
}
👁️ 第九部分:访问者模式(Visitor Pattern)
👁️ 访问舞者的登场 👁️
┌─────────────────────────────────────┐
│ 👁️ 访问者:我是元素操作专家! │
│ │
│ 📄 文档:"我有段落和图片!" │
│ 👁️ 访问者:"我来操作它们!" │
│ 📄 文档:"我要生成HTML!" │
│ 👁️ 访问者:"继续操作它们!" │
│ │
│ 💡 核心思想:双重分发机制 │
└─────────────────────────────────────┘
🏗️ 访问者模式UML类图
TypeError: Cannot read properties of undefined (reading 'x')
⏱️ 访问者模式时序图
9.1 🎭 什么是访问者模式?
一句话理解:在不改变类的前提下,为元素添加新的操作!
定义:表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
应用场景:编译器设计、文档处理、报表生成、数据结构操作、图形渲染
9.2 🛠️ 访问者模式的实现
9.2.1 🏗️ 基本结构
💡 小贴士:访问者模式就像医院体检,不同科室的医生对同一个病人进行不同的检查!
核心组件:
- Visitor(访问者):定义访问元素的接口
- ConcreteVisitor(具体访问者):实现访问者接口
- Element(元素):定义接受访问的接口
- ConcreteElement(具体元素):实现元素接口
9.2.2 🚀 多种实现方式
实现方式 | 特点 | 推荐度 |
---|---|---|
双重分发 | 基于运行时类型的选择 | ⭐⭐⭐⭐⭐ |
单重分发 | 基于编译时类型的选择 | ⭐⭐⭐ |
反射访问者 | 使用反射实现动态访问 | ⭐⭐⭐⭐ |
9.2.1 🔄 双重分发实现
// 双重分发:基于运行时类型的选择
public interface DocumentElement {
void accept(DocumentVisitor visitor);
}
public class Paragraph implements DocumentElement {
private String text;
public Paragraph(String text) {
this.text = text;
}
@Override
public void accept(DocumentVisitor visitor) {
visitor.visit(this); // 第一次分发:根据visitor类型
}
public String getText() {
return text;
}
}
public class Image implements DocumentElement {
private String url;
private String alt;
public Image(String url, String alt) {
this.url = url;
this.alt = alt;
}
@Override
public void accept(DocumentVisitor visitor) {
visitor.visit(this); // 第一次分发:根据visitor类型
}
public String getUrl() {
return url;
}
public String getAlt() {
return alt;
}
}
public class Table implements DocumentElement {
private List<List<String>> data;
public Table(List<List<String>> data) {
this.data = data;
}
@Override
public void accept(DocumentVisitor visitor) {
visitor.visit(this); // 第一次分发:根据visitor类型
}
public List<List<String>> getData() {
return data;
}
}
public interface DocumentVisitor {
void visit(Paragraph paragraph); // 第二次分发:根据element类型
void visit(Image image);
void visit(Table table);
}
public class HTMLVisitor implements DocumentVisitor {
private StringBuilder html = new StringBuilder();
@Override
public void visit(Paragraph paragraph) {
html.append("<p>").append(paragraph.getText()).append("</p>\n");
}
@Override
public void visit(Image image) {
html.append("<img src=\"").append(image.getUrl())
.append("\" alt=\"").append(image.getAlt()).append("\">\n");
}
@Override
public void visit(Table table) {
html.append("<table>\n");
for (List<String> row : table.getData()) {
html.append("<tr>\n");
for (String cell : row) {
html.append("<td>").append(cell).append("</td>\n");
}
html.append("</tr>\n");
}
html.append("</table>\n");
}
public String getHTML() {
return html.toString();
}
}
public class TextVisitor implements DocumentVisitor {
private StringBuilder text = new StringBuilder();
@Override
public void visit(Paragraph paragraph) {
text.append(paragraph.getText()).append("\n");
}
@Override
public void visit(Image image) {
text.append("[图片: ").append(image.getAlt()).append("]\n");
}
@Override
public void visit(Table table) {
for (List<String> row : table.getData()) {
for (String cell : row) {
text.append(cell).append("\t");
}
text.append("\n");
}
}
public String getText() {
return text.toString();
}
}
public class PDFVisitor implements DocumentVisitor {
private StringBuilder pdf = new StringBuilder();
@Override
public void visit(Paragraph paragraph) {
pdf.append("PDF段落: ").append(paragraph.getText()).append("\n");
}
@Override
public void visit(Image image) {
pdf.append("PDF图片: ").append(image.getUrl()).append("\n");
}
@Override
public void visit(Table table) {
pdf.append("PDF表格:\n");
for (List<String> row : table.getData()) {
for (String cell : row) {
pdf.append(cell).append(" | ");
}
pdf.append("\n");
}
}
public String getPDF() {
return pdf.toString();
}
}
单重分发实现:
// 单重分发:基于编译时类型的选择
public interface SingleDispatchElement {
void accept(SingleDispatchVisitor visitor);
}
public class SingleDispatchParagraph implements SingleDispatchElement {
private String text;
public SingleDispatchParagraph(String text) {
this.text = text;
}
@Override
public void accept(SingleDispatchVisitor visitor) {
visitor.visit(this);
}
public String getText() {
return text;
}
}
public class SingleDispatchImage implements SingleDispatchElement {
private String url;
public SingleDispatchImage(String url) {
this.url = url;
}
@Override
public void accept(SingleDispatchVisitor visitor) {
visitor.visit(this);
}
public String getUrl() {
return url;
}
}
public interface SingleDispatchVisitor {
void visit(SingleDispatchParagraph paragraph);
void visit(SingleDispatchImage image);
}
public class SingleDispatchHTMLVisitor implements SingleDispatchVisitor {
private StringBuilder html = new StringBuilder();
@Override
public void visit(SingleDispatchParagraph paragraph) {
html.append("<p>").append(paragraph.getText()).append("</p>\n");
}
@Override
public void visit(SingleDispatchImage image) {
html.append("<img src=\"").append(image.getUrl()).append("\">\n");
}
public String getHTML() {
return html.toString();
}
}
9.2.3 🔮 反射访问者实现
// 反射访问者:使用反射实现动态访问
public interface ReflectiveElement {
String getType();
Map<String, Object> getProperties();
}
public class ReflectiveParagraph implements ReflectiveElement {
private String text;
public ReflectiveParagraph(String text) {
this.text = text;
}
@Override
public String getType() {
return "paragraph";
}
@Override
public Map<String, Object> getProperties() {
Map<String, Object> props = new HashMap<>();
props.put("text", text);
return props;
}
}
public class ReflectiveImage implements ReflectiveElement {
private String url;
private String alt;
public ReflectiveImage(String url, String alt) {
this.url = url;
this.alt = alt;
}
@Override
public String getType() {
return "image";
}
@Override
public Map<String, Object> getProperties() {
Map<String, Object> props = new HashMap<>();
props.put("url", url);
props.put("alt", alt);
return props;
}
}
public class ReflectiveTable implements ReflectiveElement {
private List<List<String>> data;
public ReflectiveTable(List<List<String>> data) {
this.data = data;
}
@Override
public String getType() {
return "table";
}
@Override
public Map<String, Object> getProperties() {
Map<String, Object> props = new HashMap<>();
props.put("data", data);
return props;
}
}
public class ReflectiveVisitor {
private Map<String, Consumer<Map<String, Object>>> handlers = new HashMap<>();
private StringBuilder result = new StringBuilder();
public void registerHandler(String type, Consumer<Map<String, Object>> handler) {
handlers.put(type, handler);
}
public void visit(ReflectiveElement element) {
String type = element.getType();
Map<String, Object> properties = element.getProperties();
Consumer<Map<String, Object>> handler = handlers.get(type);
if (handler != null) {
handler.accept(properties);
} else {
System.out.println("未找到处理器: " + type);
}
}
public void append(String text) {
result.append(text);
}
public String getResult() {
return result.toString();
}
}
// 使用示例
public class ReflectiveVisitorDemo {
public static void main(String[] args) {
ReflectiveVisitor visitor = new ReflectiveVisitor();
// 注册HTML处理器
visitor.registerHandler("paragraph", props -> {
String text = (String) props.get("text");
visitor.append("<p>").append(text).append("</p>\n");
});
visitor.registerHandler("image", props -> {
String url = (String) props.get("url");
String alt = (String) props.get("alt");
visitor.append("<img src=\"").append(url)
.append("\" alt=\"").append(alt).append("\">\n");
});
visitor.registerHandler("table", props -> {
@SuppressWarnings("unchecked")
List<List<String>> data = (List<List<String>>) props.get("data");
visitor.append("<table>\n");
for (List<String> row : data) {
visitor.append("<tr>\n");
for (String cell : row) {
visitor.append("<td>").append(cell).append("</td>\n");
}
visitor.append("</tr>\n");
}
visitor.append("</table>\n");
});
// 创建文档元素
List<ReflectiveElement> elements = Arrays.asList(
new ReflectiveParagraph("这是一个段落"),
new ReflectiveImage("image.jpg", "示例图片"),
new ReflectiveTable(Arrays.asList(
Arrays.asList("姓名", "年龄"),
Arrays.asList("张三", "25"),
Arrays.asList("李四", "30")
))
);
// 访问所有元素
for (ReflectiveElement element : elements) {
visitor.visit(element);
}
System.out.println("生成的HTML:");
System.out.println(visitor.getResult());
}
}
9.2.3 🎯 标准实现示例
// 元素接口 - 被访问的对象接口
public interface Element {
void accept(Visitor visitor);
}
// 具体元素A - 具体的被访问对象
public class ConcreteElementA implements Element {
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
public void operationA() {
System.out.println("元素A的操作");
}
}
// 具体元素B - 具体的被访问对象
public class ConcreteElementB implements Element {
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
public void operationB() {
System.out.println("元素B的操作");
}
}
// 访问者接口 - 定义访问操作的接口
public interface Visitor {
void visit(ConcreteElementA element);
void visit(ConcreteElementB element);
}
// 具体访问者A - 具体的访问操作实现
public class ConcreteVisitorA implements Visitor {
@Override
public void visit(ConcreteElementA element) {
System.out.println("访问者A访问元素A");
element.operationA();
}
@Override
public void visit(ConcreteElementB element) {
System.out.println("访问者A访问元素B");
element.operationB();
}
}
// 具体访问者B - 具体的访问操作实现
public class ConcreteVisitorB implements Visitor {
@Override
public void visit(ConcreteElementA element) {
System.out.println("访问者B访问元素A");
element.operationA();
}
@Override
public void visit(ConcreteElementB element) {
System.out.println("访问者B访问元素B");
element.operationB();
}
}
// 对象结构 - 管理元素的集合
public class ObjectStructure {
private List<Element> elements = new ArrayList<>();
public void add(Element element) {
elements.add(element);
}
public void remove(Element element) {
elements.remove(element);
}
public void accept(Visitor visitor) {
for (Element element : elements) {
element.accept(visitor);
}
}
}
9.2.4 🎯 实际应用示例
// 文档元素接口
public interface DocumentElement {
void accept(DocumentVisitor visitor);
}
// 段落
public class Paragraph implements DocumentElement {
private String text;
public Paragraph(String text) {
this.text = text;
}
@Override
public void accept(DocumentVisitor visitor) {
visitor.visit(this);
}
public String getText() {
return text;
}
}
// 图片
public class Image implements DocumentElement {
private String url;
private String alt;
public Image(String url, String alt) {
this.url = url;
this.alt = alt;
}
@Override
public void accept(DocumentVisitor visitor) {
visitor.visit(this);
}
public String getUrl() {
return url;
}
public String getAlt() {
return alt;
}
}
// 文档访问者接口
public interface DocumentVisitor {
void visit(Paragraph paragraph);
void visit(Image image);
}
// HTML访问者
public class HTMLVisitor implements DocumentVisitor {
private StringBuilder html = new StringBuilder();
@Override
public void visit(Paragraph paragraph) {
html.append("<p>").append(paragraph.getText()).append("</p>\n");
}
@Override
public void visit(Image image) {
html.append("<img src=\"").append(image.getUrl())
.append("\" alt=\"").append(image.getAlt()).append("\">\n");
}
public String getHTML() {
return html.toString();
}
}
// 文本访问者
public class TextVisitor implements DocumentVisitor {
private StringBuilder text = new StringBuilder();
@Override
public void visit(Paragraph paragraph) {
text.append(paragraph.getText()).append("\n");
}
@Override
public void visit(Image image) {
text.append("[图片: ").append(image.getAlt()).append("]\n");
}
public String getText() {
return text.toString();
}
}
// 文档
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);
}
}
}
💾 第十部分:备忘录模式(Memento Pattern)
💾 备忘录舞者的登场 💾
┌─────────────────────────────────────┐
│ 💾 备忘录:我是状态保存专家! │
│ │
│ 🎮 游戏:"我要保存当前状态!" │
│ 💾 备忘录:"我来保存状态!" │
│ 🎮 游戏:"我要恢复到之前状态!" │
│ 💾 备忘录:"我来恢复状态!" │
│ │
│ 💡 核心思想:状态保存恢复 │
└─────────────────────────────────────┘
🏗️ 备忘录模式UML类图
TypeError: Cannot read properties of undefined (reading 'x')
⏱️ 备忘录模式时序图
10.1 🎭 什么是备忘录模式?
一句话理解:保存对象状态,需要时可以恢复到之前的状态,就像游戏存档!
定义:在不破坏封装性的前提下,捕获并外部化一个对象的内部状态,以便在需要时可以将对象恢复到之前的状态。
核心思想:就像游戏存档,可以保存当前状态,需要时可以回滚到之前的状态。
应用场景:
- 文本编辑器的撤销功能
- 游戏存档系统
- 数据库事务回滚
- 配置管理器的状态恢复
10.2 🛠️ 备忘录模式的实现
10.2.1 🏗️ 基本结构
💡 小贴士:备忘录模式就像游戏存档,可以保存和恢复对象的状态!
核心组件:
- Memento(备忘录):存储对象状态
- Originator(发起人):创建备忘录的对象
- Caretaker(管理者):管理备忘录的对象
10.2.2 🚀 多种实现方式
实现方式 | 特点 | 推荐度 |
---|---|---|
白箱备忘录 | 备忘录内部状态可见 | ⭐⭐⭐ |
黑箱备忘录 | 备忘录内部状态隐藏 | ⭐⭐⭐⭐⭐ |
增量备忘录 | 只保存状态变化部分 | ⭐⭐⭐⭐⭐ |
10.2.1 📦 白箱备忘录实现
// 白箱备忘录:备忘录内部状态可见
public class WhiteBoxMemento {
private final String state;
public WhiteBoxMemento(String state) {
this.state = state;
}
public String getState() {
return state;
}
}
public class WhiteBoxOriginator {
private String state;
public void setState(String state) {
this.state = state;
System.out.println("状态设置为: " + state);
}
public String getState() {
return state;
}
public WhiteBoxMemento saveState() {
return new WhiteBoxMemento(state);
}
public void restoreState(WhiteBoxMemento memento) {
this.state = memento.getState(); // 直接访问备忘录状态
System.out.println("状态恢复为: " + state);
}
}
public class WhiteBoxCareTaker {
private List<WhiteBoxMemento> mementoList = new ArrayList<>();
public void addMemento(WhiteBoxMemento memento) {
mementoList.add(memento);
}
public WhiteBoxMemento getMemento(int index) {
if (index >= 0 && index < mementoList.size()) {
return mementoList.get(index);
}
return null;
}
public int getMementoCount() {
return mementoList.size();
}
}
10.2.2 🎁 黑箱备忘录实现
// 黑箱备忘录:备忘录内部状态隐藏
public interface Memento {
// 空接口,不暴露任何方法
}
public class BlackBoxOriginator {
private String state;
public void setState(String state) {
this.state = state;
System.out.println("状态设置为: " + state);
}
public String getState() {
return state;
}
public Memento saveState() {
return new BlackBoxMemento(state);
}
public void restoreState(Memento memento) {
if (memento instanceof BlackBoxMemento) {
BlackBoxMemento blackBoxMemento = (BlackBoxMemento) memento;
this.state = blackBoxMemento.getState();
System.out.println("状态恢复为: " + state);
}
}
// 内部类,外部无法直接访问
private static class BlackBoxMemento implements Memento {
private final String state;
private BlackBoxMemento(String state) {
this.state = state;
}
private String getState() {
return state;
}
}
}
public class BlackBoxCareTaker {
private List<Memento> mementoList = new ArrayList<>();
public void addMemento(Memento memento) {
mementoList.add(memento);
}
public Memento getMemento(int index) {
if (index >= 0 && index < mementoList.size()) {
return mementoList.get(index);
}
return null;
}
public int getMementoCount() {
return mementoList.size();
}
}
10.2.3 📊 增量备忘录实现
// 增量备忘录:只保存状态变化部分
public class IncrementalMemento {
private final Map<String, Object> changes;
private final long timestamp;
public IncrementalMemento(Map<String, Object> changes) {
this.changes = new HashMap<>(changes);
this.timestamp = System.currentTimeMillis();
}
public Map<String, Object> getChanges() {
return new HashMap<>(changes);
}
public long getTimestamp() {
return timestamp;
}
}
public class IncrementalOriginator {
private Map<String, Object> state = new HashMap<>();
private List<IncrementalMemento> mementos = new ArrayList<>();
public void setProperty(String key, Object value) {
Object oldValue = state.get(key);
if (!Objects.equals(oldValue, value)) {
state.put(key, value);
System.out.println("属性 " + key + " 设置为: " + value);
// 创建增量备忘录
Map<String, Object> changes = new HashMap<>();
changes.put(key, value);
IncrementalMemento memento = new IncrementalMemento(changes);
mementos.add(memento);
}
}
public Object getProperty(String key) {
return state.get(key);
}
public Map<String, Object> getState() {
return new HashMap<>(state);
}
public void restoreToMemento(IncrementalMemento memento) {
Map<String, Object> changes = memento.getChanges();
for (Map.Entry<String, Object> entry : changes.entrySet()) {
state.put(entry.getKey(), entry.getValue());
}
System.out.println("恢复到时间戳: " + new Date(memento.getTimestamp()));
}
public void restoreToTimestamp(long timestamp) {
// 找到指定时间戳的备忘录
for (IncrementalMemento memento : mementos) {
if (memento.getTimestamp() <= timestamp) {
restoreToMemento(memento);
}
}
}
public List<IncrementalMemento> getMementos() {
return new ArrayList<>(mementos);
}
}
// 使用示例
public class IncrementalMementoDemo {
public static void main(String[] args) {
IncrementalOriginator originator = new IncrementalOriginator();
// 设置初始状态
originator.setProperty("name", "张三");
originator.setProperty("age", 25);
originator.setProperty("city", "北京");
System.out.println("\n=== 当前状态 ===");
System.out.println("姓名: " + originator.getProperty("name"));
System.out.println("年龄: " + originator.getProperty("age"));
System.out.println("城市: " + originator.getProperty("city"));
// 修改状态
originator.setProperty("age", 26);
originator.setProperty("city", "上海");
System.out.println("\n=== 修改后状态 ===");
System.out.println("姓名: " + originator.getProperty("name"));
System.out.println("年龄: " + originator.getProperty("age"));
System.out.println("城市: " + originator.getProperty("city"));
// 查看备忘录历史
System.out.println("\n=== 备忘录历史 ===");
List<IncrementalMemento> mementos = originator.getMementos();
for (int i = 0; i < mementos.size(); i++) {
IncrementalMemento memento = mementos.get(i);
System.out.println("备忘录 " + (i + 1) + ": " +
new Date(memento.getTimestamp()) + " - " +
memento.getChanges());
}
// 恢复到第一个备忘录
if (!mementos.isEmpty()) {
System.out.println("\n=== 恢复到第一个备忘录 ===");
originator.restoreToMemento(mementos.get(0));
System.out.println("姓名: " + originator.getProperty("name"));
System.out.println("年龄: " + originator.getProperty("age"));
System.out.println("城市: " + originator.getProperty("city"));
}
}
}
10.2.3 🎯 标准实现示例
// 备忘录类 - 存储状态
public class Memento {
private final String state;
public Memento(String state) {
this.state = state;
}
public String getState() {
return state;
}
}
// 发起人类 - 需要保存状态的对象
public class Originator {
private String state;
public void setState(String state) {
this.state = state;
System.out.println("状态设置为: " + state);
}
public String getState() {
return state;
}
// 创建备忘录
public Memento saveState() {
return new Memento(state);
}
// 从备忘录恢复状态
public void restoreState(Memento memento) {
this.state = memento.getState();
System.out.println("状态恢复为: " + state);
}
}
// 管理者类 - 管理备忘录
public class CareTaker {
private List<Memento> mementoList = new ArrayList<>();
public void addMemento(Memento memento) {
mementoList.add(memento);
}
public Memento getMemento(int index) {
if (index >= 0 && index < mementoList.size()) {
return mementoList.get(index);
}
return null;
}
public int getMementoCount() {
return mementoList.size();
}
}
10.2.4 🎯 实际应用示例
// 文本编辑器状态
public class TextEditorState {
private final String content;
private final int cursorPosition;
public TextEditorState(String content, int cursorPosition) {
this.content = content;
this.cursorPosition = cursorPosition;
}
public String getContent() {
return content;
}
public int getCursorPosition() {
return cursorPosition;
}
}
// 文本编辑器
public class TextEditor {
private String content = "";
private int cursorPosition = 0;
public void type(String text) {
content += text;
cursorPosition += text.length();
System.out.println("输入文本: " + text + ", 当前内容: " + content);
}
public void delete() {
if (content.length() > 0) {
content = content.substring(0, content.length() - 1);
cursorPosition = Math.max(0, cursorPosition - 1);
System.out.println("删除字符, 当前内容: " + content);
}
}
public void setCursor(int position) {
cursorPosition = Math.max(0, Math.min(position, content.length()));
System.out.println("光标移动到位置: " + cursorPosition);
}
// 保存状态
public TextEditorState saveState() {
return new TextEditorState(content, cursorPosition);
}
// 恢复状态
public void restoreState(TextEditorState state) {
this.content = state.getContent();
this.cursorPosition = state.getCursorPosition();
System.out.println("恢复状态 - 内容: " + content + ", 光标位置: " + cursorPosition);
}
public String getContent() {
return content;
}
public int getCursorPosition() {
return cursorPosition;
}
}
// 撤销管理器
public class UndoManager {
private Stack<TextEditorState> undoStack = new Stack<>();
private Stack<TextEditorState> redoStack = new Stack<>();
public void saveState(TextEditorState state) {
undoStack.push(state);
redoStack.clear(); // 新的操作会清空重做栈
}
public TextEditorState undo() {
if (!undoStack.isEmpty()) {
TextEditorState state = undoStack.pop();
redoStack.push(state);
return undoStack.isEmpty() ? null : undoStack.peek();
}
return null;
}
public TextEditorState redo() {
if (!redoStack.isEmpty()) {
TextEditorState state = redoStack.pop();
undoStack.push(state);
return state;
}
return null;
}
public boolean canUndo() {
return undoStack.size() > 1; // 至少要有两个状态才能撤销
}
public boolean canRedo() {
return !redoStack.isEmpty();
}
}
// 使用示例
public class MementoPatternDemo {
public static void main(String[] args) {
TextEditor editor = new TextEditor();
UndoManager undoManager = new UndoManager();
// 初始状态
undoManager.saveState(editor.saveState());
// 输入文本
editor.type("Hello");
undoManager.saveState(editor.saveState());
editor.type(" World");
undoManager.saveState(editor.saveState());
editor.type("!");
undoManager.saveState(editor.saveState());
System.out.println("\n=== 撤销操作 ===");
// 撤销
if (undoManager.canUndo()) {
TextEditorState state = undoManager.undo();
if (state != null) {
editor.restoreState(state);
}
}
// 再撤销
if (undoManager.canUndo()) {
TextEditorState state = undoManager.undo();
if (state != null) {
editor.restoreState(state);
}
}
System.out.println("\n=== 重做操作 ===");
// 重做
if (undoManager.canRedo()) {
TextEditorState state = undoManager.redo();
if (state != null) {
editor.restoreState(state);
}
}
}
}
10.4 备忘录模式的优缺点
优点:
- ✅ 可以保存对象的历史状态
- ✅ 实现了状态的封装,外部无法直接访问
- ✅ 支持撤销和重做操作
- ✅ 符合单一职责原则
缺点:
- ❌ 如果状态数据很大,会占用大量内存
- ❌ 频繁的保存和恢复操作可能影响性能
- ❌ 管理者类需要管理大量的备忘录对象
🗣️ 第十一部分:解释器模式(Interpreter Pattern)
🗣️ 解释舞者的登场 🗣️
┌─────────────────────────────────────┐
│ 🗣️ 解释器:我是语言解释专家! │
│ │
│ 📝 表达式:"1 + 2 * 3" │
│ 🗣️ 解释器:"我来解释执行!" │
│ 📝 表达式:"x + y * z" │
│ 🗣️ 解释器:"继续解释执行!" │
│ │
│ 💡 核心思想:语法树解析执行 │
└─────────────────────────────────────┘
🏗️ 解释器模式UML类图
TypeError: Cannot read properties of undefined (reading 'x')
⏱️ 解释器模式时序图
11.1 🎭 什么是解释器模式?
一句话理解:定义语法规则,解释执行特定语言的指令!
定义:给定一种语言,定义它的语法表示,并定义一个解释器,使用该解释器来解释语言中的句子。
核心思想:就像翻译官,能够理解并执行特定语言的指令。
应用场景:
- 数学表达式计算器
- SQL解析器
- 正则表达式解析
- 配置文件解析
- 简单脚本语言解释器
11.2 🛠️ 解释器模式的实现
11.2.1 🏗️ 基本结构
💡 小贴士:解释器模式就像翻译官,将特定的语言或表达式解释为可执行的操作!
核心组件:
- AbstractExpression(抽象表达式):定义解释操作的接口
- TerminalExpression(终结表达式):实现终结符的解释
- NonterminalExpression(非终结表达式):实现非终结符的解释
- Context(上下文):包含解释器需要的全局信息
11.2.2 🚀 多种实现方式
实现方式 | 特点 | 推荐度 |
---|---|---|
递归下降 | 自顶向下的语法分析 | ⭐⭐⭐⭐⭐ |
语法树 | 构建抽象语法树 | ⭐⭐⭐⭐⭐ |
表达式求值 | 简单的表达式计算 | ⭐⭐⭐⭐ |
11.2.1 🔄 递归下降实现
// 递归下降:自顶向下的语法分析
public class RecursiveDescentParser {
private String expression;
private int position;
private char currentChar;
public RecursiveDescentParser(String expression) {
this.expression = expression.replaceAll("\\s+", "");
this.position = 0;
this.currentChar = expression.length() > 0 ? expression.charAt(0) : '\0';
}
public Expression parse() {
return parseExpression();
}
// 表达式: term (+|- term)*
private Expression parseExpression() {
Expression left = parseTerm();
while (currentChar == '+' || currentChar == '-') {
char operator = currentChar;
advance();
Expression right = parseTerm();
if (operator == '+') {
left = new AddExpression(left, right);
} else {
left = new SubtractExpression(left, right);
}
}
return left;
}
// 项: factor (*|/ factor)*
private Expression parseTerm() {
Expression left = parseFactor();
while (currentChar == '*' || currentChar == '/') {
char operator = currentChar;
advance();
Expression right = parseFactor();
if (operator == '*') {
left = new MultiplyExpression(left, right);
} else {
left = new DivideExpression(left, right);
}
}
return left;
}
// 因子: number | (expression)
private Expression parseFactor() {
if (Character.isDigit(currentChar)) {
return parseNumber();
} else if (currentChar == '(') {
advance(); // 跳过 '('
Expression result = parseExpression();
if (currentChar == ')') {
advance(); // 跳过 ')'
return result;
} else {
throw new IllegalArgumentException("期望 ')'");
}
} else {
throw new IllegalArgumentException("意外的字符: " + currentChar);
}
}
// 数字: digit+
private Expression parseNumber() {
StringBuilder number = new StringBuilder();
while (Character.isDigit(currentChar)) {
number.append(currentChar);
advance();
}
return new NumberExpression(Integer.parseInt(number.toString()));
}
private void advance() {
position++;
if (position < expression.length()) {
currentChar = expression.charAt(position);
} else {
currentChar = '\0';
}
}
}
// 表达式接口和实现类
public interface Expression {
int interpret(Context context);
}
public class NumberExpression implements Expression {
private int number;
public NumberExpression(int number) {
this.number = number;
}
@Override
public int interpret(Context context) {
return number;
}
}
public class AddExpression implements Expression {
private Expression left;
private Expression right;
public AddExpression(Expression left, Expression right) {
this.left = left;
this.right = right;
}
@Override
public int interpret(Context context) {
return left.interpret(context) + right.interpret(context);
}
}
public class SubtractExpression implements Expression {
private Expression left;
private Expression right;
public SubtractExpression(Expression left, Expression right) {
this.left = left;
this.right = right;
}
@Override
public int interpret(Context context) {
return left.interpret(context) - right.interpret(context);
}
}
public class MultiplyExpression implements Expression {
private Expression left;
private Expression right;
public MultiplyExpression(Expression left, Expression right) {
this.left = left;
this.right = right;
}
@Override
public int interpret(Context context) {
return left.interpret(context) * right.interpret(context);
}
}
public class DivideExpression implements Expression {
private Expression left;
private Expression right;
public DivideExpression(Expression left, Expression right) {
this.left = left;
this.right = right;
}
@Override
public int interpret(Context context) {
int rightValue = right.interpret(context);
if (rightValue == 0) {
throw new ArithmeticException("除零错误");
}
return left.interpret(context) / rightValue;
}
}
11.2.2 🌳 语法树实现
// 语法树:构建抽象语法树
public abstract class ASTNode {
public abstract int evaluate(Context context);
public abstract void accept(ASTVisitor visitor);
}
public class NumberNode extends ASTNode {
private int value;
public NumberNode(int value) {
this.value = value;
}
@Override
public int evaluate(Context context) {
return value;
}
@Override
public void accept(ASTVisitor visitor) {
visitor.visit(this);
}
public int getValue() {
return value;
}
}
public class BinaryOpNode extends ASTNode {
private String operator;
private ASTNode left;
private ASTNode right;
public BinaryOpNode(String operator, ASTNode left, ASTNode right) {
this.operator = operator;
this.left = left;
this.right = right;
}
@Override
public int evaluate(Context context) {
int leftValue = left.evaluate(context);
int rightValue = right.evaluate(context);
switch (operator) {
case "+": return leftValue + rightValue;
case "-": return leftValue - rightValue;
case "*": return leftValue * rightValue;
case "/":
if (rightValue == 0) {
throw new ArithmeticException("除零错误");
}
return leftValue / rightValue;
default:
throw new IllegalArgumentException("未知操作符: " + operator);
}
}
@Override
public void accept(ASTVisitor visitor) {
visitor.visit(this);
}
public String getOperator() { return operator; }
public ASTNode getLeft() { return left; }
public ASTNode getRight() { return right; }
}
public interface ASTVisitor {
void visit(NumberNode node);
void visit(BinaryOpNode node);
}
public class PrintVisitor implements ASTVisitor {
private StringBuilder result = new StringBuilder();
private int indent = 0;
@Override
public void visit(NumberNode node) {
result.append(" ".repeat(indent)).append("Number: ").append(node.getValue()).append("\n");
}
@Override
public void visit(BinaryOpNode node) {
result.append(" ".repeat(indent)).append("BinaryOp: ").append(node.getOperator()).append("\n");
indent++;
node.getLeft().accept(this);
node.getRight().accept(this);
indent--;
}
public String getResult() {
return result.toString();
}
}
public class ASTBuilder {
public static ASTNode buildAST(String expression) {
// 简化的AST构建器,实际应用中需要更复杂的解析逻辑
String[] tokens = expression.replaceAll("\\s+", "").split("");
if (tokens.length == 1) {
return new NumberNode(Integer.parseInt(tokens[0]));
}
if (tokens.length == 3) {
ASTNode left = new NumberNode(Integer.parseInt(tokens[0]));
ASTNode right = new NumberNode(Integer.parseInt(tokens[2]));
return new BinaryOpNode(tokens[1], left, right);
}
// 处理更复杂的表达式
return buildComplexAST(expression);
}
private static ASTNode buildComplexAST(String expression) {
// 这里实现更复杂的AST构建逻辑
// 为了简化,我们使用递归下降解析器
RecursiveDescentParser parser = new RecursiveDescentParser(expression);
Expression exp = parser.parse();
return convertToAST(exp);
}
private static ASTNode convertToAST(Expression exp) {
if (exp instanceof NumberExpression) {
return new NumberNode(((NumberExpression) exp).interpret(new Context()));
} else if (exp instanceof AddExpression) {
AddExpression addExp = (AddExpression) exp;
return new BinaryOpNode("+",
convertToAST(addExp.getLeft()),
convertToAST(addExp.getRight()));
} else if (exp instanceof SubtractExpression) {
SubtractExpression subExp = (SubtractExpression) exp;
return new BinaryOpNode("-",
convertToAST(subExp.getLeft()),
convertToAST(subExp.getRight()));
} else if (exp instanceof MultiplyExpression) {
MultiplyExpression mulExp = (MultiplyExpression) exp;
return new BinaryOpNode("*",
convertToAST(mulExp.getLeft()),
convertToAST(mulExp.getRight()));
} else if (exp instanceof DivideExpression) {
DivideExpression divExp = (DivideExpression) exp;
return new BinaryOpNode("/",
convertToAST(divExp.getLeft()),
convertToAST(divExp.getRight()));
}
throw new IllegalArgumentException("不支持的表达式类型");
}
}
11.2.3 🧮 表达式求值实现
// 表达式求值:简单的表达式计算
public class SimpleExpressionEvaluator {
private Map<String, Integer> variables = new HashMap<>();
public void setVariable(String name, int value) {
variables.put(name, value);
}
public int evaluate(String expression) {
return evaluateExpression(expression.replaceAll("\\s+", ""));
}
private int evaluateExpression(String expr) {
if (expr.isEmpty()) {
return 0;
}
// 处理括号
if (expr.startsWith("(") && expr.endsWith(")")) {
return evaluateExpression(expr.substring(1, expr.length() - 1));
}
// 处理加法
int addIndex = findOperator(expr, '+');
if (addIndex != -1) {
return evaluateExpression(expr.substring(0, addIndex)) +
evaluateExpression(expr.substring(addIndex + 1));
}
// 处理减法
int subIndex = findOperator(expr, '-');
if (subIndex != -1) {
return evaluateExpression(expr.substring(0, subIndex)) -
evaluateExpression(expr.substring(subIndex + 1));
}
// 处理乘法
int mulIndex = findOperator(expr, '*');
if (mulIndex != -1) {
return evaluateExpression(expr.substring(0, mulIndex)) *
evaluateExpression(expr.substring(mulIndex + 1));
}
// 处理除法
int divIndex = findOperator(expr, '/');
if (divIndex != -1) {
int left = evaluateExpression(expr.substring(0, divIndex));
int right = evaluateExpression(expr.substring(divIndex + 1));
if (right == 0) {
throw new ArithmeticException("除零错误");
}
return left / right;
}
// 处理数字或变量
return parseNumberOrVariable(expr);
}
private int findOperator(String expr, char operator) {
int parenCount = 0;
for (int i = 0; i < expr.length(); i++) {
char c = expr.charAt(i);
if (c == '(') parenCount++;
else if (c == ')') parenCount--;
else if (c == operator && parenCount == 0) {
return i;
}
}
return -1;
}
private int parseNumberOrVariable(String expr) {
if (Character.isDigit(expr.charAt(0))) {
return Integer.parseInt(expr);
} else {
return variables.getOrDefault(expr, 0);
}
}
}
// 使用示例
public class ExpressionEvaluatorDemo {
public static void main(String[] args) {
SimpleExpressionEvaluator evaluator = new SimpleExpressionEvaluator();
// 设置变量
evaluator.setVariable("x", 10);
evaluator.setVariable("y", 5);
// 测试简单表达式
System.out.println("2 + 3 = " + evaluator.evaluate("2 + 3"));
System.out.println("10 - 5 = " + evaluator.evaluate("10 - 5"));
System.out.println("4 * 6 = " + evaluator.evaluate("4 * 6"));
System.out.println("15 / 3 = " + evaluator.evaluate("15 / 3"));
// 测试复杂表达式
System.out.println("(2 + 3) * 4 = " + evaluator.evaluate("(2 + 3) * 4"));
System.out.println("x + y = " + evaluator.evaluate("x + y"));
System.out.println("x * y - 10 = " + evaluator.evaluate("x * y - 10"));
// 测试带括号的表达式
System.out.println("(x + y) * 2 = " + evaluator.evaluate("(x + y) * 2"));
}
}
11.2.3 🎯 标准实现示例
// 抽象表达式 - 定义解释操作的接口
public interface Expression {
int interpret(Context context);
}
// 上下文类 - 包含解释器需要的全局信息
public class Context {
private Map<String, Integer> variables = new HashMap<>();
public void setVariable(String name, int value) {
variables.put(name, value);
}
public int getVariable(String name) {
return variables.getOrDefault(name, 0);
}
}
// 终结符表达式 - 数字
public class NumberExpression implements Expression {
private int number;
public NumberExpression(int number) {
this.number = number;
}
@Override
public int interpret(Context context) {
return number;
}
}
// 终结符表达式 - 变量
public class VariableExpression implements Expression {
private String variable;
public VariableExpression(String variable) {
this.variable = variable;
}
@Override
public int interpret(Context context) {
return context.getVariable(variable);
}
}
// 非终结符表达式 - 加法
public class AddExpression implements Expression {
private Expression left;
private Expression right;
public AddExpression(Expression left, Expression right) {
this.left = left;
this.right = right;
}
@Override
public int interpret(Context context) {
return left.interpret(context) + right.interpret(context);
}
}
// 非终结符表达式 - 减法
public class SubtractExpression implements Expression {
private Expression left;
private Expression right;
public SubtractExpression(Expression left, Expression right) {
this.left = left;
this.right = right;
}
@Override
public int interpret(Context context) {
return left.interpret(context) - right.interpret(context);
}
}
// 非终结符表达式 - 乘法
public class MultiplyExpression implements Expression {
private Expression left;
private Expression right;
public MultiplyExpression(Expression left, Expression right) {
this.left = left;
this.right = right;
}
@Override
public int interpret(Context context) {
return left.interpret(context) * right.interpret(context);
}
}
11.2.4 🎯 实际应用示例
// 表达式解析器
public class ExpressionParser {
public static Expression parse(String expression) {
// 简单的解析逻辑,实际应用中可能需要更复杂的解析器
expression = expression.replaceAll("\\s+", ""); // 移除空格
if (expression.contains("+")) {
String[] parts = expression.split("\\+", 2);
return new AddExpression(parse(parts[0]), parse(parts[1]));
} else if (expression.contains("-")) {
String[] parts = expression.split("-", 2);
return new SubtractExpression(parse(parts[0]), parse(parts[1]));
} else if (expression.contains("*")) {
String[] parts = expression.split("\\*", 2);
return new MultiplyExpression(parse(parts[0]), parse(parts[1]));
} else if (expression.matches("\\d+")) {
return new NumberExpression(Integer.parseInt(expression));
} else if (expression.matches("[a-zA-Z]+")) {
return new VariableExpression(expression);
} else {
throw new IllegalArgumentException("无法解析表达式: " + expression);
}
}
}
// 计算器
public class Calculator {
private Context context = new Context();
public void setVariable(String name, int value) {
context.setVariable(name, value);
}
public int calculate(String expression) {
Expression exp = ExpressionParser.parse(expression);
return exp.interpret(context);
}
}
// 使用示例
public class InterpreterPatternDemo {
public static void main(String[] args) {
Calculator calculator = new Calculator();
// 设置变量
calculator.setVariable("x", 10);
calculator.setVariable("y", 5);
// 计算表达式
System.out.println("x + y = " + calculator.calculate("x + y")); // 15
System.out.println("x - y = " + calculator.calculate("x - y")); // 5
System.out.println("x * y = " + calculator.calculate("x * y")); // 50
System.out.println("10 + 20 = " + calculator.calculate("10 + 20")); // 30
System.out.println("x + 5 = " + calculator.calculate("x + 5")); // 15
}
}
11.3.3 更复杂的表达式解析器
// 支持括号的表达式解析器
public class AdvancedExpressionParser {
private String expression;
private int position;
public Expression parse(String expression) {
this.expression = expression.replaceAll("\\s+", "");
this.position = 0;
return parseExpression();
}
private Expression parseExpression() {
Expression left = parseTerm();
while (position < expression.length() &&
(expression.charAt(position) == '+' || expression.charAt(position) == '-')) {
char operator = expression.charAt(position++);
Expression right = parseTerm();
if (operator == '+') {
left = new AddExpression(left, right);
} else {
left = new SubtractExpression(left, right);
}
}
return left;
}
private Expression parseTerm() {
Expression left = parseFactor();
while (position < expression.length() && expression.charAt(position) == '*') {
position++; // 跳过 *
Expression right = parseFactor();
left = new MultiplyExpression(left, right);
}
return left;
}
private Expression parseFactor() {
char current = expression.charAt(position);
if (current == '(') {
position++; // 跳过 (
Expression result = parseExpression();
position++; // 跳过 )
return result;
} else if (Character.isDigit(current)) {
return parseNumber();
} else if (Character.isLetter(current)) {
return parseVariable();
} else {
throw new IllegalArgumentException("意外的字符: " + current);
}
}
private Expression parseNumber() {
StringBuilder number = new StringBuilder();
while (position < expression.length() && Character.isDigit(expression.charAt(position))) {
number.append(expression.charAt(position++));
}
return new NumberExpression(Integer.parseInt(number.toString()));
}
private Expression parseVariable() {
StringBuilder variable = new StringBuilder();
while (position < expression.length() && Character.isLetter(expression.charAt(position))) {
variable.append(expression.charAt(position++));
}
return new VariableExpression(variable.toString());
}
}
// 使用高级解析器
public class AdvancedCalculator {
private Context context = new Context();
private AdvancedExpressionParser parser = new AdvancedExpressionParser();
public void setVariable(String name, int value) {
context.setVariable(name, value);
}
public int calculate(String expression) {
Expression exp = parser.parse(expression);
return exp.interpret(context);
}
}
// 测试高级计算器
public class AdvancedInterpreterDemo {
public static void main(String[] args) {
AdvancedCalculator calculator = new AdvancedCalculator();
calculator.setVariable("x", 10);
calculator.setVariable("y", 5);
calculator.setVariable("z", 2);
// 测试复杂表达式
System.out.println("(x + y) * z = " + calculator.calculate("(x + y) * z")); // 30
System.out.println("x + y * z = " + calculator.calculate("x + y * z")); // 20
System.out.println("(10 + 5) * 3 = " + calculator.calculate("(10 + 5) * 3")); // 45
}
}
11.4 解释器模式的优缺点
优点:
- ✅ 易于扩展语法规则
- ✅ 每个语法规则都是一个类,便于维护
- ✅ 可以方便地添加新的解释操作
- ✅ 符合开闭原则
缺点:
- ❌ 对于复杂语法,会产生大量的类
- ❌ 解析效率相对较低
- ❌ 不适合复杂的语言解析
- ❌ 可能导致类层次结构复杂
11.5 解释器模式在JDK中的应用
// Java正则表达式使用了解释器模式
public class RegexExample {
public static void main(String[] args) {
String text = "Hello World 123";
// Pattern.compile() 使用了解释器模式来解析正则表达式
Pattern pattern = Pattern.compile("\\d+");
Matcher matcher = pattern.matcher(text);
while (matcher.find()) {
System.out.println("找到数字: " + matcher.group());
}
}
}
🎉 总结:行为型设计模式的舞蹈盛宴
🎭 行为型设计模式总结 🎭
┌─────────────────────────────────────┐
│ 🕺 十一位舞者的精彩表演回顾! │
│ │
│ 👀 观察者:一对多通知的优雅舞者 │
│ 🎯 策略者:算法选择的灵活舞者 │
│ 📝 命令者:请求封装的智慧舞者 │
│ 🔄 状态者:状态变化的艺术舞者 │
│ 📋 模板者:算法框架的设计舞者 │
│ 🔍 迭代者:集合遍历的精准舞者 │
│ ⛓️ 责任链:请求处理的链式舞者 │
│ 🤝 中介者:对象交互的协调舞者 │
│ 👁️ 访问者:元素操作的专家舞者 │
│ 💾 备忘录:状态保存的记忆舞者 │
│ 🗣️ 解释器:语言解释的翻译舞者 │
│ │
│ 🎊 感谢观看这场精彩的舞蹈表演! │
└─────────────────────────────────────┘
🎯 各模式的特点与选择指南
模式 | 核心特点 | 适用场景 | 推荐度 |
---|---|---|---|
👀 观察者模式 | 一对多通知机制,松耦合通信 | 事件处理、消息推送、数据绑定、GUI事件 | ⭐⭐⭐⭐⭐ |
🎯 策略模式 | 算法封装,运行时切换 | 支付方式、排序算法、游戏技能、压缩算法 | ⭐⭐⭐⭐⭐ |
📝 命令模式 | 请求封装,支持撤销重做 | 遥控器、撤销重做、宏命令、日志记录 | ⭐⭐⭐⭐⭐ |
🔄 状态模式 | 状态封装,行为随状态变化 | 状态机、游戏角色、订单状态、工作流 | ⭐⭐⭐⭐ |
📋 模板方法模式 | 算法骨架固定,步骤可变 | 算法框架、代码复用、流程控制、钩子方法 | ⭐⭐⭐⭐ |
🔍 迭代器模式 | 统一遍历接口,封装内部结构 | 集合遍历、分页查询、数据结构访问 | ⭐⭐⭐⭐ |
⛓️ 责任链模式 | 请求沿链传递,动态组合处理 | 请求处理、审批流程、异常处理、过滤器 | ⭐⭐⭐⭐ |
🤝 中介者模式 | 集中控制交互,降低对象耦合 | 聊天系统、事件总线、GUI交互、服务注册 | ⭐⭐⭐ |
👁️ 访问者模式 | 双重分发,不改变类定义新操作 | 编译器、文档处理、报表生成、数据结构操作 | ⭐⭐⭐ |
💾 备忘录模式 | 状态保存恢复,历史记录管理 | 撤销功能、游戏存档、状态恢复、配置管理 | ⭐⭐⭐ |
🗣️ 解释器模式 | 语法树解析,递归解释执行 | 表达式计算、SQL解析、脚本解释、配置文件 | ⭐⭐⭐ |
🚀 选择建议:何时使用哪种模式?
🎯 按问题类型选择
1. 对象间通信问题
- 观察者模式:一对多通知场景
- 中介者模式:复杂对象交互场景
- 命令模式:请求封装和参数化场景
2. 算法选择问题
- 策略模式:多种算法可替换场景
- 模板方法模式:算法框架固定场景
- 解释器模式:语言解析场景
3. 状态管理问题
- 状态模式:状态影响行为场景
- 备忘录模式:状态保存恢复场景
4. 集合访问问题
- 迭代器模式:统一遍历接口场景
- 访问者模式:对元素执行不同操作场景
5. 请求处理问题
- 责任链模式:请求沿链传递场景
- 命令模式:请求封装和队列场景
🎯 按应用场景选择
应用场景 | 推荐模式 | 原因 |
---|---|---|
GUI事件处理 | 观察者模式 | 事件驱动,松耦合 |
支付系统 | 策略模式 | 多种支付方式,易于扩展 |
文本编辑器 | 命令模式 | 支持撤销重做 |
游戏状态管理 | 状态模式 | 角色状态影响行为 |
数据处理框架 | 模板方法模式 | 算法骨架固定,步骤可变 |
集合遍历 | 迭代器模式 | 统一访问接口 |
审批流程 | 责任链模式 | 请求沿审批链传递 |
聊天系统 | 中介者模式 | 用户间交互协调 |
编译器 | 访问者模式 | 对语法树执行不同操作 |
游戏存档 | 备忘录模式 | 保存和恢复游戏状态 |
表达式计算 | 解释器模式 | 解析和执行表达式 |
💡 实践要点与最佳实践
🎯 选择策略
- 理解场景:根据具体需求选择合适的设计模式
- 避免过度设计:不是所有地方都需要使用设计模式
- 考虑性能:设计模式可能带来一定的性能开销
- 保持简单:优先选择简单的解决方案
- 遵循SOLID原则:确保设计模式的使用符合设计原则
🚀 实战建议
- 从简单开始:先尝试最简单的解决方案
- 渐进式重构:在需要时逐步引入设计模式
- 团队协作:确保团队成员都理解设计模式的使用
- 文档记录:记录设计模式的使用原因和效果
- 接口优先:定义清晰的接口,提高灵活性
- 组合优于继承:使用组合实现,避免继承的局限性
⚠️ 常见陷阱与注意事项
- 过度使用:不要为了使用模式而使用模式
- 性能问题:某些模式可能带来性能开销
- 复杂性增加:模式可能增加代码复杂性
- 学习成本:团队成员需要理解模式的使用
- 维护困难:过度使用模式可能导致维护困难
🌟 结语
通过深入理解这十一种行为型设计模式,我们掌握了"对象协作的舞蹈艺术":
- 观察者模式教会我们如何实现优雅的一对多通知机制
- 策略模式让我们学会封装算法,实现运行时切换
- 命令模式帮助我们封装请求,支持撤销重做操作
- 状态模式让我们学会根据状态改变对象行为
- 模板方法模式教会我们如何定义算法骨架,让子类实现具体步骤
- 迭代器模式让我们学会统一访问集合元素的方式
- 责任链模式帮助我们构建灵活的处理链
- 中介者模式让我们学会集中管理对象间的交互
- 访问者模式教会我们如何在不改变类的情况下添加新操作
- 备忘录模式帮助我们保存和恢复对象状态
- 解释器模式让我们学会解析和执行特定语言的指令
记住,设计模式不是银弹,而是工具箱中的利器。在实际项目中,要根据具体需求灵活运用,让对象间的协作既优雅又高效!
让我们一起在代码的舞台上,跳出优雅的舞蹈! 💃🕺
🎭 延伸阅读:
🚀 实践建议:建议在实际项目中尝试使用这些模式,从简单的场景开始,逐步掌握它们的精髓!记住,最好的学习方式就是动手实践!