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.
Definition: The command pattern encapsulates a request as an object, thereby letting us parameterize other objects with different requests, queue or log requests, and support undoable operations.
Design Pattern based on Encapsulation in JavaMany design pattern in Java uses the encapsulation concept, one of them is Factory pattern which is used to create objects.
In object-oriented programming, the command pattern is a behavioral design pattern in which an object is used to encapsulate all information needed to perform an action or trigger an event at a later time. This information includes the method name, the object that owns the method and values for the method parameters.
A Command Pattern says that "encapsulate a request under an object as a command and pass it to invoker object. Invoker object looks for the appropriate object which can handle this command and pass the command to the corresponding object and that object executes the command". It is also known as Action or Transaction.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With