首页 > 其他分享 >命令模式(Command Pattern)

命令模式(Command Pattern)

时间:2023-05-22 17:56:23浏览次数:33  
标签:请求 Pattern 接收者 模式 发送者 命令 Command public

一、模式动机

命令模式(Command Pattern)是一种常用的行为型设计模式,它将请求发送者与请求接收者解耦,请求发送者通过命令对象来间接引用接收者,使得系统具有更好的灵活性,可以在不修改现有系统源代码的情况下将相同的发送者对应不同的接收者,也可以将多个命令对象组合成宏命令,还可以在命令类中提供用来撤销请求的方法。
命令模式又称为“动作(Action)模式”或者“事务(Transaction)模式”,是对象行为型模式之一。

  • 现实生活
    • 相同的开关可以通过不同的电线来控制不同的电器
    • 开关 类比 请求发送者
    • 电灯 类比 请求的最终接收者和处理者
    • 开关和电灯之间并不存在直接耦合关系,它们通过电线连接在一起,使用不同的电线可以连接不同的请求接收者
  • 软件开发
    • 按钮 相当于 请求发送者
    • 事件处理类 相当于 请求的最终接收者和处理者
    • 发送者与接收者之间引入了新的命令对象(类似电线),将发送者的请求封装在命令对象中,再通过命令对象来调用接收者的方法
    • 相同的按钮可以对应不同的事件处理类
    • 将请求发送者和接收者完全解耦
    • 发送者与接收者之间没有直接引用关系
    • 发送请求的对象只需要知道如何发送请求,而不必知道如何完成请求

二、模式定义

  • 命令模式(Command Pattern):将一个请求封装为一个对象,从而使我们可用不同的请求对客户进行参数化;对请求排队或者记录请求日志,以及支持可撤销的操作
  • 命令模式是一种对象行为型模式,其别名为动作(Action)模式或事务(Transaction)模式
    • “用不同的请求对客户进行参数化”
    • “对请求排队”
    • “记录请求日志”
    • “支持可撤销操作”

三、模式结构

image

四、案例实现

案例背景

电视机遥控器

案例结构

image

代码实现

电视机类

public class Television {

    public void open(){
        System.out.println("打开电视");
    }
    public void close(){
        System.out.println("关闭");
    }
    public void change(){
        System.out.println("换台");
    }

}

抽象命令类

public interface Command {

    void excute();

}

打开命令

public class OpenCommand implements Command{

    private Television t;

    public OpenCommand(){
        t = new Television();
    }

    @Override
    public void excute() {
        t.open();
    }
}

关闭命令

public class CloseCommand implements Command{

    private Television t;

    public CloseCommand() {
        t = new Television();
    }

    @Override
    public void excute() {
        t.close();
    }
}

换台命令

public class ChangeCommand implements Command{

    private Television t;

    public ChangeCommand() {
        t = new Television();
    }

    @Override
    public void excute() {
        t.change();
    }
}

电视机遥控器

public class Controller {

    private Command openCommand,closeCommand,changeCommand;

    public Controller(Command openCommand, Command closeCommand, Command changeCommand) {
        this.openCommand = openCommand;
        this.closeCommand = closeCommand;
        this.changeCommand = changeCommand;
    }

    public void open(){
        openCommand.excute();
    }

    public void close(){
        closeCommand.excute();
    }
    public void change(){
        changeCommand.excute();
    }
}

客户类

public class Client {

    public static void main(String[] args) {
        Command openCommand,closeCommand,changeCommand;
        openCommand = new OpenCommand();
        closeCommand = new CloseCommand();
        changeCommand = new ChangeCommand();
        Controller controller = new Controller(openCommand,closeCommand,changeCommand);
        controller.open();
        controller.close();
        controller.change();
    }

}

案例结果

image

案例分析

调用者与抽象命令相关联,在程序运行时注入具体命令类对象,在Controller的业务方法中调用命令类的excute(),不同命令类的excute()不同,可以调用请求接受者的不同请求响应方法。
每一个具体命令类对应一个请求的处理者(接收者),通过向请求发送者注入不同的具体命令对象可以使相同的发送者对应不同的接收者,从而实现“将一个请求封装为一个对象,用不同的请求对客户进行参数化”,客户端只需要将具体命令对象作为参数注入请求发送者,无须直接操作请求的接收者

五、模式分析

  • 命令模式的本质是对请求进行封装
  • 将请求发送者和接收者完全解耦
  • 使得请求的一方不必知道接收请求的一方的接口,更不必知道请求如何被接收、操作是否被执行、何时被执行,以及是怎么被执行的。
  • 发送请求的对象只需要知道如何发送请求,而不必知道如何完成请求
  • 命令模式的本质是对请求进行封装
  • 一个请求对应于一个命令,将发出命令的责任和执行命令的责任分开

六、总结

模式优点

  • 降低系统的耦合度
  • 新的命令可以很容易地加入到系统中,符合开闭原则
  • 可以比较容易地设计一个命令队列或宏命令(组合命令)
  • 为请求的撤销(Undo)和恢复(Redo)操作提供了一种设计和实现方案

模式缺点

  • 使用命令模式可能会导致某些系统有过多的具体命令类(针对每一个对请求接收者的调用操作都需要设计一个具体命令类)

使用情形

  • 需要将请求调用者和请求接收者解耦,使得调用者和接收者不直接交互
  • 需要在不同的时间指定请求、将请求排队和执行请求
  • 需要支持命令的撤销(Undo)操作和恢复(Redo)操作
  • 需要将一组操作组合在一起形成宏命令

标签:请求,Pattern,接收者,模式,发送者,命令,Command,public
From: https://www.cnblogs.com/sorrymine/p/17421300.html

相关文章

  • 读书笔记 软件需求模式
    前面了解到什么事需求的,接下来就应该学习如何使用和编写需求模式。我们不仅到了解需求模式的含义,更要学会在什么情况下使用需求模式。在定义系统期间,有两种场合使用需求模式:1.当定义需求时,看是否存在一个模式可以指导如何定义这种需求。2.当考虑系统需求是否完全时,浏览主题覆盖......
  • AIGC持续火爆大模型争相推出,庞大市场造就算力供应模式演变
    本图由AI生成  黄仁勋说的AI发展迎来iPhone时刻,对NVIDIA有什么影响?文/王吉伟 近期的AIGC领域仍旧火爆异常。但火的不只是AIGC应用,还有巨头之间的AI竞赛,以及接连不断上新的AI大模型(LLM,LargeLanguageModel)。面对ChatGPT带来的技术冲击,为了研发谷歌多模态AI模型及应对......
  • 行为型模式(Behavioer Pattern)
    行为型设计模式行为型模式定义了系统中对象之间的交互与通信,研究系统在运行时对象之间的相互通信与协作,进一步明确对象的职责,包括对系统中较为复杂的流程的控制。在软件系统运行时对象并不是孤立存在的,它们可以通过相互通信和协作完成某些功能,一个对象在运行时也将影响其他对象......
  • 代理模式(Proxy Pattern)
    一、模式动机通过引入一个新的对象(如小图片和远程代理对象)来实现对真实对象的操作,或者将新的对象作为真实对象的一个替身引入代理对象来间接访问一个对象二、模式定义给某一个对象提供一个代理,并由代理对象控制对原对象的引用对象结构型模式代理对象可以在客户端和目标对......
  • 外观模式(Facade Pattern)
    一、模式动机外观模式(FacadePattern)是一种使用频率非常高的设计模式,它通过引入一个外观角色来简化客户端和子系统之间的操作,为复杂的子系统调用提供一个统一的入口,使子系统与客户端的耦合度降低,且客户端调用非常方便。外观模式中,外部与一个子系统的通信可以通过一个统一的外观......
  • 策略模式的实际应用
    publicinterfaceTransactionDetailProcessor{/***判断是否策略包含内容**@paramstrategy*@return*/booleanfitStrategy(QueryOrderDetailStrategystrategy);voidprocess(OperationContextcontext,TransactionDetailV......
  • 如何打破996模式下的成长魔咒?
    如何打破996模式下的成长魔咒?996相信是国内互联网的标配了,标配到是一个默认的道德约定了。道德约定有多可怕相信很多人都知道,那是比法律稍微低一点的人性约束。996下的无奈如果你不996,你可能无法找到互联网的工作。如果你不996,你可能在互联网公司里无法长期立足。如果你不996,哪怕......
  • pod 插件报错: LoadError - cannot load such file -- cocoapods/command/gen
    报错信息:LoadError-cannotloadsuchfile–cocoapods/command/gen解决方法:geminstallcocoapods-generate......
  • Android利用activity启动模式退出整个应用
    前面我们来先看一下目前网上提供的几种方案:1.退出单个activity1)、获取当前进程的id,杀死该进程。android.os.Process.killProcess(android.os.Process.myPid())2)、终止当前正在运行的Java虚拟机方法。System.exit(0); 3)、finish();4)、杀包方式。......
  • Intel公布全新架构x86S!纯64位模式运行:指令集大幅精简
    在iOS生态中,苹果已经完全淘汰了32位,安卓领域也在加速,设计APP、操作系统、处理器等多方面。而对于PC电脑而言,Intel似乎要“大动干戈”了。Intel已经提出一种全新架构名为x86S,即x86-64ISA简化版,其独特的地方在于纯64bit模式运行的设计。当然,别担心,在技术白皮书中,Intel表示,纯64......