命令模式

定义:将一个请求封装为一个对象,从而可用不同的请求对客户进行参数化;对请求队列或者请求日志以及支持可撤销的操作。

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();  
    }  
}

  

原文地址:https://www.cnblogs.com/a863886199/p/10165622.html