Command pattern is for encapsulating commands in objects. But why not use function pointers instead? Why do I need to subclass Command for each operation? Instead I can have different functions and call the function pointers.
But why not use function pointers instead.
Because function pointers can't store arbitrary state. You'll often want the command to be parametrised when you create it. For example:
struct command {
virtual ~command() {}
virtual void do_it() = 0;
};
struct say_something : command {
// store a message to print later
say_something(std::string message) : message(message) {}
// print the stored message
void do_it() override {std::cout << message << '\n';}
std::string message;
};
std::unique_ptr<command> say_hello(new say_something("Hello!"));
// later
say_hello->do_it(); // prints stored string
If you were to use a plain function pointer, then you'd need a different function for everything you might want to print.
Why I need to subclass Command class for each operation?
Because that's how old-school OOP works; although as mentioned above, you can use the fact that it's an object to parametrise it rather than subclass it.
Luckily, modern C++ has better facilities:
typedef std::function<void()> command;
// print a static string
command say_hello = []{std::cout << "Hello!\n";};
// store a string to print later
std::string goodbye = "Goodbye!";
command say_goodbye = [goodbye]{std::cout << goodbye << '\n';};
// later
say_hello(); // prints static string
say_goodbye(); // prints string stored in the command
Command pattern is much more than just executing a function. It encapsulates data and logic inside a class and provides an object that could easily be passed as a parameter. Besides executing tasks, it could also fire events, parse and clean up data and much more, and that's where inheritance and template methods come handy, which you won't get using function pointers. Also, implementing undo and redo is very easy using commands.
© 2022 - 2024 — McMap. All rights reserved.