行为设计模式 - 命令设计模式
命令模式是行为设计模式之一。命令设计模式用于在请求 - 响应模型中实现松散耦合。

目录[ 隐藏 ]
命令模式
在命令模式中,请求被发送到invoker和调用者将其传递给封装command对象。
Command对象将请求传递Receiver给执行特定操作的适当方法。
客户端程序创建接收器对象,然后将其附加到命令。然后它创建调用者对象并附加命令对象以执行操作。
现在,当客户端程序执行操作时,它将根据命令和接收器对象进行处理。
命令设计模式示例
我们将看一下我们可以实现Command模式的真实场景。假设我们想要提供一个文件系统实用程序,其中包含打开,写入和关闭文件的方法。此文件系统实用程序应支持多种操作系统,如Windows和Unix。
要实现我们的文件系统实用程序,首先我们需要创建实际完成所有工作的接收器类。
由于我们使用java中的接口进行编码,因此我们可以FileSystemReceiver为不同的操作系统风格(如Windows,Unix,Solaris等)提供接口及其实现类。
命令模式接收器类
package com.journaldev.design.command;
public interface FileSystemReceiver {
void openFile();
void writeFile();
void closeFile();
}
FileSystemReceiver接口定义实现类的契约。为简单起见,我正在创建两种接收器类,以便与Unix和Windows系统一起使用。
package com.journaldev.design.command;
public class UnixFileSystemReceiver implements FileSystemReceiver {
@Override
public void openFile() {
System.out.println("Opening file in unix OS");
}
@Override
public void writeFile() {
System.out.println("Writing file in unix OS");
}
@Override
public void closeFile() {
System.out.println("Closing file in unix OS");
}
}
package com.journaldev.design.command;
public class WindowsFileSystemReceiver implements FileSystemReceiver {
@Override
public void openFile() {
System.out.println("Opening file in Windows OS");
}
@Override
public void writeFile() {
System.out.println("Writing file in Windows OS");
}
@Override
public void closeFile() {
System.out.println("Closing file in Windows OS");
}
}
你有没有注意到Override注释,如果你想知道为什么使用它,请阅读java注释并覆盖注释的好处。
现在我们的接收器类已经准备就绪,我们可以继续实现我们的Command类。
命令模式接口和实现
我们可以使用接口或抽象类来创建我们的基本命令,这是一个设计决策,取决于您的要求。
我们正在使用接口,因为我们没有任何默认实现。
package com.journaldev.design.command;
public interface Command {
void execute();
}
现在我们需要为接收器执行的所有不同类型的动作创建实现。由于我们有三个动作,我们将创建三个Command实现。每个Command实现都会将请求转发给适当的接收方法。
package com.journaldev.design.command;
public class OpenFileCommand implements Command {
private FileSystemReceiver fileSystem;
public OpenFileCommand(FileSystemReceiver fs){
this.fileSystem=fs;
}
@Override
public void execute() {
//open command is forwarding request to openFile method
this.fileSystem.openFile();
}
}
package com.journaldev.design.command;
public class CloseFileCommand implements Command {
private FileSystemReceiver fileSystem;
public CloseFileCommand(FileSystemReceiver fs){
this.fileSystem=fs;
}
@Override
public void execute() {
this.fileSystem.closeFile();
}
}
package com.journaldev.design.command;
public class WriteFileCommand implements Command {
private FileSystemReceiver fileSystem;
public WriteFileCommand(FileSystemReceiver fs){
this.fileSystem=fs;
}
@Override
public void execute() {
this.fileSystem.writeFile();
}
}
现在我们已准备好接收器和命令实现,因此我们可以实现调用者类。
命令模式调用者类
Invoker是一个简单的类,它封装了Command并将请求传递给命令对象来处理它。
package com.journaldev.design.command;
public class FileInvoker {
public Command command;
public FileInvoker(Command c){
this.command=c;
}
public void execute(){
this.command.execute();
}
}
我们的文件系统实用程序实现已准备就绪,我们可以编写一个简单的命令模式客户端程序。但在此之前,我将提供一个实用程序方法来创建适当的FileSystemReceiver对象。
由于我们可以使用System类来获取操作系统信息,我们将使用它,否则我们可以使用Factory模式根据输入返回适当的类型。
package com.journaldev.design.command;
public class FileSystemReceiverUtil {
public static FileSystemReceiver getUnderlyingFileSystem(){
String osName = System.getProperty("os.name");
System.out.println("Underlying OS is:"+osName);
if(osName.contains("Windows")){
return new WindowsFileSystemReceiver();
}else{
return new UnixFileSystemReceiver();
}
}
}
现在让我们开始创建将使用我们的文件系统实用程序的命令模式示例客户端程序。
package com.journaldev.design.command;
public class FileSystemClient {
public static void main(String[] args) {
//Creating the receiver object
FileSystemReceiver fs = FileSystemReceiverUtil.getUnderlyingFileSystem();
//creating command and associating with receiver
OpenFileCommand openFileCommand = new OpenFileCommand(fs);
//Creating invoker and associating with Command
FileInvoker file = new FileInvoker(openFileCommand);
//perform action on invoker object
file.execute();
WriteFileCommand writeFileCommand = new WriteFileCommand(fs);
file = new FileInvoker(writeFileCommand);
file.execute();
CloseFileCommand closeFileCommand = new CloseFileCommand(fs);
file = new FileInvoker(closeFileCommand);
file.execute();
}
}
请注意,客户端负责创建适当类型的命令对象。例如,如果要编写文件,则不应创建CloseFileCommand对象。
客户端程序还负责将接收器连接到命令,然后命令调用者类。
上述命令模式示例程序的输出是:
Underlying OS is:Mac OS X
Opening file in unix OS
Writing file in unix OS
Closing file in unix OS
命令模式类图
这是我们的文件系统实用程序实现的类图。

命令模式重点
- 命令是命令设计模式的核心,它定义了实现合同。
- Receiver实现与命令实现分开。
- 命令实现类选择了调用接收器对象的方法,对于接收器中的每个方法都会有一个命令实现。它作为接收器和动作方法之间的桥梁。
- Invoker类只是将请求从客户端转发到命令对象。
- 客户端负责实例化适当的命令和接收器实现,然后将它们关联在一起。
- 客户端还负责实例化调用者对象并将命令对象与其关联并执行操作方法。
- 命令设计模式很容易扩展,我们可以在接收器中添加新的操作方法,并在不更改客户端代码的情况下创建新的Command实现。
- Command设计模式的缺点是代码变得庞大而且混淆了很多动作方法,并且因为有很多关联。
命令设计模式JDK示例
Runnable接口(java.lang.Runnable)和Swing Action(javax.swing.Action)使用命令模式。


169

被折叠的 条评论
为什么被折叠?



