
什么是命令模式?
命令模式允許您將命令發送者(客戶端)和命令執行者(接收者)解耦,使得發送者無需知道接收者的具體類別。
-
命令(Command):聲明了執行操作的接口,通常包括一個 execute
方法。 -
具體命令(Concrete Command):實現了命令接口,包含了實際的操作邏輯。每個具體命令對象都與一個接收者相關聯。 -
接收者(Receiver):執行命令實際操作的對象。 -
調用者(Invoker):負責調用命令對象來執行請求。 -
客戶端(Client):創建命令對象并設置其接收者,然后將命令對象傳遞給調用者。
為什么需要命令模式?
-
解耦:命令模式可以將發送者和接收者解耦,發送者無需知道接收者的具體實現,從而提高了系統的靈活性。 -
可擴展性:您可以輕松地添加新的命令類,而無需修改已有的代碼。 -
撤銷操作:命令對象通常會保存操作的狀態,從而支持撤銷操作。 -
日志記錄和事務管理:您可以使用命令模式來記錄所有執行的命令,以便進行事務管理或撤銷。
命令模式的實現
Command
,它包括了一個 execute
方法:void execute();
}
TurnOnCommand
、ChangeChannelCommand
和 AdjustVolumeCommand
,它們實現了 Command
接口,并分別執行相應的操作。private Television television;
public TurnOnCommand(Television television) {
this.television = television;
}
public void execute() {
television.turnOn();
}
}
// 類似地實現 ChangeChannelCommand 和 AdjustVolumeCommand
Television
,它包含了實際的操作邏輯:public void turnOn() {
System.out.println("電視已打開");
}
public void changeChannel() {
System.out.println("切換頻道");
}
public void adjustVolume() {
System.out.println("調整音量");
}
}
RemoteControl
,它接收并執行命令:private Command command;
public void setCommand(Command command) {
this.command = command;
}
public void pressButton() {
command.execute();
}
}
public static void mAIn(String[] args) {
Television television = new Television();
Command turnOnCommand = new TurnOnCommand(television);
Command changeChannelCommand = new ChangeChannelCommand(television);
Command adjustVolumeCommand = new AdjustVolumeCommand(television);
RemoteControl remoteControl = new RemoteControl();
remoteControl.setCommand(turnOnCommand);
remoteControl.pressButton();
remoteControl.setCommand(changeChannelCommand);
remoteControl.pressButton();
remoteControl.setCommand(adjustVolumeCommand);
remoteControl.pressButton();
}
}
宏命令
-
打開文件 -
編輯文件 -
保存文件
macroCommand
,它包含了 add
和 execute
方法:void add(Command command);
void execute();
}
TextEditorMacro
,它可以添加和執行多個子命令:private List<Command> commands = new ArrayList<>();
public void add(Command command) {
commands.add(command);
}
public void execute() {
for (Command command : commands) {
command.execute();
}
}
}
OpenFileCommand
、EditFileCommand
和 SaveFileCommand
,它們分別執行打開、編輯和保存文件的操作。public static void main(String[] args) {
OpenFileCommand openFile = new OpenFileCommand();
EditFileCommand editFile = new EditFileCommand();
SaveFileCommand saveFile = new SaveFileCommand();
TextEditorMacro macro = new TextEditorMacro();
macro.add(openFile);
macro.add(editFile);
macro.add(saveFile);
// 執行宏命令,依次執行子命令
macro.execute();
}
}
撤銷和重做
undo
方法來恢復到之前的狀態。Command
,包括了 execute
和 undo
方法:void execute();
void undo();
}
AddTextCommand
和 DeleteTextCommand
,它們分別執行添加文本和刪除文本的操作,并實現了 undo
方法來撤銷操作。private TextEditor textEditor;
private String addedText;
public AddTextCommand(TextEditor textEditor, String addedText) {
this.textEditor = textEditor;
this.addedText = addedText;
}
public void execute() {
textEditor.addText(addedText);
}
public void undo() {
textEditor.deleteText(addedText);
}
}
// 類似地實現 DeleteTextCommand
TextEditor
,它包含了實際的文本編輯邏輯,包括添加文本、刪除文本和顯示文本。private StringBuilder text = new StringBuilder();
public void addText(String addedText) {
text.Append(addedText);
}
public void deleteText(String deletedText) {
int start = text.lastIndexOf(deletedText);
if (start != -1) {
text.delete(start, start + deletedText.length());
}
}
public void displayText() {
System.out.println(text.toString());
}
}
public static void main(String[] args) {
TextEditor textEditor = new TextEditor();
Command addCommand1 = new AddTextCommand(textEditor, "Hello, ");
Command addCommand2 = new AddTextCommand(textEditor, "Design Patterns!");
Command deleteCommand = new DeleteTextCommand(textEditor, "Patterns!");
// 執行添加和刪除操作
addCommand1.execute();
addCommand2.execute();
deleteCommand.execute();
// 顯示當前文本
textEditor.displayText(); // 輸出: Hello, Design!
// 撤銷刪除操作
deleteCommand.undo();
// 顯示當前文本
textEditor.displayText(); // 輸出: Hello, Design Patterns!
}
}