行为型设计模式:对象协作的舞蹈家(上)
🕺 行为型设计模式:对象协作的舞蹈家
💡 温馨提示:本文将以轻松有趣的方式带你探索行为型设计模式的世界,就像在观看一场精彩的"对象舞蹈表演"一样!
🚪 传送门:在开始我们的"对象协作之旅"
之前,建议先通过这个 🎨 Java设计模式详解:让代码优雅如诗的秘密武器
了解设计模式的基础概念和整体架构,然后通过 🏭 创建型设计模式:对象诞生的艺术与智慧
学习对象创建的艺术,再通过 🏗️ 结构型设计模式:代码架构的魔法师
了解对象组合的艺术,这样能让你更好地理解本文内容!就像跳舞要先学会走路一样!💃
🕺 行为型设计模式整体架构
🎪 引言:为什么我们需要行为型设计模式?
🕺 场景:混乱的对象舞蹈现场 🕺
┌─────────────────────────────────────┐
│ 💻 程序员小王的一天 💻 │
│ │
│ 😵 对象间通信像鸡同鸭讲! │
│ 🔥 算法选择像选择困难症! │
│ 🐛 状态管理像迷宫一样复杂! │
│ │
│ 💡 突然,行为型设计模式舞者出现了! │
│ 🕺 "让我来编排你们的协作舞蹈!" │
└─────────────────────────────────────┘
行为型设计模式就像是"对象协作"的标准舞蹈编排,让对象之间的通信变得优雅、灵活、高效。
本文将带你探索十一种行为型设计模式,就像观看十一个不同的"对象舞蹈表演"一样精彩!
🎯 本文你将学到什么?
🎬 行为型设计模式舞蹈团 🎬
┌─────────────────────────────────────┐
│ 🕺 十一位协作舞者登场! │
│ │
│ 👀 观察者:一对多通知机制 │
│ 🎯 策略者:算法选择专家 │
│ 📝 命令者:请求封装大师 │
│ 🔄 状态者:状态变化艺术家 │
│ 📋 模板者:算法框架设计师 │
│ 🔍 迭代者:集合遍历专家 │
│ ⛓️ 责任链:请求处理链 │
│ 🤝 中介者:对象交互协调员 │
│ 👁️ 访问者:元素操作专家 │
│ 💾 备忘录:状态保存专家 │
│ 🗣️ 解释器:语言解释专家 │
│ │
│ 🚀 准备好开始舞蹈之旅了吗? │
└─────────────────────────────────────┘
👀 第一部分:观察者模式(Observer Pattern)
👀 观察者舞者的登场 👀
┌─────────────────────────────────────┐
│ 👀 观察者:我是一对多通知专家! │
│ │
│ 📢 主题:"我有新消息!" │
│ 👀 观察者:"我来通知大家!" │
│ 📢 主题:"状态变化了!" │
│ 👀 观察者:"我来更新大家!" │
│ │
│ 💡 核心思想:一对多通知机制 │
└─────────────────────────────────────┘
🏗️ 观察者模式UML类图
⏱️ 观察者模式时序图
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;}@Overridepublic 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;}@Overridepublic 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;}@Overridepublic 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; // 主题状态@Overridepublic void registerObserver(Observer observer) {observers.add(observer);System.out.println("观察者 " + observer + " 已注册");}@Overridepublic void removeObserver(Observer observer) {observers.remove(observer);System.out.println("观察者 " + observer + " 已移除");}@Overridepublic 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;}@Overridepublic void update(String message) {System.out.println(name + " 收到通知: " + message);}@Overridepublic String toString() {return name;}
}
1.2.4 📰 实际应用示例
💡 场景:新闻社发布新闻,各个新闻频道自动接收并报道!
问题:新闻社需要及时通知所有订阅的新闻频道
// 新闻发布系统 - 具体主题
public class NewsAgency implements Subject {private List<Observer> observers = new ArrayList<>(); // 新闻频道列表private String news; // 最新新闻@Overridepublic void registerObserver(Observer observer) {observers.add(observer);System.out.println("新闻频道 " + observer + " 已订阅");}@Overridepublic void removeObserver(Observer observer) {observers.remove(observer);System.out.println("新闻频道 " + observer + " 已取消订阅");}@Overridepublic 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;}@Overridepublic void update(String news) {System.out.println("📺 " + name + " 频道报道: " + news);}@Overridepublic 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类图
⏱️ 策略模式时序图
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 {@Overridepublic 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 {@Overridepublic 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 {@Overridepublic 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 {@Overridepublic 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 {@Overridepublic 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 {@Overridepublic void algorithmInterface() {System.out.println("🎯 执行策略A的算法");}
}// 具体策略B - 实现算法B
public class ConcreteStrategyB implements Strategy {@Overridepublic 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 {@Overridepublic void pay(double amount) {System.out.println("💰 使用支付宝支付: " + amount + " 元");System.out.println("📱 跳转到支付宝支付页面...");System.out.println("✅ 支付宝支付成功!");}
}// 微信支付策略
public class WechatStrategy implements PaymentStrategy {@Overridepublic void pay(double amount) {System.out.println("💰 使用微信支付: " + amount + " 元");System.out.println("📱 跳转到微信支付页面...");System.out.println("✅ 微信支付成功!");}
}// 银行卡支付策略
public class BankCardStrategy implements PaymentStrategy {@Overridepublic 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类图
⏱️ 命令模式时序图
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;}@Overridepublic void execute() {light.turnOn();}
}public class LightOffCommand implements SimpleCommand {private Light light;public LightOffCommand(Light light) {this.light = light;}@Overridepublic 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<>();@Overridepublic void addCommand(SimpleCommand command) {commands.add(command);}@Overridepublic void removeCommand(SimpleCommand command) {commands.remove(command);}@Overridepublic 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;}@Overridepublic void execute() {tv.turnOn();}
}public class StereoOnCommand implements SimpleCommand {private Stereo stereo;public StereoOnCommand(Stereo stereo) {this.stereo = stereo;}@Overridepublic 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;}@Overridepublic void execute() {light.turnOn();}@Overridepublic void undo() {light.turnOff();}
}public class LightOffCommandWithUndo implements UndoableCommand {private Light light;public LightOffCommandWithUndo(Light light) {this.light = light;}@Overridepublic void execute() {light.turnOff();}@Overridepublic 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;}@Overridepublic void execute() {prevSpeed = ceilingFan.getSpeed();ceilingFan.high();}@Overridepublic 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 {@Overridepublic void execute() {// 什么都不做}@Overridepublic 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;}@Overridepublic void execute() {receiver.action();}@Overridepublic 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 {@Overridepublic void turnOn() {System.out.println("电灯打开");}@Overridepublic void turnOff() {System.out.println("电灯关闭");}
}// 开灯命令
public class LightOnCommand implements Command {private Light light;public LightOnCommand(Light light) {this.light = light;}@Overridepublic void execute() {light.turnOn();}@Overridepublic void undo() {light.turnOff();}
}// 关灯命令
public class LightOffCommand implements Command {private Light light;public LightOffCommand(Light light) {this.light = light;}@Overridepublic void execute() {light.turnOff();}@Overridepublic 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();}
}