🕺 行为型设计模式:对象协作的舞蹈家
💡 温馨提示:本文将以轻松有趣的方式带你探索行为型设计模式的世界,就像在观看一场精彩的"对象舞蹈表演"一样!
🚪 传送门 :在开始我们的"对象协作之旅"之前,建议先通过这个 🎨 Java设计模式详解:让代码优雅如诗的秘密武器
了解设计模式的基础概念和整体架构,然后通过 🏭 创建型设计模式:对象诞生的艺术与智慧
学习对象创建的艺术,再通过 🏗️ 结构型设计模式:代码架构的魔法师
了解对象组合的艺术,这样能让你更好地理解本文内容!就像跳舞要先学会走路一样!💃
🕺 行为型设计模式整体架构
设计原则 行为型设计模式 一对多通知 算法选择 请求封装 状态变化 算法框架 集合遍历 请求处理链 对象交互 元素操作 状态保存 语言解释 对扩展开放
对修改关闭 开闭原则 依赖抽象
不依赖具体 依赖倒置原则 一个类只负责
一个职责 单一职责原则 选择合适模式 对象协作问题 观察者模式 策略模式 命令模式 状态模式 模板方法模式 迭代器模式 责任链模式 中介者模式 访问者模式 备忘录模式 解释器模式 事件处理
消息推送
数据绑定 支付方式
排序算法
压缩算法 遥控器系统
撤销重做
宏命令 状态机
游戏角色
订单状态 算法框架
代码复用
钩子方法 集合遍历
数据结构
分页查询 请求处理
异常处理
审批流程 聊天系统
事件总线
GUI交互 编译器
文档处理
报表生成 撤销功能
游戏存档
状态恢复 表达式计算
SQL解析
脚本解释
🎪 引言:为什么我们需要行为型设计模式?
🕺 场景:混乱的对象舞蹈现场 🕺
┌─────────────────────────────────────┐
│ 💻 程序员小王的一天 💻 │
│ │
│ 😵 对象间通信像鸡同鸭讲! │
│ 🔥 算法选择像选择困难症! │
│ 🐛 状态管理像迷宫一样复杂! │
│ │
│ 💡 突然,行为型设计模式舞者出现了! │
│ 🕺 "让我来编排你们的协作舞蹈!" │
└─────────────────────────────────────┘
行为型设计模式就像是"对象协作"的标准舞蹈编排,让对象之间的通信变得优雅、灵活、高效。
本文将带你探索十一种行为型设计模式,就像观看十一个不同的"对象舞蹈表演"一样精彩!
🎯 本文你将学到什么?
🎬 行为型设计模式舞蹈团 🎬
┌─────────────────────────────────────┐
│ 🕺 十一位协作舞者登场! │
│ │
│ 👀 观察者:一对多通知机制 │
│ 🎯 策略者:算法选择专家 │
│ 📝 命令者:请求封装大师 │
│ 🔄 状态者:状态变化艺术家 │
│ 📋 模板者:算法框架设计师 │
│ 🔍 迭代者:集合遍历专家 │
│ ⛓️ 责任链:请求处理链 │
│ 🤝 中介者:对象交互协调员 │
│ 👁️ 访问者:元素操作专家 │
│ 💾 备忘录:状态保存专家 │
│ 🗣️ 解释器:语言解释专家 │
│ │
│ 🚀 准备好开始舞蹈之旅了吗? │
└─────────────────────────────────────┘
👀 第一部分:观察者模式(Observer Pattern)
👀 观察者舞者的登场 👀
┌─────────────────────────────────────┐
│ 👀 观察者:我是一对多通知专家! │
│ │
│ 📢 主题:"我有新消息!" │
│ 👀 观察者:"我来通知大家!" │
│ 📢 主题:"状态变化了!" │
│ 👀 观察者:"我来更新大家!" │
│ │
│ 💡 核心思想:一对多通知机制 │
└─────────────────────────────────────┘
🏗️ 观察者模式UML类图
uses creates implements implements notifies <<interface>> Subject +registerObserver(observer) +removeObserver(observer) +notifyObservers() <<interface>> Observer +update(message) ConcreteSubject -observers: List<Observer> -state: String +setState(state) +registerObserver(observer) +removeObserver(observer) +notifyObservers() ConcreteObserver -name: String +update(message) Client +useObserver()
⏱️ 观察者模式时序图
客户端 主题 观察者1 观察者2 registerObserver(observer1) registerObserver(observer2) setState("新状态") update("新状态") update("新状态") 处理完成 处理完成 客户端 主题 观察者1 观察者2
1.1 🎭 什么是观察者模式?
一句话理解:当一个对象状态改变时,自动通知所有依赖它的对象,就像新闻发布一样!
定义:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
应用场景:事件处理系统、消息推送、数据绑定、日志记录、GUI事件处理
1.2 🛠️ 观察者模式的实现
1.2.1 🏗️ 基本结构
💡 小贴士:观察者模式就像新闻发布系统,主题是新闻社,观察者是各个新闻频道!
核心组件:
- Subject(主题):被观察的对象,维护观察者列表
- Observer(观察者):观察主题的对象,接收通知
- ConcreteSubject(具体主题):具体的被观察对象
- ConcreteObserver(具体观察者):具体的观察者实现
1.2.2 🚀 多种实现方式
实现方式 | 特点 | 推荐度 |
---|---|---|
推模式 | 主题主动推送数据给观察者 | ⭐⭐⭐⭐ |
拉模式 | 观察者主动从主题获取数据 | ⭐⭐⭐ |
事件驱动 | 基于事件的松耦合实现 | ⭐⭐⭐⭐⭐ |
推模式实现:
java
// 推模式:主题主动推送数据给观察者
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);
}
}
拉模式实现:
java
// 拉模式:观察者主动从主题获取数据
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);
}
}
事件驱动实现:
java
// 事件驱动:基于事件的松耦合实现
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 🎯 标准实现示例
java
// 观察者接口 - 定义观察者的行为
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 📰 实际应用示例
💡 场景:新闻社发布新闻,各个新闻频道自动接收并报道!
问题:新闻社需要及时通知所有订阅的新闻频道
java
// 新闻发布系统 - 具体主题
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类图
uses uses implements implements <<interface>> Strategy +algorithmInterface() ConcreteStrategyA +algorithmInterface() ConcreteStrategyB +algorithmInterface() Context -strategy: Strategy +setStrategy(strategy) +contextInterface() Client +useStrategy()
⏱️ 策略模式时序图
客户端 上下文 策略 setStrategy(strategy) contextInterface() algorithmInterface() result result 客户端 上下文 策略
2.1 🎭 什么是策略模式?
一句话理解:定义一系列算法,让它们可以互相替换,就像选择不同的支付方式一样!
定义:定义一系列的算法,把它们一个个封装起来,并且使它们可以互相替换。
应用场景:支付方式选择、排序算法选择、压缩算法选择、游戏角色技能选择
2.2 🛠️ 策略模式的实现
2.2.1 🏗️ 基本结构
💡 小贴士:策略模式就像游戏中的技能选择,玩家可以根据需要切换不同的技能!
核心组件:
- Strategy(策略):算法的抽象接口
- ConcreteStrategy(具体策略):具体的算法实现
- Context(上下文):使用策略的客户端
2.2.2 🚀 多种实现方式
实现方式 | 特点 | 推荐度 |
---|---|---|
接口策略 | 通过接口定义策略 | ⭐⭐⭐⭐⭐ |
枚举策略 | 使用枚举简化策略 | ⭐⭐⭐⭐ |
函数式策略 | 使用Lambda表达式 | ⭐⭐⭐⭐⭐ |
接口策略实现:
java
// 接口策略:通过接口定义策略
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);
}
}
枚举策略实现:
java
// 枚举策略:使用枚举简化策略
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);
}
}
函数式策略实现:
java
// 函数式策略:使用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 🎯 标准实现示例
java
// 策略接口 - 定义算法的抽象
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 💰 实际应用示例
💡 场景:电商平台支持多种支付方式,用户可以根据需要选择不同的支付策略!
问题:需要支持多种支付方式,并且可以灵活切换
java
// 支付策略接口 - 定义支付行为的抽象
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类图
uses creates uses uses implements <<interface>> Command +execute() +undo() ConcreteCommand -receiver: Receiver +execute() +undo() Receiver +action() +undoAction() Invoker -command: Command +setCommand(command) +executeCommand() +undoCommand() Client +useCommand()
⏱️ 命令模式时序图
客户端 调用者 命令 接收者 setCommand(command) executeCommand() execute() action() result result result 客户端 调用者 命令 接收者
3.1 🎭 什么是命令模式?
一句话理解:将请求封装为对象,支持撤销和重做,就像遥控器一样!
定义:将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化。
应用场景:遥控器系统、撤销/重做功能、宏命令、日志记录、事务处理
3.2 🛠️ 命令模式的实现
3.2.1 🏗️ 基本结构
💡 小贴士:命令模式就像遥控器,每个按钮对应一个命令,可以轻松实现撤销重做!
核心组件:
- Command(命令):封装请求的接口
- ConcreteCommand(具体命令):具体的命令实现
- Receiver(接收者):执行命令的对象
- Invoker(调用者):使用命令的客户端
3.2.2 🚀 多种实现方式
实现方式 | 特点 | 推荐度 |
---|---|---|
简单命令 | 一个命令对应一个接收者 | ⭐⭐⭐⭐ |
宏命令 | 一个命令包含多个子命令 | ⭐⭐⭐⭐⭐ |
撤销重做 | 支持命令的撤销和重做 | ⭐⭐⭐⭐⭐ |
简单命令实现:
java
// 简单命令:一个命令对应一个接收者
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();
}
}
宏命令实现:
java
// 宏命令:一个命令包含多个子命令
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);
}
}
撤销重做实现:
java
// 撤销重做:支持命令的撤销和重做
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 🎯 标准实现示例
java
// 命令接口 - 定义命令的行为
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 🎯 实际应用示例
java
// 电器接口
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();
}
}