行为型模式-命令模式
Posted 风流 少年
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了行为型模式-命令模式相关的知识,希望对你有一定的参考价值。
定义
将一个请求封装
为一个对象,使得发出请求的责任和执行请求的责任分割开。这样两者之间通过命令对象进行沟通,这样方便将命令对象进行存储、传递、调用、增加与管理。
当对象A中的方法需要调用对象B中的方法时我们可以直接在A方法中创建一个B对象,然后通过B对象来直接调用。方法调用我们一般都是这么写,但是这么写会使得A要强依赖于B,名利模式就是为了解耦A与B。
对象方法调用
@Data
public class Order
/** 餐桌号 */
private int diningTable;
/** 食物名和数量 */
private Map<String, Integer> foodDir = new HashMap<>();
public void putFood(String name, int num)
foodDir.put(name, num);
/** 厨师 */
public class Chef
public void makeFood(String foodName, int num)
System.out.println("制作食物:" + foodName + ", 份数:" + num);
/**
* 服务员点餐
*/
public class Waiter
public void orderFood(Order order)
// 1.创建厨师对象
Chef chef = new Chef();
order.getFoodDir().forEach((foodName, num) ->
// 2.调用厨师中的制作食物方法
chef.makeFood(foodName, num);
);
public class Test
public static void main(String[] args)
Order order = new Order();
order.setDiningTable(1);
order.putFood("鸡蛋面", 1);
order.putFood("可乐", 2);
Waiter waiter = new Waiter();
waiter.orderFood(order);
方法的调用说破天也是通过对象.方法(实参);
这种方式调用的,如chef.makeFood(foodName, num)
。
而命令模式最终也将会使用对象.方法(实参);
这种方式来调用,只不过,命令模式会先将 对象
、参数
封装成一个对象(Command),然后将这个对象放到List先暂存起来,等需要的时候再执行对象.方法(实参);
。
命令模式只是将方法的调用预先暂存起来(调用的对象和方法的实参还是要预先准备好的),等到需要执行的时候再执行而不是立即执行。
案例
餐馆下单案例:
- 顾客把订单交给服务员
- 服务员将订单交给厨师
- 厨师根据订单准备餐点
// 抽象命令角色
public interface Command
void execute();
/**
* 具体命令:封装调用者和方法参数列表,实现Command中的execute()来最后调用对象的真正方法
*/
public class OrderCommand implements Command
/** 方法调用对象 */
private Chef chef;
/** 方法参数 */
private Order order;
public OrderCommand(Chef chef, Order order)
this.chef = chef;
this.order = order;
/**
* 调用对象的指定的方法
*/
@Override
public void execute()
order.getFoodDir().forEach((foodName, num) ->
chef.makeFood(foodName, num);
);
服务员:不再直接调用厨师对应的方法,而是暂缓客户端传递过来的命令对象,然后统一执行命令中的方法。
/**
* 服务员(请求者角色)
*/
public class Waitor
private List<Command> commands = new ArrayList<>();
public void setCommand(Command command)
commands.add(command);
public void orderUp()
System.out.println("服务员:大厨,来订单啦");
for (Command command : commands)
if (command != null)
command.execute();
public class Client
public static void main(String[] args)
// 对象
Chef chef = new Chef();
// 方法实参
Order order = new Order();
order.setDiningTable(1);
order.putFood("鸡蛋面", 1);
order.putFood("可乐", 2);
// 封装调用对象和实参
OrderCommand cmd = new OrderCommand(chef, order);
// 暂缓命令,并执行命令列表
Waitor waitor = new Waitor();
waitor.setCommand(cmd);
waitor.orderUp();
对象方法的调用本来一句话就能解决的事对象.方法(实参);
,为啥要活生生的拆的骨肉分离呢?为了解耦感觉已经走🔥入魔了。
优缺点
优点:
- 降低系统的耦合度。命令模式能将调用操作的对象与实现该操作的对象解耦。
- 增加或删除命令非常方便。采用名利模式增加与删除名利不会影响其它类。它满足开闭原则,对扩展比较灵活。
- 可以实现宏命令。命令模式可以与组合模式结合,将多个命令装配成一个组合命令,即宏命令。
- 方便实现undo和redo操作。
缺点:
- 使用名利模式可能会造成某些系统有过多的具体命令类。
- 系统结构更加复杂。
使用场景
- 系统需要将请求调用者和请求接收者解耦,使得调用者和接收者不直接交互。
- 系统需要在不同时间指定请求、将请求排队和执行请求。
- 系统需要支持命令的撤销(Undo)和恢复(Redo)操作。
JDK源码中的运用
// 抽象命令角色
public interface Runnable
public abstract void run();
// 具体命令
public class Thread implements Runnable
private Runnable target;
public synchronized void start()
start0();
private native void start0();
以上是关于行为型模式-命令模式的主要内容,如果未能解决你的问题,请参考以下文章