策略模式与命令模式的区别 是什么?

本文深入探讨了策略模式与命令模式的区别,解释了设计模式如何通过封装算法来提高软件的灵活性和可维护性。重点阐述了策略模式解决单一问题,而命令模式处理多个问题的能力。同时,文章提供了设计模式之间的相似性和差异性分析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


策略模式 把易于变化的行为分别封装起来,让它们之间可以互相替换, 让这些行为的变化独立于拥有这些行为的客户。

  GoF《设计模式》中说道:定义一系列算法,把它们一个个封装起来,并且使它们可以相互替换。该模式使得算法可独立于它们的客户变化。

Command命令模式是一种对象行为型模式,它主要解决的问题是:在软件构建过程中,“行为请求者”与“行为实现者”通常呈现一种“紧耦合”的问题。
  GoF《设计模式》中说道:将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。 

 

我个人觉得,策略模式和命令模式的其中一个最大区别,是在于:策略模式对付的问题域通常是一个,就是说,多个策略只是处理同一个问题,而命令模式对付的是多个问题域,就是很多不同的命令来做不同的事情。

各种设计模式之间,有很多相似之处,只是由于侧重的方向不同。

转载于:https://www.cnblogs.com/baiduligang/p/4247312.html

<think>命令模式策略模式的主要区别: 1. **目的不同**: - 策略模式:定义一系列算法,使它们可以互相替换,让算法独立于客户端而变化。 - 命令模式:将请求封装成对象,以便使用不同的请求、队列或日志来参数化其他对象,并支持可撤销操作。 2. **关注点不同**: - 策略模式关注的是算法的互换性封装,客户端通常主动选择不同的策略。 - 命令模式关注的是操作的封装请求的发送者接收者的解耦,通常用于支持撤销、队列、日志等。 3. **使用方式不同**: - 在策略模式中,客户端通常知道可用的策略并主动切换。 - 在命令模式中,客户端创建命令对象,然后由调用者执行,客户端可能不知道具体命令的实现。 4. **类结构差异**: - 策略模式:一个Context类持有一个策略接口的引用,策略接口有多个具体实现(算法)。 - 命令模式:一个Invoker类持有命令接口的引用,命令接口有多个具体实现(操作),每个具体命令持有接收者(执行实际操作的对象)的引用。 5. **功能扩展**: - 命令模式支持撤销(undo)重做(redo)功能,而策略模式通常不支持。 下面用代码示例说明两种模式: ### 策略模式示例 ```java // 策略接口 interface SortingStrategy { void sort(int[] data); } // 具体策略:冒泡排序 class BubbleSort implements SortingStrategy { public void sort(int[] data) { System.out.println("Using bubble sort"); // 实现冒泡排序算法 // ... } } // 具体策略:快速排序 class QuickSort implements SortingStrategy { public void sort(int[] data) { System.out.println("Using quick sort"); // 实现快速排序算法 // ... } } // 上下文类 class Sorter { private SortingStrategy strategy; public void setStrategy(SortingStrategy strategy) { this.strategy = strategy; } public void executeSort(int[] data) { strategy.sort(data); } } // 客户端使用 public class StrategyDemo { public static void main(String[] args) { Sorter sorter = new Sorter(); int[] data = {5, 2, 7, 1}; // 使用冒泡排序 sorter.setStrategy(new BubbleSort()); sorter.executeSort(data); // 切换到快速排序 sorter.setStrategy(new QuickSort()); sorter.executeSort(data); } } ``` ### 命令模式示例(带撤销功能) ```java // 命令接口 interface Command { void execute(); void undo(); } // 接收者:执行实际操作的对象 class TextEditor { private StringBuilder text = new StringBuilder(); private String lastDeleted; public void write(String newText) { text.append(newText); } public void deleteLastWord() { if (text.length() > 0) { lastDeleted = text.substring(text.lastIndexOf(" ") + 1); text.delete(text.lastIndexOf(" "), text.length()); } } public String getText() { return text.toString(); } public String getLastDeleted() { return lastDeleted; } } // 具体命令:写入命令 class WriteCommand implements Command { private TextEditor editor; private String text; public WriteCommand(TextEditor editor, String text) { this.editor = editor; this.text = text; } public void execute() { editor.write(text); } public void undo() { // 撤销写入:删除最后添加的文本 // 这里简化处理,实际可能需要记录位置 // 注意:这个撤销操作并不完美,仅用于示例 editor.deleteLastWord(); } } // 调用者 class Invoker { private Command command; private Stack<Command> history = new Stack<>(); public void setCommand(Command command) { this.command = command; } public void executeCommand() { command.execute(); history.push(command); } public void undo() { if (!history.isEmpty()) { Command lastCommand = history.pop(); lastCommand.undo(); } } } // 客户端使用 public class CommandDemo { public static void main(String[] args) { TextEditor editor = new TextEditor(); Invoker invoker = new Invoker(); // 创建并执行写入命令 Command writeHello = new WriteCommand(editor, "Hello "); invoker.setCommand(writeHello); invoker.executeCommand(); // 文本变为 "Hello " Command writeWorld = new WriteCommand(editor, "World!"); invoker.setCommand(writeWorld); invoker.executeCommand(); // 文本变为 "Hello World!" // 撤销 invoker.undo(); // 撤销"World!" -> 文本变为 "Hello " System.out.println(editor.getText()); } } ``` ### 关键区别总结表 | 特性 | 策略模式 | 命令模式 | |--------------|------------------------------|------------------------------| | **主要目的** | 封装互换算法 | 封装操作请求解耦 | | **核心角色** | 策略接口、具体策略、上下文 | 命令接口、具体命令、调用者、接收者 | | **撤销支持** | 不支持 | 支持 | | **队列/日志**| 不支持 | 支持 | | **使用场景** | 需要动态切换算法 | 需要撤销、事务、宏命令等功能 | §§相关问题§§: 1. 策略模式在哪些实际应用场景中最常用? 2. 命令模式如何实现宏命令(组合多个命令)? 3. 策略模式状态模式有何异同? 4. 在命令模式中,如何处理命令执行过程中的异常?</think># 命令模式策略模式的主要区别 命令模式策略模式都是行为设计模式,它们都通过封装变化来提高代码的灵活性,但它们的应用场景设计目的有本质区别。 ## 核心区别总结 | 特性 | 命令模式 | 策略模式 | |--------------|----------------------------------|--------------------------------| | **主要目的** | 封装请求为对象 | 封装算法系列 | | **关注点** | 请求的封装执行机制 | 算法的选择互换 | | **撤销/重做**| 支持(核心特性) | 不支持 | | **队列支持** | 支持(可排队执行) | 不支持 | | **对象关系** | 命令对象知道接收者 | 策略对象不知道上下文 | | **典型应用** | 操作历史、事务处理、任务队列 | 算法选择、支付方式、排序策略 | ## 代码示例对比 ### 策略模式实现(支付场景) ```java // 策略接口 interface PaymentStrategy { void pay(double amount); } // 具体策略实现 class CreditCardPayment implements PaymentStrategy { public void pay(double amount) { System.out.println("Paid $" + amount + " via Credit Card"); } } class PayPalPayment implements PaymentStrategy { public void pay(double amount) { System.out.println("Paid $" + amount + " via PayPal"); } } // 上下文类 class PaymentContext { private PaymentStrategy strategy; public void setPaymentStrategy(PaymentStrategy strategy) { this.strategy = strategy; } public void executePayment(double amount) { strategy.pay(amount); } } // 客户端使用 public class StrategyDemo { public static void main(String[] args) { PaymentContext context = new PaymentContext(); context.setPaymentStrategy(new CreditCardPayment()); context.executePayment(100.0); context.setPaymentStrategy(new PayPalPayment()); context.executePayment(50.0); } } ``` ### 命令模式实现(文本编辑器场景) ```java // 命令接口 interface Command { void execute(); void undo(); } // 接收者类 class TextEditor { private StringBuilder text = new StringBuilder(); public void addText(String newText) { text.append(newText); } public void deleteText(int length) { if (length > text.length()) length = text.length(); text.delete(text.length() - length, text.length()); } public String getText() { return text.toString(); } } // 具体命令类 class AddTextCommand implements Command { private TextEditor editor; private String text; public AddTextCommand(TextEditor editor, String text) { this.editor = editor; this.text = text; } public void execute() { editor.addText(text); } public void undo() { editor.deleteText(text.length()); } } // 调用者类 class Invoker { private Stack<Command> history = new Stack<>(); public void executeCommand(Command command) { command.execute(); history.push(command); } public void undoLastCommand() { if (!history.isEmpty()) { Command lastCommand = history.pop(); lastCommand.undo(); } } } // 客户端使用 public class CommandDemo { public static void main(String[] args) { TextEditor editor = new TextEditor(); Invoker invoker = new Invoker(); invoker.executeCommand(new AddTextCommand(editor, "Hello ")); invoker.executeCommand(new AddTextCommand(editor, "World!")); System.out.println("Current text: " + editor.getText()); // "Hello World!" invoker.undoLastCommand(); System.out.println("After undo: " + editor.getText()); // "Hello " } } ``` ## 关键区别详解 1. **目的不同**: - 策略模式:封装一系列可互换的算法,让算法独立于使用它的客户端而变化 - 命令模式:将请求封装为对象,使你可以参数化客户端对象,队列请求,记录日志,支持撤销操作 2. **撤销/重做支持**: - 命令模式直接支持撤销操作(核心特性) - 策略模式不支持撤销操作,因为策略是算法而非操作 3. **对象关系**: - 策略模式中,策略对象通常不知道上下文对象 - 命令模式中,命令对象知道接收者对象(执行操作的目标) 4. **使用场景**: - 策略模式:当有多个相关类仅在行为上不同时,或需要算法的不同变体时 - 命令模式:当需要参数化对象、排队请求、支持撤销操作或记录请求日志时 5. **生命周期**: - 策略对象通常长期存在,作为配置的一部分 - 命令对象通常是短期的,执行后被丢弃或存储在历史记录中 ## 何时使用哪种模式 ### 使用策略模式当: - 需要多种算法变体 - 算法需要独立于使用它们的客户端 - 需要在运行时选择算法 - 有多个条件语句用于选择算法 ### 使用命令模式当: - 需要参数化对象 - 需要支持撤销/重做操作 - 需要将操作放入队列并在不同时间执行 - 需要记录操作历史 - 需要支持事务操作
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值