定义:将一个请求封装为一个对象,从而可用不同的请求对客户进行参数化;对请求队列或者请求日志以及支持可撤销的操作。
UML图:
结构:
抽象命令接口Command:定义命令的接口,声明执行的方法。
具体的命令对象ConcreteCommand:持有具体的接受者对象,完成具体的具体的命令。
接受者对象Receiver:接受者对象,真正执行命令的对象。
请求者对象Invoker:持有命令对象,要求命令对象执行请求。
客户端对象Client:创建具体命令的对象并且设置命令对象的接受者。
代码:
抽象命令接口:
abstract class Command { public abstract void execute(); }
具体命令对象
class ConcreteCommand extends Command { private Receiver receiver; //维持一个对请求接收者对象的引用 public void execute() { receiver.action(); //调用请求接收者的业务处理方法action() } }
接受者对象
class Receiver { public void action() { //具体操作 } }
请求者对象
class Invoker { private Command command; //构造注入 public Invoker(Command command) { this.command = command; } //设值注入 public void setCommand(Command command) { this.command = command; } //业务方法,用于调用命令类的execute()方法 public void call() { command.execute(); } }
书上的例题
import java.util.*; //功能键设置窗口类 class FBSettingWindow { private String title; //窗口标题 //定义一个ArrayList来存储所有功能键 private ArrayList<FunctionButton> functionButtons = new ArrayList<FunctionButton>(); public FBSettingWindow(String title) { this.title = title; } public void setTitle(String title) { this.title = title; } public String getTitle() { return this.title; } public void addFunctionButton(FunctionButton fb) { functionButtons.add(fb); } public void removeFunctionButton(FunctionButton fb) { functionButtons.remove(fb); } //显示窗口及功能键 public void display() { System.out.println("显示窗口:" + this.title); System.out.println("显示功能键:"); for (Object obj : functionButtons) { System.out.println(((FunctionButton)obj).getName()); } System.out.println("------------------------------"); } } //功能键类:请求发送者 class FunctionButton { private String name; //功能键名称 private Command command; //维持一个抽象命令对象的引用 public FunctionButton(String name) { this.name = name; } public String getName() { return this.name; } //为功能键注入命令 public void setCommand(Command command) { this.command = command; } //发送请求的方法 public void onClick() { System.out.print("点击功能键:"); command.execute(); } } //抽象命令类 abstract class Command { public abstract void execute(); } //帮助命令类:具体命令类 class HelpCommand extends Command { private HelpHandler hhObj; //维持对请求接收者的引用 public HelpCommand() { hhObj = new HelpHandler(); } //命令执行方法,将调用请求接收者的业务方法 public void execute() { hhObj.display(); } } //最小化命令类:具体命令类 class MinimizeCommand extends Command { private WindowHanlder whObj; //维持对请求接收者的引用 public MinimizeCommand() { whObj = new WindowHanlder(); } //命令执行方法,将调用请求接收者的业务方法 public void execute() { whObj.minimize(); } } //窗口处理类:请求接收者 class WindowHanlder { public void minimize() { System.out.println("将窗口最小化至托盘!"); } } //帮助文档处理类:请求接收者 class HelpHandler { public void display() { System.out.println("显示帮助文档!"); } }
import javax.xml.parsers.*; import org.w3c.dom.*; import org.xml.sax.SAXException; import java.io.*; public class XMLUtil { //该方法用于从XML配置文件中提取具体类类名,并返回一个实例对象,可以通过参数的不同返回不同类名节点所对应的实例 public static Object getBean(int i) { try { //创建文档对象 DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = dFactory.newDocumentBuilder(); Document doc; doc = builder.parse(new File("config.xml")); //获取包含类名的文本节点 NodeList nl = doc.getElementsByTagName("className"); Node classNode = null; if (0 == i) { classNode = nl.item(0).getFirstChild(); } else { classNode = nl.item(1).getFirstChild(); } String cName = classNode.getNodeValue(); //通过类名生成实例对象并将其返回 Class c = Class.forName(cName); Object obj = c.newInstance(); return obj; } catch(Exception e){ e.printStackTrace(); return null; } } }
class Client { public static void main(String args[]) { FBSettingWindow fbsw = new FBSettingWindow("功能键设置"); FunctionButton fb1,fb2; fb1 = new FunctionButton("功能键1"); fb2 = new FunctionButton("功能键1"); Command command1,command2; //通过读取配置文件和反射生成具体命令对象 command1 = (Command)XMLUtil.getBean(0); command2 = (Command)XMLUtil.getBean(1); //将命令对象注入功能键 fb1.setCommand(command1); fb2.setCommand(command2); fbsw.addFunctionButton(fb1); fbsw.addFunctionButton(fb2); fbsw.display(); //调用功能键的业务方法 fb1.onClick(); fb2.onClick(); } }