🕺 行为型设计模式:对象协作的舞蹈家(上)

🕺 行为型设计模式:对象协作的舞蹈家

💡 温馨提示:本文将以轻松有趣的方式带你探索行为型设计模式的世界,就像在观看一场精彩的"对象舞蹈表演"一样!
🚪 传送门 :在开始我们的"对象协作之旅" 之前,建议先通过这个 🎨 Java设计模式详解:让代码优雅如诗的秘密武器 了解设计模式的基础概念和整体架构,然后通过 🏭 创建型设计模式:对象诞生的艺术与智慧 学习对象创建的艺术,再通过 🏗️ 结构型设计模式:代码架构的魔法师 了解对象组合的艺术,这样能让你更好地理解本文内容!就像跳舞要先学会走路一样!💃

🎪 引言:为什么我们需要行为型设计模式?

arduino 复制代码
🕺 场景:混乱的对象舞蹈现场 🕺
┌─────────────────────────────────────┐
│  💻 程序员小王的一天 💻              │
│                                     │
│  😵 对象间通信像鸡同鸭讲!          │
│  🔥 算法选择像选择困难症!          │
│  🐛 状态管理像迷宫一样复杂!        │
│                                     │
│  💡 突然,行为型设计模式舞者出现了! │
│  🕺 "让我来编排你们的协作舞蹈!"     │
└─────────────────────────────────────┘

行为型设计模式就像是"对象协作"的标准舞蹈编排,让对象之间的通信变得优雅、灵活、高效。

本文将带你探索十一种行为型设计模式,就像观看十一个不同的"对象舞蹈表演"一样精彩!


🎯 本文你将学到什么?

复制代码
🎬 行为型设计模式舞蹈团 🎬
┌─────────────────────────────────────┐
│  🕺 十一位协作舞者登场!            │
│                                     │
│  👀 观察者:一对多通知机制          │
│  🎯 策略者:算法选择专家            │
│  📝 命令者:请求封装大师            │
│  🔄 状态者:状态变化艺术家          │
│  📋 模板者:算法框架设计师          │
│  🔍 迭代者:集合遍历专家            │
│  ⛓️ 责任链:请求处理链              │
│  🤝 中介者:对象交互协调员          │
│  👁️ 访问者:元素操作专家            │
│  💾 备忘录:状态保存专家            │
│  🗣️ 解释器:语言解释专家            │
│                                     │
│  🚀 准备好开始舞蹈之旅了吗?        │
└─────────────────────────────────────┘

👀 第一部分:观察者模式(Observer Pattern)

arduino 复制代码
👀 观察者舞者的登场 👀
┌─────────────────────────────────────┐
│  👀 观察者:我是一对多通知专家!    │
│                                     │
│  📢 主题:"我有新消息!"            │
│  👀 观察者:"我来通知大家!"        │
│  📢 主题:"状态变化了!"            │
│  👀 观察者:"我来更新大家!"        │
│                                     │
│  💡 核心思想:一对多通知机制        │
└─────────────────────────────────────┘

🏗️ 观察者模式UML类图

1.1 🎭 什么是观察者模式?

一句话理解:当一个对象状态改变时,自动通知所有依赖它的对象,就像新闻发布一样!

定义:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

应用场景:事件处理系统、消息推送、数据绑定、日志记录、GUI事件处理

1.2 🛠️ 观察者模式的实现

1.2.1 🏗️ 基本结构

💡 小贴士:观察者模式就像新闻发布系统,主题是新闻社,观察者是各个新闻频道!

核心组件

  • Subject(主题) :被观察的对象,维护观察者列表
  • Observer(观察者) :观察主题的对象,接收通知
  • ConcreteSubject(具体主题) :具体的被观察对象
  • ConcreteObserver(具体观察者) :具体的观察者实现
1.2.2 🚀 多种实现方式
实现方式 特点 推荐度
推模式 主题主动推送数据给观察者 ⭐⭐⭐⭐
拉模式 观察者主动从主题获取数据 ⭐⭐⭐
事件驱动 基于事件的松耦合实现 ⭐⭐⭐⭐⭐

推模式实现

typescript 复制代码
// 推模式:主题主动推送数据给观察者
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);
    }
}

拉模式实现

typescript 复制代码
// 拉模式:观察者主动从主题获取数据
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);
    }
}

事件驱动实现

csharp 复制代码
// 事件驱动:基于事件的松耦合实现
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 🎯 标准实现示例
typescript 复制代码
// 观察者接口 - 定义观察者的行为
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 📰 实际应用示例

💡 场景:新闻社发布新闻,各个新闻频道自动接收并报道!

问题:新闻社需要及时通知所有订阅的新闻频道

typescript 复制代码
// 新闻发布系统 - 具体主题
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)

arduino 复制代码
🎯 策略舞者的登场 🎯
┌─────────────────────────────────────┐
│  🎯 策略者:我是算法选择专家!      │
│                                     │
│  💰 客户:"我要用支付宝支付!"      │
│  🎯 策略者:"我来切换策略!"        │
│  💰 客户:"我要用微信支付!"        │
│  🎯 策略者:"继续切换策略!"        │
│                                     │
│  💡 核心思想:算法可以互相替换      │
└─────────────────────────────────────┘

🏗️ 策略模式UML类图

2.1 🎭 什么是策略模式?

一句话理解:定义一系列算法,让它们可以互相替换,就像选择不同的支付方式一样!

定义:定义一系列的算法,把它们一个个封装起来,并且使它们可以互相替换。

应用场景:支付方式选择、排序算法选择、压缩算法选择、游戏角色技能选择

2.2 🛠️ 策略模式的实现

2.2.1 🏗️ 基本结构

💡 小贴士:策略模式就像游戏中的技能选择,玩家可以根据需要切换不同的技能!

核心组件

  • Strategy(策略) :算法的抽象接口
  • ConcreteStrategy(具体策略) :具体的算法实现
  • Context(上下文) :使用策略的客户端
2.2.2 🚀 多种实现方式
实现方式 特点 推荐度
接口策略 通过接口定义策略 ⭐⭐⭐⭐⭐
枚举策略 使用枚举简化策略 ⭐⭐⭐⭐
函数式策略 使用Lambda表达式 ⭐⭐⭐⭐⭐

接口策略实现

ini 复制代码
// 接口策略:通过接口定义策略
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);
    }
}

枚举策略实现

ini 复制代码
// 枚举策略:使用枚举简化策略
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);
    }
}

函数式策略实现

ini 复制代码
// 函数式策略:使用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 🎯 标准实现示例
csharp 复制代码
// 策略接口 - 定义算法的抽象
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)

arduino 复制代码
📝 命令舞者的登场 📝
┌─────────────────────────────────────┐
│  📝 命令者:我是请求封装大师!      │
│                                     │
│  🎮 遥控器:"我要开灯!"            │
│  📝 命令者:"我来封装请求!"        │
│  🎮 遥控器:"我要关灯!"            │
│  📝 命令者:"继续封装请求!"        │
│                                     │
│  💡 核心思想:将请求封装为对象      │
└─────────────────────────────────────┘

🏗️ 命令模式UML类图

3.1 🎭 什么是命令模式?

一句话理解:将请求封装为对象,支持撤销和重做,就像遥控器一样!

定义:将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化。

应用场景:遥控器系统、撤销/重做功能、宏命令、日志记录、事务处理

3.2 🛠️ 命令模式的实现

3.2.1 🏗️ 基本结构

💡 小贴士:命令模式就像遥控器,每个按钮对应一个命令,可以轻松实现撤销重做!

核心组件

  • Command(命令) :封装请求的接口
  • ConcreteCommand(具体命令) :具体的命令实现
  • Receiver(接收者) :执行命令的对象
  • Invoker(调用者) :使用命令的客户端
3.2.2 🚀 多种实现方式
实现方式 特点 推荐度
简单命令 一个命令对应一个接收者 ⭐⭐⭐⭐
宏命令 一个命令包含多个子命令 ⭐⭐⭐⭐⭐
撤销重做 支持命令的撤销和重做 ⭐⭐⭐⭐⭐

简单命令实现

csharp 复制代码
// 简单命令:一个命令对应一个接收者
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();
    }
}

宏命令实现

csharp 复制代码
// 宏命令:一个命令包含多个子命令
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);
    }
}

撤销重做实现

ini 复制代码
// 撤销重做:支持命令的撤销和重做
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 🎯 标准实现示例
csharp 复制代码
// 命令接口 - 定义命令的行为
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 🎯 实际应用示例
csharp 复制代码
// 电器接口
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();
    }
}

本文使用 markdown.com.cn 排版

相关推荐
饕餮争锋1 小时前
设计模式笔记_行为型_策略模式
笔记·设计模式·策略模式
易元1 小时前
模式组合应用-桥接模式(一)
后端·设计模式
是2的10次方啊1 小时前
🕺 行为型设计模式:对象协作的舞蹈家(中)
设计模式
the sun342 小时前
常见的设计模式(2)单例模式
单例模式·设计模式
一乐小哥5 小时前
从面试高频到实战落地:单例模式全解析(含 6 种实现 + 避坑指南)
java·设计模式
用户84913717547167 小时前
JustAuth实战系列(第11期):测试驱动开发 - 质量保证与重构实践
java·设计模式·单元测试
melonbo9 小时前
代理模式C++
c++·设计模式·系统安全·代理模式
我们从未走散10 小时前
设计模式学习笔记-----单例模式
java·笔记·学习·单例模式·设计模式
long31612 小时前
java 工厂方法设计模式 FactoryMethod
java·开发语言·后端·设计模式