Functional Command Pattern
Learn the functional command pattern in C# and F#. Discover how functions as first-class citizens simplify command implementation and enable Undo/Redo.
Command pattern is a pattern which allows the executor of the pattern to execute or playback commands. In most applications where Undo/Redo is implemented, this pattern is used.
Here is C# code.
Now, in this code the Command Pattern is not in its purest form. As normally in command pattern we are saving the state of an outside object. Instead, I just returned the result to mock the outside object.
Now have a look at similar F# code. That is doing kind of the same thing.
Here, instead of a class, I am using functions with the command type. And the definition of the command is given as a type instead of an interface. Now, this is fun with functional programming in general, where functions are first-class citizens. I can save commands and events like objects only. I don't have to wrap them around some classes. This makes the code more concise.
Fan of CQRS and Event Sourcing? Listen up—these both design concepts are standing on the shoulders of the command pattern.
Frequently Asked Questions
The Command Pattern allows you to encapsulate requests as objects, enabling you to execute or replay commands. It's commonly used in applications that implement Undo/Redo functionality, where you need to store and manage a history of operations.
In the functional approach, you use functions as first-class citizens and define commands as types rather than classes or interfaces. This eliminates the need to wrap commands in classes, resulting in more concise and readable code while achieving the same functionality.
The Command Pattern provides the foundational mechanism that both Event Sourcing and CQRS depend on—the ability to capture, store, and replay commands as discrete objects. This makes it easier to maintain an audit trail of all operations and separate read/write responsibilities in your application.
Yes, in functional programming languages like F#, you can use functions with a command type to implement the Command Pattern effectively. This approach treats functions as first-class citizens, allowing you to save and execute commands without wrapping them in classes, making the code more concise.
The pure Command Pattern typically saves the state of an external object to enable undo/redo operations. The examples shown use a simplified version that returns results directly instead of modifying external state, making them easier to understand while still demonstrating the core pattern concept.