命令模式(行为型)

目录

一、前言

二、命令模式

三、总结


一、前言

命令模式(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应用程序:

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

任务队列:

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

日志系统:

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

撤销/重做功能:

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

相关推荐
wu~9707 小时前
手撕四种常用设计模式(工厂,策略,代理,单例)
java·单例模式·设计模式·代理模式·抽象工厂模式·策略模式
敲代码的 蜡笔小新14 小时前
【行为型之访问者模式】游戏开发实战——Unity灵活数据操作与跨系统交互的架构秘诀
unity·设计模式·c#·访问者模式
新手村领路人1 天前
qt5.14.2 opencv调用摄像头显示在label
qt·opencv·命令模式
软考真题app1 天前
软件设计师考试结构型设计模式考点全解析
设计模式·软件设计师·结构型设计模式·考试考点
xiaolin03331 天前
【设计模式】- 行为型模式1
设计模式·状态模式·责任链模式·策略模式·命令模式·模板方法模式·行为型模式
沐土Arvin1 天前
深入理解 requestIdleCallback:浏览器空闲时段的性能优化利器
开发语言·前端·javascript·设计模式·html
bao_lanlan1 天前
兰亭妙微:用系统化思维重构智能座舱 UI 体验
ui·设计模式·信息可视化·人机交互·交互·ux·外观模式
总是难免1 天前
设计模式 - 单例模式 - Tips
java·单例模式·设计模式
Java致死2 天前
设计模式Java
java·开发语言·设计模式
ghost1432 天前
C#学习第23天:面向对象设计模式
开发语言·学习·设计模式·c#