一.命令模式的简介
命令模式(Command Pattern)将一个请求封装为一个对象,从而使你用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作。
命令模式的核心思路: 在程序设计中,一个“行为请求者”和“行为实现者”往往是紧密耦合的,当某些情况下,要对行为进行记录、撤销等操作的时候,就必须对行为实现者和请求者进行解耦为松耦合模式。
命令模式应用案例: Struts中只有一个ActionServlet(相当于命令模式的Invoker),而不同系统有不同的模型类(相当于命令模式中的具体Command),所以Struts通过命令模式保证对不同的行为请求者进行各种操作。
二.命令模式的源码讲解
1.设计类图:
(图片加载慢,多刷新几下,耐心等待……)
注:调用者(Invoker)聚合命令者(Command),二者是聚合关系。
聚合关系:调用者(Invoker)包含命令者(Command),但命令者(Command)不是调用者(Invoker)的一部分。
通俗解释类图 :例如餐馆中顾客点餐的命令怎么执行的呢?顾客(Client
)下命令(Command
)给服务员(Invoker
),服务员(Invoker
)通知和分发命令,寻找能够处理该命令的人,并传达命令,若是点餐命令(Command1
)就把命令传给后厨(receiver1
),若是买单命令(Command2
)就传给收银员(receiver2
)。后厨和收银员接到命令后各自执行具体的处理(调用命令的handle()
)。
三.命令模式的代码实现
1.命令抽象类(Command)
设计分析: 命令抽象类
依赖接受者类,并提供一个处理命令的抽象方法,供子类继承。
package com.pattern.command.command;
import com.pattern.command.receiver.Receiver;
/**
* 命令抽象类
*
* @see 命令者需要知道给谁下命令
*/
public abstract class Command {
protected Receiver receiver;
//创建命令对象,明确给谁下命令
public Command(Receiver receiver) {
this.receiver = receiver;
}
//处理命令
public abstract void handle();
}
2.命令的具体实现类(ConcreteCommand)
设计分析 实现具体的命令,绑定一个接受者,包装一个请求,传递给调用对象。
package com.pattern.command.command;
import com.pattern.command.receiver.Receiver;
/**
* 具体的命令类
*
*/
public class ConcreteCommand extends Command {
//具体的命令通过此构造函数,
public ConcreteCommand(Receiver receiver) {
super(receiver);
}
//执行具体的命令
@Override
public void handle() {
// 将一个接受者对象绑定一个行为,可以让任何的receiver都实现这个行为
receiver.action();
}
}
3.调用者类(Invoker)
设计分析: 调用者类
通过聚合,引入具体命令类
,寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。
package com.pattern.command.invoker;
import com.pattern.command.command.Command;
/**
* 命令调用者(通知命令类执行命令,实现执行不同的具体命令)
*
* @see 相当于餐厅服务员,接收命令,传达命令
*
*/
public class Invoker {
private Command command;
// 设置命令
public void setCommand(Command command) {
this.command = command;
}
// 传达命令
public void doCommandHandle() {
command.handle();
}
}
4.接受者类(Receiver)
设计分析: 接受者类
实现具体命令细节。
package com.pattern.command.receiver;
/**
* 接受者类
*
* @see 执行请求后的操作。任何的类都可以成为接受者,来被命令调用
*
*/
public class Receiver {
public void action() {
System.out.println("接受者执行具体的命令");
};
}
5.客户端(Client)中用法:
设计分析:展示发起请求、命令调用、命令接受、命令执行的实现 。
代码如下:
package com.pattern.command.client;
import com.pattern.command.command.Command;
import com.pattern.command.command.ConcreteCommand;
import com.pattern.command.invoker.Invoker;
import com.pattern.command.receiver.Receiver;
public class Client {
public static void main(String[] args) {
// 创建接受者
Receiver receiver = new Receiver();
// 实例化具体命令类,而不是抽象类
Command command = new ConcreteCommand(receiver);
//创建调用者
Invoker invoker = new Invoker();
//调用者设置命令
invoker.setCommand(command);
//调用者传达命令
invoker.doCommandHandle();
}
}
6.运行结果
执行具体的命令
7.源码下载
本文示例代码下载地址:点击下载
三.总结:
命令模式(Command Pattern)是一种数据驱动的设计模式,它属于行为型模式。请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。
1.命令模式的优点
- 较容易的设计一个命令队列。
- 可以比较容易的将命令记入日志。
- 允许接收请求的一方,决定是否要否决请求。
- 降低系统的耦合度。
- 可轻易的添加新的命令,而不影响其他类。
2.命令模式的缺点
- 太多的具体命令类,增加了代码的复杂性。