Friday, October 16, 2015

Design Pattern - Command pattern

Description:
The command pattern encapsulates a request as an object to perform an operation on an object (receiver). This allows client to parameterize other objects (invoker) with different requests, queue or log requests, and support undoable operations.

In short - "Encapsulate a command request as an object"


Problem:
Need to issue requests to objects without knowing anything about the operation being requested or the receiver of the request.

How to use Command pattern:
1. Concepts involved in Command pattern, 'receiver', 'invoker' and 'command'

2. Create an interface 'command' with abstract method 'execute'

3. Create derived concrete class(es) from 'command' base class which encapsulates a 'receiver', a method to invoke and the arguments to pass

4. 'Receiver' is actually responsible to perform the desired action which is encapsulated in the 'command' as attribute. Mostly passed to command through constructor

5. 'Invoker' gets the command object(s) through method like 'setCommand(Command)' and provides a mean to make a call to 'command' class's 'execute' method

6. Client of Command pattern creates a concrete 'command' object, passes reciever to it and sets it to 'invoker' by making call to 'setCommand(Command)'. Later client asks 'invoker' to execute the command.

Class diagram:


























Benefits:
1. decouples the object that invokes the operation from the one that know how to perform it
2. Allows parameterization of clients with different requests
3. Allows invoker to save request in a queue
4. Undo and redo functionality can be implemented as 


Notes:
1. Macro Command - represents set of commands to be performed on call to be executed. Macro commands can be implemented as Composite, can also have other operation like undo, redo, forward/backward traversing, logging, queue etc.
2. Undo/redo action - can be performed two ways
  • Store receiver's previous state in memory
  • Store set of performed actions on receiver in memory
3. Queuing the requests - as the commands are isolated from invoker, those can be executed asynchronously in background of an application. Usually invoker keeps a set of commands, runs in main thread and action request to receiver can happen in a separate thread. To have faster processing, multi-thread can be considered to run through the set of commands. Scheduler, thread pool, job queues etc. applications can be considered as good example of this scenario.



Things to check back:
1. Coexistence with other patterns
2. Alternates of Command patterns


Resources:
1. Head First Design Pattern
2. https://sourcemaking.com/design_patterns
3. https://en.wikipedia.org/wiki/command_pattern

No comments: