命令模式(行为型)

目录

一、前言

二、命令模式

三、总结


一、前言

命令模式(Command Pattern)是一种行为型设计模式,命令模式将一个请求封装为一个对象,从而可以用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。

命令模式由以下角色组成:

Command(命令):

该角色定义了执行操作的接口。通常包含一个执行操作的方法,如 execute()。命令对象可能会携带执行操作所需的参数。

Concrete Command(具体命令):

该角色实现了命令接口,对具体的操作进行了实现。具体命令对象将一个接收者对象绑定到一个动作,并负责调用接收者的相应方法来执行请求。

Receiver(接收者):

该角色实际执行操作的对象。命令对象会将请求委托给接收者来执行实际的操作。

Invoker/Client(调用者/客户端):

该角色创建命令对象并将其发送给接收者。调用者不需要了解命令是如何执行的,它只需要发送请求。

整个命令模式的结构图:

二、命令模式

比如在餐馆就餐,我们会先向服务员点单,下单后服务员通知后厨进行制作,这种就可以用命令模式进行演示。Receiver可以当做是具体制作食物的厨师,Invoker可以当做是服务员进行调用,Command理解成每一个菜单,也就是发出的命令。

先创建厨师Receiver类:

java 复制代码
public class Receiver {

    public void actionOne(){
        System.out.println("制作食物one");
    }

    public void actionTwo(){
        System.out.println("制作食物two");
    }

    public void actionThree(){
        System.out.println("制作食物three");
    }
}

创建抽象命令Command:

java 复制代码
public interface Command {
    void execute();
}

创建菜单具体的命令:

java 复制代码
public class ConcreteCommandOne implements Command{

    private Receiver receiver;

    public ConcreteCommandOne(Receiver receiver) {
        this.receiver = receiver;
    }

    @Override
    public void execute() {
        receiver.actionOne();
    }
}


public class ConcreteCommandTwo  implements Command{
    private Receiver receiver;

    public ConcreteCommandTwo(Receiver receiver) {
        this.receiver = receiver;
    }

    @Override
    public void execute() {
        receiver.actionTwo();
    }
}

public class ConcreteCommandThree  implements Command{
    private Receiver receiver;

    public ConcreteCommandThree(Receiver receiver) {
        this.receiver = receiver;
    }

    @Override
    public void execute() {
        receiver.actionThree();
    }
}

创建服务员Invoker类:

java 复制代码
public class Invoker {

    private List<Command> commands = new ArrayList<>();

   public void setCommand(Command command){
       commands.add(command);
   }

   public void removeCommand(Command command){
       commands.remove(command);
       System.err.println("取消订单");
   }

    public void call(){
       for (Command command : commands){
           command.execute();

       }
    }
}

客户端调用类:

java 复制代码
public class Client {

    public static void main(String[] args) {
        Receiver receiver = new Receiver();

        Command commandOne = new ConcreteCommandOne(receiver);
        Command commandTwo = new ConcreteCommandTwo(receiver);
        Command commandThree = new ConcreteCommandThree(receiver);

        Invoker invoker = new Invoker();

        invoker.setCommand(commandOne);
        invoker.setCommand(commandTwo);
        invoker.setCommand(commandThree);

        invoker.removeCommand(commandTwo);

        invoker.call();


    }
}

执行结果:

可以看出client创建不同的命令,通过invoker将命令设置进去,也可以通过invoker取消命令,最后invoker通知进行调用。

三、总结

优点与缺点:

优点:

解耦请求发送者和接收者:

命名模式将请求封装成一个对象,使得发送者和接收者之间的解耦程度增加。发送者只需要知道如何发送命令,而不需要了解命令是如何被执行的。

支持撤销和重做操作:

由于命令对象封装了对接收者的调用,因此可以轻松地实现撤销和重做操作,只需保留历史命令对象即可。

增加新的命令:

通过添加新的命令类,可以轻松地扩展命令模式,而无需修改现有的客户端代码。

支持组合命令:

可以通过组合多个命令对象来执行复杂的操作,从而实现更高级的功能。

缺点:

类爆炸:

在系统中可能会产生大量的具体命令类,如果命令种类过多,可能会导致类爆炸,增加系统的复杂性。

增加调试难度:

由于命令模式涉及多个对象之间的交互,因此调试可能会变得更加复杂。

应用场景:

GUI应用程序:

命令模式常用于实现菜单和工具栏按钮的操作。每个菜单项或按钮可以表示一个命令,当用户点击时,该命令将被执行。

任务队列:

命令模式可以用于实现任务队列,例如,在操作系统中,可以将用户的操作封装成命令对象,然后将它们放入队列中以便逐个执行。

日志系统:

命令模式可以用于实现日志系统,将所有操作封装成命令对象,并在执行时记录相关的日志信息。

撤销/重做功能:

命令模式很适合实现撤销和重做功能,因为每个命令对象都可以保存执行时的状态,从而支持撤销和重做操作。

相关推荐
程序员与背包客_CoderZ9 小时前
C++设计模式——Abstract Factory Pattern抽象工厂模式
c语言·开发语言·c++·设计模式·抽象工厂模式
zzzhpzhpzzz9 小时前
设计模式——组合实体模式
设计模式
zzzhpzhpzzz12 小时前
设计模式——前端控制器模式
设计模式
forestsea12 小时前
【Java 解释器模式】实现高扩展性的医学专家诊断规则引擎
java·人工智能·设计模式·解释器模式
小白不太白95015 小时前
设计模式之 命令模式
设计模式·命令模式
吃汉堡吃到饱15 小时前
【创建型设计模式】单例模式
单例模式·设计模式
小白不太白95015 小时前
设计模式之 备忘录模式
服务器·设计模式·备忘录模式
zzzhpzhpzzz15 小时前
设计模式——策略模式
设计模式·策略模式
入门到跑路15 小时前
【君正T31开发记录】8.了解rtsp协议及设计模式
网络协议·设计模式
小白不太白95015 小时前
设计模式之 解释器模式
java·设计模式·解释器模式