Command Pattern made Reactive
ReactiveCommander


According to Wikipedia:
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.
When I was writing the book Reactive Programming in your Swift Apps and inspired by the architecture we use in SoundCloud for iOS I came up with the idea of implementing a framework that mixed both, Reactive and Commands using existing Foundation components like NSOperation or NSOperationQueues. I’ve to say I’m not very original inventing names so I called the framework ReactiveCommander.
Advantages of the Command Pattern
- Self-dependency: Commands have all its dependency injected and that’s everything they need to be executed (e.g. the request predicate to access database element, the HTTP request to fetch a collection from an API). That simplifies our dependencies graph and forcing the immutability of these dependencies we protect our action logic from a race condition that might arise during the operation execution.
- Single responsibility: The concept “commands” aims to design actions with just only a responsibility. For example, we could have a command that clears the user credentials, ClearCredentialsCommand, a command that fetches our SoundCloud likes, FetchLikesApiCommand but would you have a command that authenticates the user against an API, save its credential and persists its account? How would it be? AuthenticationAndSessionPersistanceAndAccountSaverCommand?
- Asynchrony management: Commands shouldn’t worry about the thread where they’ll be executed. We can design our custom scheduling system based on queues for example that takes these commands and execute them in a background queue. Consequently, the threading management is centralised and we can even specify the background priority of these commands when they’re about to be executed in the background.
Reusability might result hard when working with commands. It’s up to you to decide the level of reusability of your commands. You might have for example commands that reports everything out and then you can chain these results with more commands that also can be composed with other commands… My recommendation regarding its topic is that you try to have only one level of reuse, otherwise you’ll end up with a messy graph of commands interacting between among them. ReactiveCommander offers simple composition commands like RollbackCommand or SyncCommand I’ll explain below.
ReactiveCommander
The idea of ReactiveCommander is to provide a set of base commands that can be extended on different purposes. These commands can be scheduled in an NSOperationQueue subclass queue that support ReactiveCommander commands. When commands are scheduled a Signal (from ReactiveCocoa) is returned to listen to the events that are sent by the command when it gets executed.
Commands
- Command: Basic command, it’s a generic type Command<T> where T is the value returned after the execution. In order to use this command, it must be subclassed and the method action() overridden as shown in the example below:
- FetchCommand: Command that returns a value if it could be properly fetched from a data source. FetchCommand<T> must be overridden before being used implementing the method fetch():
- SaveCommand: In this case the command is initialized with an object which is persisted somewhere. The method that has to be overridden is execute(withObject object: T) where you specify how the object is saved:
- SyncCommand: This command is initialized with a main command, Command<T> and a SaveCommand<T> type. The first one returns a value that is persisted by the second command:
Queue
Finally, the commands that we have seen can be scheduled in a CommandQueue. You can use its backgroundQueue singleton instance that uses the GCD queue with priority DISPATCH_QUEUE_PRIORITY_DEFAULT or you can implement your own Queue with your configuration (it’s a subclass of NSOperationQueue).
When the commands are added a Signal is returned to get the values returned by the original Command when it gets executed in the queue. Moreover you can use a couple of custom operators provided by the framework <~ and <~!:
Reactive Programming in your Swift Apps
If you’re interested in this and other Reactive ideas, I recommend you the book I worked on the past months where I explain this and other related concepts related to Reactive Programming in Swift.