CODESAMPLE
Command - C
The Command pattern encapsulates a request as an object, allowing for parameterization of clients with different requests, queuing or logging of requests, and support for undoable operations. This implementation defines a base command struct with an execute function pointer. Concrete commands implement this interface to perform specific actions on a receiver object. An invoker holds and executes commands. This approach is idiomatic C as it leverages function pointers to achieve polymorphism and avoids complex object hierarchies, keeping the code lightweight and efficient.
#include <stdio.h>
#include <stdlib.h>
// Receiver
typedef struct {
int value;
} Receiver;
void receiver_set_value(Receiver *receiver, int value) {
receiver->value = value;
}
int receiver_get_value(const Receiver *receiver) {
return receiver->value;
}
// Command
typedef struct {
Receiver *receiver;
void (*execute)(const struct Command*);
} Command;
// Concrete Commands
void command_set_a(const Command *command) {
receiver_set_value(command->receiver, 10);
}
void command_set_b(const Command *command) {
receiver_set_value(command->receiver, 20);
}
// Invoker
typedef struct {
Command *command;
} Invoker;
void invoker_set_command(Invoker *invoker, Command *command) {
invoker->command = command;
}
void invoker_execute_command(Invoker *invoker) {
if (invoker->command != NULL) {
invoker->command->execute(invoker->command);
}
}
int main() {
Receiver receiver = {0};
Invoker invoker;
Command set_a_command = {&receiver, command_set_a};
Command set_b_command = {&receiver, command_set_b};
invoker_set_command(&invoker, &set_a_command);
invoker_execute_command(&invoker);
printf("Value after set A: %d\n", receiver_get_value(&receiver));
invoker_set_command(&invoker, &set_b_command);
invoker_execute_command(&invoker);
printf("Value after set B: %d\n", receiver_get_value(&receiver));
return 0;
}