带你看懂命令模式
我所理解的命令模式:
其定义:在面向对象程式设计的范畴中,命令模式(Command Pattern)是一种设计模式,它尝试以物件来代表实际行动。
该模式分为几个部分:
Command、ConcreteCommand、Receiver、Invoker、Client
1、Command是个接口,声明执行方法。
2、ConcreteCommand 其就是具体命令,看名字就知道其实现了Command接口,不同ConcreteCommand 可以执行不同命令,但基本专注于一件事上。
3、Receiver ConcreteCommand 的执行者。
4、Invoker 要求Receiver执行ConcreteCommand,可以持有很多个ConcreteCommand,比如多线程中往queue里塞任务。
5、Client 创建具体Invoker,调用invoker方法间接执行命令
以古代战争为例:比如皇帝攻打其他国需要向军师下令,然后军师训练军队服从命令,通常有多条命令,但是一条命令只让军队做了一件事,比如开始攻打。而且皇帝只关心自己的命令执行完毕,无需知道军队能做什么,能做多少事。
对应的类:
实现:
Sodier.java
/**
*士兵
*/
public class Sodier {
private String attach;
private String back;
public String getAttach() {
return attach;
}
public void setAttach(String attach) {
this.attach = attach;
}
public String getBack() {
return back;
}
public void setBack(String back) {
this.back = back;
}
}
Army.java
/**
*军队
*具体执行攻打撤退命令
*有多个方法=自己能做很多事情
*/
public class Army {
private Sodier sodier;
public Army(Sodier sodier) {
super();
this.sodier = sodier;
}
public void attach() {
sodier.setAttach("攻击");
System.out.println("攻击");
}
public void back() {
sodier.setBack("撤退");
System.out.println("撤退");
}
}
Command.java
/**
*命令
*一道命令通常只让军队做一件事
*/
interface Command {
void excute();
}
AttachCommand.java
package 命令模式;
public class AttachCommand implements Command{
private Army army;
public AttachCommand(Army army) {
super();
this.army = army;
}
@Override
public void excute() {
// TODO Auto-generated method stub
army.attach();
}
}
AttachCommand.java
public class AttachCommand implements Command{
private Army army;
public AttachCommand(Army army) {
super();
this.army = army;
}
@Override
public void excute() {
// TODO Auto-generated method stub
army.attach();
}
}
UndoCommand.java
public class UndoCommand implements Command{
private Army army;
public UndoCommand(Army army) {
super();
this.army = army;
}
@Override
public void excute() {
// TODO Auto-generated method stub
army.back();
}
}
General.java
/*军师
*军师只关心自己接到的圣旨和下的命令,只让军队做一件事
*这不就是解耦了吗
*/
public class General {
private Command undoCommand;
private Command attackCommand;
public General() {
Sodier sodier = new Sodier();
Army army = new Army(sodier);
undoCommand=new UndoCommand(army);
attackCommand = new AttachCommand(army);
}
/**
* 皇帝调用
*/
public void attach() {
attackCommand.excute();
}
public void undo() {
undoCommand.excute();
}
}
Emperor.java
/*
*当然这里实现过于简洁,通常实在Client里创建ConcreteCommand和Reciver,然后丢给
*Invoker进行处理。
*这里只是为了用这个例子讲解这个模式
*这里我直接在General构造函数自行创建了,一般我们用
*setCommend来进行设置
*/
public class Emperor {
public static void main(String[] args) {
General general = new General();
general.attach();
general.undo();
}
}