• 设计模式(19)命令模式


    一、介绍:

    1、定义:命令模式(Command Pattern)是一种行为设计模式,它将请求封装为一个对象,从而使你可以使用不同的请求对客户端进行参数化。命令模式还支持请求的排队、记录日志、撤销操作等功能。

    2、组成结构:

    (1)命令接口(Command):定义执行命令的方法,可以是抽象类或接口。

    1. public interface Command {
    2. void execute();
    3. }

    (2)具体命令类(Concrete Command):实现命令接口,封装了具体的请求和接收者,负责执行请求。

    1. /**
    2. * 具体的命令实现
    3. */
    4. public class ConcreteCommand implements Command {
    5. /**
    6. * 持有相应的接收者对象
    7. */
    8. private Receiver receiver = null;
    9. /**
    10. * 构造方法,传入相应的接收者对象
    11. *
    12. * @param receiver 相应的接收者对象
    13. */
    14. public ConcreteCommand(Receiver receiver) {
    15. this.receiver = receiver;
    16. }
    17. /**
    18. * 执行命令
    19. */
    20. @Override
    21. public void execute() {
    22. // 通常会转调接收者对象的相应方法,让接收者来真正执行功能
    23. receiver.action();
    24. }
    25. }

    (3)接收者类(Receiver):命令接受者对象,定义了命令接受者可以做的事情。执行实际的操作,命令对象将请求委托给接收者来执行。

    1. public class Receiver {
    2. public void action() {
    3. System.out.println("执行具体操作");
    4. }
    5. }

    (4)调用者类(Invoker):Invoker类是具体命令的接收者,用于接收客户的所有命令,然后将命令转达给执行者,执行这些命令。

    1. public class Invoker {
    2. private Command command;
    3. public void setCommand(Command command) {
    4. this.command = command;
    5. }
    6. public void executeCommand() {
    7. command.execute();
    8. }
    9. }

    客户端(Client):创建具体的命令对象,并将其分配给调用者来执行。

    1. public class Client {
    2. public static void main(String[] args) {
    3. // 创建接收者
    4. Receiver receiver = new Receiver();
    5. // 创建命令对象,设定它的接收者
    6. Command command = new ConcreteCommand(receiver);
    7. // 创建调用者,把命令对象设置进去
    8. Invoker invoker = new Invoker();
    9. invoker.setCommand(command);
    10. // 调用者调用命令
    11. invoker.executeCommand();
    12. }
    13. }

    3、优点

    • 能够比较容易的设计一个命令队列
    • 在需要的情况下,可以比较容易地将命令记入日志
    • 允许接收请求的一方决定是否要解决请求
    • 可以容易的实现对请求的撤销和重做
    • 容易扩展新的命令类
    • 能够把请求一个操作的对象,与知道怎么执行一个操作的对象分隔开

    二、demo:

    1、点餐:服务员充当命令委托角色,在顾客和厨师之间松耦合

    (1)命令:

    1. //顾客抽象命令
    2. public abstract class Command {
    3. public Integer count;
    4. public Integer getCount() {
    5. return count;
    6. }
    7. public void setCount(Integer count) {
    8. this.count = count;
    9. }
    10. protected Cook receiver;
    11. public Command(Cook receiver,int count) {
    12. this.receiver = receiver;
    13. this.count = count;
    14. }
    15. public abstract void execute();
    16. }
    17. //具体命令1
    18. public class BakeBeefCommand extends Command {
    19. public BakeBeefCommand(Cook receiver,int count) {
    20. super(receiver,count);
    21. }
    22. @Override
    23. public void execute() {
    24. receiver.bakeBeef();
    25. }
    26. }
    27. //具体命令2
    28. public class BakeMuttonCommand extends Command{
    29. public BakeMuttonCommand(Cook receiver,int count) {
    30. super(receiver,count);
    31. }
    32. @Override
    33. public void execute() {
    34. receiver.bakeMutton();
    35. }
    36. }

    (2)命令实际接收者 厨师

    1. public class Cook {
    2. public void bakeMutton(){
    3. System.out.println("烤羊肉");
    4. }
    5. public void bakeBeef(){
    6. System.out.println("烤牛肉");
    7. }
    8. }

    (3)命令中转 服务员

    1. public class Waiter {
    2. private List orders= new ArrayList<>();
    3. public void setOrder(Command command) {
    4. if(command.getCount() < 5){
    5. System.err.println("点餐失败,一份数量最小为5,count="+command.getCount());
    6. }else{
    7. System.out.println("点餐成功,记录日志,count="+command.getCount());
    8. this.orders.add(command);
    9. }
    10. }
    11. public void cancleOrder(Command command) {
    12. System.out.println("取消成功,记录日志,count="+command.getCount());
    13. this.orders.remove(command);
    14. }
    15. public void executeCommand(){
    16. System.out.println("***点餐结束***");
    17. for (Command comm : orders) {
    18. comm.execute();
    19. }
    20. }
    21. }

    客户端

    1. public static void main(String[] args) {
    2. Cook receiver = new Cook();
    3. Waiter waiter = new Waiter();
    4. Command muttonCommand = new BakeMuttonCommand(receiver,1);
    5. waiter.setOrder(muttonCommand);
    6. muttonCommand = new BakeMuttonCommand(receiver,5);
    7. waiter.setOrder(muttonCommand);
    8. Command beefCommand = new BakeBeefCommand(receiver,6);
    9. waiter.setOrder(beefCommand);
    10. beefCommand = new BakeBeefCommand(receiver,7);
    11. waiter.setOrder(beefCommand);
    12. //临时取消
    13. waiter.cancleOrder(beefCommand);
    14. //全部点餐结束后执行
    15. waiter.executeCommand();
    16. }
    17. 输出:
    18. 点餐失败,一份数量最小为5count=1
    19. 点餐成功,记录日志,count=5
    20. 点餐成功,记录日志,count=6
    21. 点餐成功,记录日志,count=7
    22. 取消成功,记录日志,count=7
    23. ***点餐结束***
    24. 烤羊肉
    25. 烤牛肉
  • 相关阅读:
    1012 The Best Rank
    TIJ14_类型信息
    2022-08-04 clickhouse的join子句
    千兆以太网——MDIO接口协议
    首尔伟傲世将在2022年IFA展会上展示其微型LED的非凡价值
    变电站远程维护解决方案,工程师从此不再“跑断腿“
    Python 正则表达式
    Spring的注解开发-依赖注入相关注解
    英伟达发布526.98 WHQL 显卡驱动,支持RTX 4080,三款即将上线游戏
    【css | linear-gradient】linear-gradient()的用法
  • 原文地址:https://blog.csdn.net/w_t_y_y/article/details/134074888