设计模式专题之C语言-命令模式

1.简介

命令模式(Command Pattern)是一种行为型设计模式,它将请求封装为一个对象,从而使你能够参数化方法调用。这种模式允许我们解耦发送者和接收者,使得系统更加灵活,易于扩展。

2.通俗讲解

想象一下你在使用电视遥控器。当你按下遥控器上的按钮时,实际上并没有直接控制电视,而是向遥控器发出一个命令,然后遥控器通过这个命令告诉电视做什么。这里,遥控器就像是命令模式中的“调用者”,而电视则是执行具体操作的“接收者”。

3.实战

  1. 定义命令接口:创建一个抽象基类或结构体,定义所有命令都应该有的方法。
  2. 创建具体的命令类:这些类继承或包含命令接口,并实现具体的操作。
  3. 实现接收者:定义执行实际工作的对象。
  4. 创建调用者:通常是一个对象,用来存储并执行命令。

3.1.代码

#include <stdio.h>
#include <stdlib.h>

// 定义命令接口
typedef struct Command {
    void (*execute)(void);
} Command;

// 接收者 - 电视
typedef struct TV {
    int isOn;
} TV;

// 打开电视
void turnOn(TV *tv) {
    tv->isOn = 1;
    printf("TV is turned ON.\n");
}

// 关闭电视
void turnOff(TV *tv) {
    tv->isOn = 0;
    printf("TV is turned OFF.\n");
}

// 具体命令 - 打开电视命令
typedef struct TurnOnCommand {
    Command base;
    TV *tv;
} TurnOnCommand;

TurnOnCommand* createTurnOnCommand(TV *tv) {
    TurnOnCommand *command = (TurnOnCommand*)malloc(sizeof(TurnOnCommand));
    command->base.execute = (void (*)(void))turnOn;
    command->tv = tv;
    return command;
}

// 具体命令 - 关闭电视命令
typedef struct TurnOffCommand {
    Command base;
    TV *tv;
} TurnOffCommand;

TurnOffCommand* createTurnOffCommand(TV *tv) {
    TurnOffCommand *command = (TurnOffCommand*)malloc(sizeof(TurnOffCommand));
    command->base.execute = (void (*)(void))turnOff;
    command->tv = tv;
    return command;
}

// 调用者 - 遥控器
typedef struct RemoteControl {
    Command *onCommand;
    Command *offCommand;
} RemoteControl;

RemoteControl* createRemoteControl() {
    RemoteControl *remote = (RemoteControl*)malloc(sizeof(RemoteControl));
    remote->onCommand = NULL;
    remote->offCommand = NULL;
    return remote;
}

void setCommand(RemoteControl *remote, Command *onCommand, Command *offCommand) {
    remote->onCommand = onCommand;
    remote->offCommand = offCommand;
}

int main() {
    TV *tv = (TV*)malloc(sizeof(TV));
    tv->isOn = 0;

    TurnOnCommand *turnOnCommand = createTurnOnCommand(tv);
    TurnOffCommand *turnOffCommand = createTurnOffCommand(tv);

    RemoteControl *remote = createRemoteControl();
    setCommand(remote, &turnOnCommand->base, &turnOffCommand->base);

    // 使用遥控器打开电视
    remote->onCommand->execute(tv);

    // 使用遥控器关闭电视
    remote->offCommand->execute(tv);

    free(turnOnCommand);
    free(turnOffCommand);
    free(remote);
    free(tv);

    return 0;
}

3.2.代码解析

  • 抽象命令接口 (Command): 这是一个简单的结构体,其中只有一个函数指针成员 execute。所有命令都需要实现这个函数指针所指向的函数。
  • 具体命令 (TurnOnCommandTurnOffCommand): 这些结构体包含了指向命令接口的指针,以及指向实际要操作的对象 (TV) 的指针。每个具体命令都实现了 execute 函数,该函数根据需要调用接收者的相应方法。
  • 接收者 (TV): 这里定义了实际执行动作的对象,即电视。它有两个方法:turnOnturnOff,用于改变电视的状态。
  • 调用者 (RemoteControl): 这个结构体包含了指向具体命令的指针。它通过 setCommand 函数设置这些指针,然后通过调用 execute 方法来执行命令。

3.3.代码运行

TV is turned ON.
TV is turned OFF.

3.4.结果分析

  1. 当我们第一次按下遥控器的 “ON” 按钮时,电视被打开。
  2. 接着当我们按下 “OFF” 按钮时,电视被关闭。

分析

  1. 初始化阶段:
    • 创建了一个 TV 对象,初始状态为关闭 (isOn = 0)。
    • 创建了两个具体命令对象:TurnOnCommandTurnOffCommand,它们分别对应于打开和关闭电视的动作。
    • 创建了一个 RemoteControl 对象,并设置了其 onCommandoffCommand 成员变量,指向具体的命令对象。
  2. 执行阶段:
    • main 函数中,首先调用了 remote->onCommand->execute(tv),这将触发 turnOn 函数,从而改变 TV 对象的状态,使其从关闭变为打开。
    • 接下来,调用 remote->offCommand->execute(tv),触发 turnOff 函数,使 TV 对象的状态再次改变,这次是从打开变为关闭。
  3. 资源释放:
    • 最后,程序释放了分配给命令对象、遥控器对象以及电视对象的内存,以避免内存泄漏。

4.总结

  • 解耦: 发送者(遥控器)不需要知道接收者(电视)的实现细节。
  • 可扩展性: 可以轻松添加新的命令或修改现有命令的行为,而无需更改发送者或接收者的代码。
  • 灵活性: 支持撤销/重做等高级功能,只需稍作修改即可实现。
  • 10
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

甜航一直在

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值