Follow Techotopia on Twitter

On-line Guides
All Guides
eBook Store
iOS / Android
Linux for Beginners
Office Productivity
Linux Installation
Linux Security
Linux Utilities
Linux Virtualization
Linux Kernel
System/Network Admin
Programming
Scripting Languages
Development Tools
Web Development
GUI Toolkits/Desktop
Databases
Mail Systems
openSolaris
Eclipse Documentation
Techotopia.com
Virtuatopia.com
Answertopia.com

How To Guides
Virtualization
General System Admin
Linux Security
Linux Filesystems
Web Servers
Graphics & Desktop
PC Hardware
Windows
Problem Solutions
Privacy Policy

  




 

 

Thinking in C++ Vol 2 - Practical Programming
Prev Home Next

Command: choosing the operation

The Command pattern is structurally very simple, but can have an important impact on decoupling and thus cleaning up your code.

In Advanced C++: Programming Styles And Idioms (Addison Wesley, 1992), Jim Coplien coins the term functor which is an object whose sole purpose is to encapsulate a function (since functor has a meaning in mathematics, we shall use the more explicit term function object). The point is to decouple the choice of function to be called from the site where that function is called.

This term is mentioned but not used in GoF. However, the theme of the function object is repeated in a number of patterns in that book.

A Command is a function object in its purest sense: a function that s an object. By wrapping a function in an object, you can pass it to other functions or objects as a parameter, to tell them to perform this particular operation in the process of fulfilling your request. You could say that a Command is a Messenger that carries behavior.

//: C10:CommandPattern.cpp
#include <iostream>
#include <vector>
using namespace std;
 
class Command {
public:
virtual void execute() = 0;
};
 
class Hello : public Command {
public:
void execute() { cout << "Hello "; }
};
 
class World : public Command {
public:
void execute() { cout << "World! "; }
};
 
class IAm : public Command {
public:
void execute() { cout << "I'm the command pattern!"; }
};
 
// An object that holds commands:
class Macro {
vector<Command*> commands;
public:
void add(Command* c) { commands.push_back(c); }
void run() {
vector<Command*>::iterator it = commands.begin();
while(it != commands.end())
(*it++)->execute();
}
};
 
int main() {
Macro macro;
macro.add(new Hello);
macro.add(new World);
macro.add(new IAm);
macro.run();
} ///:~
 

The primary point of Command is to allow you to hand a desired action to a function or object. In the above example, this provides a way to queue a set of actions to be performed collectively. Here, you can dynamically create new behavior, something you can normally only do by writing new code but in the above example could be done by interpreting a script (see the Interpreter pattern if what you need to do gets very complex).

GoF says that Commands are an object-oriented replacement for callbacks. [141] However, we think that the word back is an essential part of the concept of callbacks a callback reaches back to the creator of the callback. On the other hand, with a Command object you typically just create it and hand it to some function or object, and you are not otherwise connected over time to the Command object.

A common example of Command is the implementation of undo functionality in an application. Each time the user performs an operation, the corresponding undo Command object is placed into a queue. Each Command object that is executed backs up the state of the program by one step.

Thinking in C++ Vol 2 - Practical Programming
Prev Home Next

 
 
   Reproduced courtesy of Bruce Eckel, MindView, Inc. Design by Interspire