设计模式-命令模式
定义
命令模式(Command Pattern)是对命令的一个封装,每一个命令都是一个操作。请求的一方发出请求,要求执行一个操作,接收的一方收到请求并执行操作。命令模式解耦了请求方和接收方,请求方只需要请求执行命令,不用关心命令是怎么被接收的,怎样被操作等。
本质:解耦命令请求和处理。
属于行为型模式。
适用场景
- 现实语义中具备“命令”操作
- 请求调用者和请求的接收者需要解耦,使得调用者和接受者不直接交互
- 需要抽象出等待执行的行为,比如撤销操作和恢复操作等
- 需要支持命令宏(即命令组合操作)
代码示例
拿下单举例:
- 新建 饭 类和 订单 类
package com.black.design.pattern.command.order;
// 饭
public class Meal {
// 饭名
private String name ;
// 价格
private double price;
// 数量
private int amt;
public Meal(String name, double price, int amt) {
super();
this.name = name;
this.price = price;
this.amt = amt;
}
public String getName() {
return name;
}
public double getPrice() {
return price;
}
public int getAmt() {
return amt;
}
// 总价
public double getTotalAmt() {
return price * amt;
}
}
package com.black.design.pattern.command.order;
import java.util.ArrayList;
import java.util.List;
// 订单
public class Order {
// 饭
private List<Meal> meals = new ArrayList<Meal>();
// 订单总价
private double totalAmt;
public Order() {
}
//点菜
public void addMeal(Meal meal){
meals.add(meal);
totalAmt = totalAmt + meal.getAmt() * meal.getPrice();
}
// 总价
public double getTotalAmt() {
return totalAmt;
}
public List<Meal> getMeals() {
return meals;
}
}
- 新建 厨师 类和 收银员 类
package com.black.design.pattern.command.order;
import java.util.List;
// 厨师
public class Cook{
// 订单
private Order o;
public Cook(Order o ) {
this.o = o;
}
public void cook() {
System.out.println("厨师做饭开始...");
List<Meal> meals = o.getMeals();
for (Meal meal: meals) {
System.out.println(meal.getName() +"做好了,一共" +meal.getAmt()+"份" );
}
System.out.println("厨师做饭结束。");
}
}
package com.black.design.pattern.command.order;
// 收银员
public class Cashier{
// 订单
private Order o;
public Cashier(Order o ) {
this.o = o;
}
public void checkOut() {
System.out.println("收银员开始结账...");
System.out.println("一共应收取"+o.getTotalAmt()+"元");
System.out.println("已结账...");
}
}
- 创建命令接口类和【下单】【结账】命令类
package com.black.design.pattern.command.order;
// 命令接口类
public interface ICommand {
//执行命令
public void execute();
}
package com.black.design.pattern.command.order;
import com.black.design.pattern.command.order.ICommand;
// 下单命令
public class PlaceOrderCommand implements ICommand {
// 厨师
private Cook cook;
public PlaceOrderCommand(Cook cook) {
this.cook = cook;
}
public void execute() {
// 开始做饭
cook.cook();
}
}
package com.black.design.pattern.command.order;
import com.black.design.pattern.command.order.ICommand;
// 结账命令
public class CheckOutCommand implements ICommand {
// 收银员
private Cashier cashier;
public CheckOutCommand(Cashier cashier) {
this.cashier = cashier;
}
public void execute() {
// 结账
cashier.checkOut();
}
}
- 创建服务员类,用于执行命令
package com.black.design.pattern.command.order;
import java.util.List;
import com.black.design.pattern.command.order.ICommand;
// 服务员
public class Waiter {
private List<ICommand> commands;
public void setCommands(List<ICommand> cds) {
this.commands = cds;
}
// 执行命令
public void executeCommands() {
for (ICommand command : commands) {
command.execute();
}
}
}
- 测试
package com.black.design.pattern.command.order;
import java.util.ArrayList;
import java.util.List;
public class Clinet {
public static void main(String[] args) {
// 去饭馆吃饭,开始点菜
System.out.println("=====================");
System.out.println(" 进饭馆吃饭");
System.out.println("=====================");
System.out.println("进饭馆,叫来了一个服务员");
Waiter waiter = new Waiter();
Meal chaoJiDan = new Meal("炒鸡蛋",12.00,1);
Meal feiniuFan = new Meal("肥牛盖饭",18.00,1);
Meal liufeichang = new Meal("溜肥肠",48.00,1);
Meal mapodoufu = new Meal("麻婆豆腐",24.00,1);
System.out.println("点了一份炒鸡蛋");
System.out.println("点了一份肥牛盖饭");
System.out.println("点了一份溜肥肠");
System.out.println("点了一份麻婆豆腐");
Order order = new Order();
order.addMeal(chaoJiDan);
order.addMeal(feiniuFan);
order.addMeal(liufeichang);
order.addMeal(mapodoufu);
// 下单
Cook cook = new Cook(order);
ICommand placeOrder = new PlaceOrderCommand(cook);
List<ICommand> commands = new ArrayList<ICommand>();
commands.add(placeOrder);
waiter.setCommands(commands);
System.out.println("点好了,让服务员去下单");
System.out.println("服务员去下单了...");
waiter.executeCommands();
System.out.println("=====================");
System.out.println(" 吃饭中...");
System.out.println("=====================");
System.out.println("吃完了,叫服务员过来结账");
// 结账
Cashier cashier = new Cashier(order);
ICommand checkout = new CheckOutCommand(cashier);
List<ICommand> commands2 = new ArrayList<ICommand>();
commands2.add(checkout);
waiter.setCommands(commands2);
waiter.executeCommands();
System.out.println("=====================");
System.out.println(" 离开饭馆");
System.out.println("=====================");
}
}
结果:
=====================
进饭馆吃饭
=====================
进饭馆,叫来了一个服务员
点了一份炒鸡蛋
点了一份肥牛盖饭
点了一份溜肥肠
点了一份麻婆豆腐
点好了,让服务员去下单
服务员去下单了...
厨师做饭开始...
炒鸡蛋做好了,一共1份
肥牛盖饭做好了,一共1份
溜肥肠做好了,一共1份
麻婆豆腐做好了,一共1份
厨师做饭结束。
=====================
吃饭中...
=====================
吃完了,叫服务员过来结账
收银员开始结账...
一共应收取102.0元
已结账...
=====================
离开饭馆
=====================