设计模式-命令模式
在软件开发过程中,经常需要在一个对象中调用另外一个对象的方法去执行某种操作,但是调用方可能需要执行不同对象的方法;这时候可以考虑使用命令模式,来减少调用方和执行方的耦合,让调用方不用关注具体的执行方是谁,也不需要关注具体的实现;命令模式的主要特点就是通过引入command对象,使得命令的调用方和具体执行方解耦;
1.组成结构
1>Invoker
命令的调用方,就是谁要来执行操作的,它通过command对象来执行命令,会持有一个command的引用,如果是批量处理命令的话,会有一个command 队列的引用;
2>Command
抽象命令类,包含一个execute方法用来执行命令;在Invoker中会进行调用execute方法;
3>ConcreteCommand
具体的命令类,实现了Command抽象类的execute方法,会调用receiver.action方法来完成命令的执行;
4>Receiver
命令的执行者,来执行命令的具体的操作的;会有一个action方法,被ConcreteCommand来调用;
具体的代码
1.Invoker
public class Invoker {
private Command command;
public Invoker(Command command) {
this.command = command;
}
public void doSomething() {
this.command.execute();
}
}
2.抽象Command
public abstract class Command {
public abstract void execute();
}
3.ConcreteCommand
public class ConcreteCommandA extends Command {
public Receiver receiver;
public ConcreteCommandA(Receiver receiver) {
this.receiver = receiver;
}
@Override
public void execute() {
this.receiver.action();
}
}
4.Receiver
public class Receiver {
public void action(){
System.out.println("具体执行命令!!");
}
}
2. 理解
为什么要通过command来做一个中间类,而不是直接在invoker类中调用receiver的action方法执行对应的操作哪?主要是为了解耦;如果直接调用就耦合了
Invoker invoker = new Invoker(receiver)
invoker.doSomeThing()
这样的话,如果说invoker要调用其他的操作就不行了;通过引入Command,可以注入不同的具体的command来执行操作,系统的灵活性大大提升;举个例子比如有个设置快捷键的功能,针对某一个快捷键A,可以设置为打印,也可以设置为删除,复制等操作;我们就可以把这些操作抽象成命令,这样的话,可以随便设置,而不固定于某一种操作;这就是命令模式的优点所在;另外命令模式也可以实现批处理的命令执行,这时候需要把调用方Invoker中添加一个Command队列的引用;
class CommandQueue {
//定义一个ArrayList来存储命令队列
private ArrayList<Command> commands = new ArrayList<Command>();
public void addCommand(Command command) {
commands.add(command);
}
public void removeCommand(Command command) {
commands.remove(command);
}
//循环调用每一个命令对象的execute()方法
public void execute() {
for (Object command : commands) {
((Command)command).execute();
}
}
}
class Invoker {
private CommandQueue commandQueue; //维持一个CommandQueue对象的引用
//构造注入
public Invoker(CommandQueue commandQueue) {
this. commandQueue = commandQueue;
}
//设值注入
public void setCommandQueue(CommandQueue commandQueue) {
this.commandQueue = commandQueue;
}
//调用CommandQueue类的execute()方法
public void call() {
commandQueue.execute();
}
}
总结:命令模式的优点有
1>降低系统的耦合性,通过引入了一个command,解耦了命令的调用方和执行方;
2>新的命令可以很方便的加入到系统中,扩展性很好,直接添加command的具体实现即可;
3>可以很容易的实现队列,请求的撤销和恢复;
当然缺点就是引入了大量的类,每增加一种命令的操作就引入了一个新的类去处理