命令模式(Command Pattern)是用来实现在一个请求 - 响应模型松耦合。在命令模式中,请求被发送给调用者和调用它传递给被封装的命令对象。 Command对象将请求传递到接收器的适当的方法来执行特定操作。客户端程序创建接收器对象,然后将其连接到命令。然后,它会创建调用对象和附加命令对象执行的操作。现在,当客户端程序执行的操作,它是基于命令和接收对象的处理。
我们将着眼于真实的生活场景,我们可以实现Command模式。比方说,我们希望提供一个文件系统工具与具体操作文件的打开,写入和关闭文件功能,它应该支持多种操作系统,如Windows和Unix。
为了实现我们的文件系统工具,首先我们需要创建一个接收器类实现以上所有的工作。由于我们在Java依据接口设计,我们可以有FileSystemReceiver接口和它的实现类实现不同的操作系统,如Windows,UNIX的Solaris等
FileSystemReceiver.java
package com.journaldev.design.command; public interface FileSystemReceiver { void openFile(); void writeFile(); void closeFile();}
FileSystemReceiver接口定义了实现类实现规则方法,为了简单,我只创建了windows,linux两个接收器。
UnixFileSystemReceiver.java
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"); } }WindowsFileSystemReceiver.java
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"); } }conmand接口设计与实现:
我们可以使用接口或抽象类实现,具体实现取决于你的需求,这里我仍使用接口实现
package com.journaldev.design.command;public interface Command { void execute();}现在,我们 需要创建 实现 所有不同 类型的action 由接收器 进行的 , 因为我们有 三个acton ,我们将创建 三个命令 实现 ,每个 命令 执行将 请求转发到 接收器的 适当的方法。
OpenFileCommand.java
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(); } }CloseFileCommand.java
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(); } }WriteFileCommand.java
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(); } }现在接收器与Conmand实现已完成,下面实现调用类。
调用是封装的命令和请求传递给命令对象来处理它一个简单的类。
FileInvoker.java
package com.journaldev.design.command; public class FileInvoker { public Command command; public FileInvoker(Command c){ this.command=c; } public void execute(){ this.command.execute(); }}FileSystemReceiverUtil.java
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(); } } }下面创建客户端类使用我们的文件系统Util
FileSystemClient.java
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(); } }程序输出:
Underlying OS is:Mac OS X
Opening
file
in
unix OS
Writing
file
in
unix OS
Closing
file
in
unix OS
类结构视图:
要点总结:
命令是这种模式,它定义了规则执行核心。
接收机的实现是由分开的命令执行。 命令实现类选择的方法来调用接收对象,每个方法的接收器会有一个命令执行。它的工作原理是接收器和行动方法之间的桥梁。 调用类从客户端获取请求,将命令对象转发。 客户端负责实例化相应的命令并接收执行,然后将它们联系到一起。 客户端还负责调用实例化对象,并与之关联的命令对象,并执行该操作方法。 Command模式很容易扩展的,我们可以在接收器中添加新的操作方法,并创建新的命令的实现在不改变客户端代码。 command模式的缺点是代码量是巨大的,因为这么多的关联和混乱有大量的动作和方法。