将请求封装成为命令对象,使“方法的请求者”与“方法的实现者”解耦。命令对象可以被存储、转发、排队、记录、处理、撤销等。又称为动作(Action)模式或事务(Transaction)模式。
角色
调用者/请求者(Invoker):请求的发送者,持有一个或多个命令对象,通过调用命令对象执行命令接口处理相关请求,它不直接访问接收者
抽象命令类(Command):声明执行命令的接口(execute)
具体命令(ConcreteCommand):抽象命令类的实现类,持有接收者对象,调用接收者的功能接口完成操作。
实现者/接收者(Receiver):执行命令功能的相关操作,是命令的真正实现者
调用者/请求者 Invoker
public class Invoker {
private Command command;
public Invoker() { }
public void setCommand(Command command) {
this.command = command;
}
public void commit() {
this.command.execute();
}
public void rollback() {
this.command.recover();
}
}
抽象命令类 Command
public interface Command {
void execute();
void recover();
}
具体命令 Concrete Command
public class ConcreteCommand implements Command {
private Receiver receiver;
public ConcreteCommand(Receiver receiver) {
this.receiver = receiver;
}
@Override
public void execute() {
receiver.operate();
}
@Override
public void recover() {
receiver.cancel();
}
}
实现者/接收者 Receiver
public class Receiver {
public void operate() {
System.out.println("operate...");
}
public void cancel() {
System.out.println("cancel...");
}
}
测试类
public class CommandPattern {
public static void main(String args[]) {
Receiver receiver = new Receiver();
Invoker invoker = new Invoker();
invoker.setCommand(new ConcreteCommand(receiver));
try {
invoker.commit();
throw new RuntimeException("error occur...");
} catch (RuntimeException e) {
System.out.println(e.getMessage());
invoker.rollback();
}
}
}
operate...
error occur...
cancel...
举例:餐厅点菜
通过服务员(调用者)点菜,支持批量操作,将菜作为命令,根据不同的菜系分配给不同的厨师
public class Waiter {
private List<Cuisine> cuisines = new ArrayList<>();
public void addCuisine(Cuisine cuisine) {
this.cuisines.add(cuisine);
}
public void addCuisines(Cuisine ... coll) {
for (Cuisine cuisine : coll) {
if (!cuisines.contains(cuisine))
cuisines.add(cuisine);
}
}
public void addCuisines(Collection<Cuisine> coll) {
cuisines.addAll(new HashSet<>(coll));
}
public void order() {
for (Cuisine cuisine : cuisines) {
cuisine.order();
}
}
}
public interface Cuisine {
void order();
}
public class CantoneseCuisine implements Cuisine {
private Chef chef = new CantoneseCuisineChef();
@Override
public void order() {
this.chef.cooking();
}
}
public class HunanCuisine implements Cuisine {
private Chef chef = new HunanCuisineChef();
@Override
public void order() {
chef.cooking();
}
}
public class SichuanCuisine implements Cuisine {
private Chef chef = new SichuanCuisineChef();
@Override
public void order() {
this.chef.cooking();
}
}
public interface Chef {
void cooking();
}
public class CantoneseCuisineChef implements Chef {
@Override
public void cooking() {
System.out.println("cooking cantonese cuisine...");
}
}
public class HunanCuisineChef implements Chef {
@Override
public void cooking() {
System.out.println("cooking hunan cuisine...");
}
}
public class SichuanCuisineChef implements Chef {
@Override
public void cooking() {
System.out.println("cooking sichuan cuisine...");
}
}
public class CommandPattern {
public static void main(String args[]) {
Waiter waiter = new Waiter();
waiter.addCuisine(new HunanCuisine());
waiter.addCuisine(new CantoneseCuisine());
waiter.addCuisine(new SichuanCuisine());
waiter.order();
}
}
cooking hunan cuisine...
cooking cantonese cuisine...
cooking sichuan cuisine...
举例:前端请求服务器
将请求封装,通过客户端执行不同的请求,后台执行不同的业务操作
public class FrontClient {
private Request request;
public void setRequest(Request request) {
this.request = request;
}
public void get() {
request.doGet();
}
public void post() {
request.doPost();
}
}
public interface Request {
void doGet();
void doPost();
}
public class HttpRequest implements Request {
private Backend backend;
public HttpRequest(Backend backend) {
this.backend = backend;
}
@Override
public void doGet() {
backend.doGetService();
}
@Override
public void doPost() {
backend.doPostService();
}
}
public class Backend {
public void doGetService() {
System.out.println("do get service...");
}
public void doPostService() {
System.out.println("do post service...");
}
}
public class CommandPattern {
public static void main(String args[]) {
Backend backend = new Backend();
Request request = new HttpRequest(backend);
FrontClient client = new FrontClient();
client.setRequest(request);
client.get();
client.post();
}
}
do get service...
do post service...