09-命令者模式-C语言实现

命令者模式是一个高内聚的模式, 其定义为: Encapsulate a request as an object,thereby letting you parameterize clients with different requests,queue or log requests,and support undoable operations.(将一个请求封装成一个对象, 从而让你使用不同的请求把客户端参数化, 对请求排队或者记录请求日志, 可以提供命令的撤销和恢复功能。 )

UML图:

代码实现:

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

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

// 具体命令类
typedef struct {
    Command command;
    void* receiver;
    void (*action)(void*);
    void (*undoAction)(void*);
} ConcreteCommand;

void ConcreteCommand_execute(void* obj) {
    ConcreteCommand* self = (ConcreteCommand*)obj;
    self->action(self->receiver);
}

void ConcreteCommand_undo(void* obj) {
    ConcreteCommand* self = (ConcreteCommand*)obj;
    self->undoAction(self->receiver);
}

ConcreteCommand createConcreteCommand(void* receiver, void (*action)(void*), void (*undoAction)(void*)) {
    ConcreteCommand command;
    command.command.execute = ConcreteCommand_execute;
    command.command.undo = ConcreteCommand_undo;
    command.receiver = receiver;
    command.action = action;
    command.undoAction = undoAction;
    return command;
}

// 调用者类
typedef struct {
    Command* command;
    void (*setCommand)(void*, Command*);
    void (*executeCommand)(void*);
    void (*undoCommand)(void*);
} Invoker;

void Invoker_setCommand(void* obj, Command* command) {
    Invoker* self = (Invoker*)obj;
    self->command = command;
}

void Invoker_executeCommand(void* obj) {
    Invoker* self = (Invoker*)obj;
    self->command->execute(self->command);
}

void Invoker_undoCommand(void* obj) {
    Invoker* self = (Invoker*)obj;
    self->command->undo(self->command);
}

Invoker createInvoker() {
    Invoker invoker;
    invoker.setCommand = Invoker_setCommand;
    invoker.executeCommand = Invoker_executeCommand;
    invoker.undoCommand = Invoker_undoCommand;
    return invoker;
}

// 接收者类
typedef struct {
    void (*action)(void*);
    void (*undoAction)(void*);
} Receiver;

void Receiver_action(void* obj) {
    printf("Receiver performs action.\n");
}

void Receiver_undoAction(void* obj) {
    printf("Receiver undoes action.\n");
}

Receiver createReceiver() {
    Receiver receiver;
    receiver.action = Receiver_action;
    receiver.undoAction = Receiver_undoAction;
    return receiver;
}

int main() {
    Receiver receiver = createReceiver();
    ConcreteCommand command = createConcreteCommand(&receiver, &receiver.action, &receiver.undoAction);
    Invoker invoker = createInvoker();

    invoker.setCommand(&invoker, &command);
    invoker.executeCommand(&invoker);
    invoker.undoCommand(&invoker);

    return 0;
}

在上面的示例代码中,定义了命令接口Command和具体命令类ConcreteCommand,实现了执行和撤销方法来处理具体的命令。

同时还定义了调用者类Invoker,具有设置命令、执行命令和撤销命令的方法,并通过命令对象来调用相应的方法。

还定义了接收者类Receiver,具有执行操作和撤销操作的方法。

main函数中,首先创建了一个接收者对象receiver,然后创建了一个具体命令对象command,并将接收者对象和相应的操作方法传入。

接着创建了一个调用者对象invoker,通过调用者对象设置命令对象,并执行和撤销命令。

命令模式的优点:

  1. 可以将请求发送者与接收者解耦,使得请求发送者不需要知道具体的接收者和处理方法。

  2. 可以实现请求的参数化、队列化和记录日志等功能。

  3. 支持可撤销操作,可以随时撤销执行过的命令。

命令模式的缺点:

  1. 可能导致命令类的数量增加,因为每个具体命令都需要实现一个命令类。

  2. 可能引入额外的开销,因为需要维护命令对象和命令队列。

适用场景:

  1. 需要将请求发送者和接收者解耦的场景。

  2. 需要支持请求的参数化、队列化和记录日志等功能的场景。

  3. 需要支持可撤销操作的场景。

总结:命令模式通过将请求封装成对象来实现请求的参数化、队列化和记录日志等功能,并且支持可撤销操作。它可以降低系统的耦合度,提高系统的灵活性和可维护性。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值