系列文章目录
设计模式之-6大设计原则简单易懂的理解以及它们的适用场景和代码示列
设计模式之-单列设计模式,5种单例设计模式使用场景以及它们的优缺点
设计模式之-3种常见的工厂模式简单工厂模式、工厂方法模式和抽象工厂模式,每一种模式的概念、使用场景和优缺点。
设计模式之模板方法模式,通俗易懂快速理解,以及模板方法模式的使用场景
设计模式之-建造者模式通俗易懂理解,以及建造者模式的使用场景和示列代码
设计模式之-代理模式,快速掌握理解代理模式,以及代理模式的使用场景
设计模式之-原型模式,快速掌握原型模式,通俗易懂的理解原型模式以及使用场景
设计模式之-中介者模式,快速掌握中介者模式,通俗易懂的讲解中介者模式以及它的使用场景
设计模式之-责任链模式,快速掌握责任链模式,通俗易懂的讲解责任链模式以及它的使用场景
设计模式之-装饰模式,快速掌握装饰模式,通俗易懂的讲解装饰模式以及它的使用场景
设计模式之-适配器模式,快速掌握适配器模式,通俗易懂的讲解适配器模式以及它的使用场景
一、快速理解命令模式
命令模式是一种行为型设计模式,它将请求封装成一个对象,从而使得可以用不同的请求对客户进行参数化,并且能够支持请求的排队执行、记录日志、撤销和重做等操作。
在现实生活中,命令模式的例子可以是遥控器。遥控器上的按钮(客户端)发送命令(请求)给电视(接收者),电视根据命令进行相应的操作。遥控器上的每个按钮都代表一个具体的命令,可以随时更换或增加按钮(命令)。
二、命令模式使用场景
使用命令模式的主要场景包括:
1.当需要将请求发送者和接收者解耦时,可以使用命令模式。命令对象封装了请求的细节,使得请求发送者和接收者之间没有直接的依赖关系。
- 当需要支持请求的排队执行、记录日志、撤销和重做等操作时,可以使用命令模式。通过将命令对象保存在队列中,可以实现对请求的排队执行和记录,同时可以通过撤销和重做命令对象来进行操作的撤销和重做。
代码示例
下面是一个通俗易懂的命令模式示例代码,以电视遥控器为场景:
// 抽象命令:命令接口
interface Command {
void execute();
}
// 具体命令:打开电视命令
class OpenTVCommand implements Command {
private Television television;
public OpenTVCommand(Television television) {
this.television = television;
}
@Override
public void execute() {
television.open();
}
}
// 具体命令:关闭电视命令
class CloseTVCommand implements Command {
private Television television;
public CloseTVCommand(Television television) {
this.television = television;
}
@Override
public void execute() {
television.close();
}
}
// 接收者:电视
class Television {
public void open() {
System.out.println("打开电视");
}
public void close() {
System.out.println("关闭电视");
}
}
// 请求者:遥控器
class RemoteController {
private Command openCommand;
private Command closeCommand;
public void setOpenCommand(Command openCommand) {
this.openCommand = openCommand;
}
public void setCloseCommand(Command closeCommand) {
this.closeCommand = closeCommand;
}
public void openButtonPressed() {
openCommand.execute();
}
public void closeButtonPressed() {
closeCommand.execute();
}
}
// 客户端代码
public class Main {
public static void main(String[] args) {
Television television = new Television();
Command openCommand = new OpenTVCommand(television);
Command closeCommand = new CloseTVCommand(television);
RemoteController remoteController = new RemoteController();
remoteController.setOpenCommand(openCommand);
remoteController.setCloseCommand(closeCommand);
remoteController.openButtonPressed();
remoteController.closeButtonPressed();
}
}
在上面的示例中,Command是抽象命令接口,定义了命令的执行方法execute。OpenTVCommand和CloseTVCommand是具体命令类,分别实现了抽象命令接口,并在execute方法中调用接收者对象的相应方法。
Television是接收者类,定义了电视的打开和关闭方法。
RemoteController是请求者类,具有打开按钮和关闭按钮,通过设置具体命令对象来执行相应的命令。
在客户端代码中,首先创建了电视对象television。然后创建了打开电视命令对象openCommand和关闭电视命令对象closeCommand,并设置给遥控器对象remoteController。最后,通过调用遥控器对象的打开按钮和关闭按钮方法,分别执行相应的命令。
通过使用命令模式,可以将请求发送者和接收者解耦,使得它们之间的依赖关系更加松散。命令模式还支持请求的排队执行、记录日志、撤销和重做等操作,提供了更多的灵活性和可扩展性。
我们来听一个有趣的故事,加深理解
假设有一个魔法王国,国王统治着整个王国,而魔法师们则拥有各种强大的魔法能力。国王经常需要向魔法师下达各种任务,比如拯救被困的公主、击败恶龙等。
在这个故事中,国王是命令发送者,魔法师是命令接收者,而命令模式允许国王将不同的命令封装成对象,并将其发送给魔法师进行执行。
现在,我们来看一下如何使用命令模式来实现这个故事。
首先,我们定义一个命令(Command)接口,其中包含一个执行(execute)方法。
interface Command {
void execute();
}
然后,我们定义具体的命令类,比如拯救公主命令(SavePrincessCommand)和击败恶龙命令(DefeatDragonCommand),它们实现了命令接口。
class SavePrincessCommand implements Command {
private Wizard wizard;
public SavePrincessCommand(Wizard wizard) {
this.wizard = wizard;
}
public void execute() {
wizard.savePrincess();
}
}
class DefeatDragonCommand implements Command {
private Wizard wizard;
public DefeatDragonCommand(Wizard wizard) {
this.wizard = wizard;
}
public void execute() {
wizard.defeatDragon();
}
}
接下来,我们定义一个命令发送者(King)类,它负责创建具体的命令对象并将其发送给魔法师。
class King {
private Command command;
public void setCommand(Command command) {
this.command = command;
}
public void sendCommand() {
command.execute();
}
}
最后,我们定义一个命令接收者(Wizard)类,它负责执行具体的命令。
class Wizard {
public void savePrincess() {
System.out.println("魔法师正在拯救公主...");
// 具体的拯救公主逻辑
}
public void defeatDragon() {
System.out.println("魔法师正在击败恶龙...");
// 具体的击败恶龙逻辑
}
}
现在,我们来看一下如何将这些角色组合起来并运行起来。
public class CommandPatternStory {
public static void main(String[] args) {
// 创建命令接收者
Wizard wizard = new Wizard();
// 创建命令对象并设置命令接收者
Command savePrincessCommand = new SavePrincessCommand(wizard);
Command defeatDragonCommand = new DefeatDragonCommand(wizard);
// 创建命令发送者并设置具体的命令
King king = new King();
king.setCommand(savePrincessCommand);
// 发送命令
king.sendCommand(); // 魔法师正在拯救公主...
// 修改命令并发送新的命令
king.setCommand(defeatDragonCommand);
king.sendCommand(); // 魔法师正在击败恶龙...
}
}
在这个故事中,命令模式允许国王将拯救公主和击败恶龙这两个不同的任务封装成命令对象,并将其发送给魔法师进行执行。国王不需要知道具体的执行细节,只需要发送命令即可。魔法师根据接收到的命令进行相应的行动。
命令模式的优点在这个故事中体现为:
- 国王和魔法师之间解耦,国王只需要发送命令,而不需要关注具体的执行逻辑。
- 可以轻松地扩展和修改命令,例如添加新的命令或修改现有的命令,而不需要修改发送者和接收者之间的关系。
希望这个故事能帮助你理解命令模式的概念和应用!