一 概念
命令模式:将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。
结构图如下:
二 原理
请求的发起者不直接与请求的执行者进行交互;而是由请求的传达者中转命令。
如结构图所示,
Client作为请求的提出者,Invoker作为请求的传达者,Receiver作为请求的执行者。其中Command作为抽象类抽象出命令执行方法,ConcreteCommand作为Command的子类重写出针对于执行者的具体命令。
具体由提出者Client提出请求,传达者接收具体执行的ConcreteCommand为参数;传达者执行Command命令,在Command的子类ConcreteCommand中引用receiver。所以最后是由receiver来执行action()
三 优缺点
优点
1 它能较轻易的设计一个命令队列;
2 在需要的情况下,可以较轻易的将命令计入日志;
3 允许接收请求的一方决定是否要否决请求;
4 可以容易的实现对请求的撤销或者重做;
5 由于加进新的具体命令类不影响其他类,因此增加新的命令类很容易。
6 把请求一个操作对象与知道怎么执行一个操作的对象分割开。(最主要的优点)
缺点
Command角色的子类容易膨胀。
四 实现
需求:职员 告诉 领导 电脑坏了。
逻辑:由职员作为请求提出者,由领导作为invoker传达者,由网管负责执行。
这里领导执行的命令由很多,在这里Command引用网管,由ConcreteCommand来做指向Receiver的具体命令。
最后 由网管进行具体操作。
//领导-invoker
public class Leader {
private Command command;
public Command getCommand() {
return command;
}
public void setCommand(Command command) {
this.command = command;
}
public void executeCommand(){
command.execute();
}
}
//网管-receiver
public class Manager {
public void makeChange(){
System.out.println("网管换电脑");
}
public void fixComputer(){
System.out.println("网管修电脑");
}
}
//抽象Command
public abstract class Command {
private Manager manager;
public Command(Manager manager){
this.manager = manager;
}
abstract public void execute();
}
//子类 具体Command 这里是修电脑
public class WebsiteManageCommand extends Command{
private Manager manager;
public WebsiteManageCommand(Manager manager) {
super(manager);
// TODO Auto-generated constructor stub
this.manager=manager;
}
@Override
public void execute() {
// TODO Auto-generated method stub
manager.fixComputer();
}
}
//main方法
public class Main {
public static void main(String[] args) {
Manager manager = new Manager();
Leader leader = new Leader();
Command command = new WebsiteManageCommand(manager);
leader.setCommand(command);//命令作为参数
leader.executeCommand();
}
}
执行结果:网管修电脑
--over--