Overview
This is the last post from the introduction series in which we will identify and use a design pattern for the problem found in PART 2, according to the steps presented in PART 1
Finding a pattern steps:
Note: the code can be found here.
1. Identify the problem
We identified the problem in the previous post : the dependency of the startUnit method on specific operations therefore we have a problem of how objects and classes interact.
2. Identify the pattern family
Our problem of class interaction is solved by the behavioral patterns.
3. Scan the intent section of each pattern
We found the following description in “The Gang of four“.
Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and supportable operations.
4. Study the pattern description
From the pattern description we extract following:
- the pattern applies when we have no way of knowing the receiver of the request or the operations that will carry out.
- turns the request into an object
- the key to this pattern is an Command interface which has an execute operation
- each subclass stores the instance as a class variable
- implements an execute method to invoke the operation
From the description this pattern looks like a good candidate to solve our problem regarding the dependency on specific operations.
5. Examine reason of redesign
The Command pattern solves our problem regarding the knowledge of startUnit method on the types of operations for each tower type.
We can now add new types of towers without modifying the existing implementation.
6. Consider what should be variable in your design
This step is the opposite of the previous step. We have to think about what will change in the future.
We to have different types of unit that do different type of actions that will be modified in the future.
Applying the pattern steps:
1. Get an overview of the pattern
We will take a deeper look at the Motivation section:
- user interface toolkit with menus and button that carry out different request from the user
- the toolkit cannot implement explicitly the request in the menu or buttons
- only the applications that use the toolkit will know for witch object to apply the operation
- etc
2. Understand the structure of the pattern
The pattern has the following structure:

Understanding the diagram
Let’s have a firs look at the diagram and see what can we make of it. Let’s apply the information from Understanding UML class diagrams chapter presented in the first post and see what we can figure out.
- Command is an interface with an execute method
- ConcreteCommandOne:
- is a realization of Command interface
- it has a dependency on the Receiver class
- in the helper note we see that it wraps the receiver action – calling it from the execute method.
- Client:
- has a dependency on the Receiver
- instantiates a ConcreteCommandOne (the doted line).
- Invoker:
- aggregates (has ownership but does not manage his lifetime) of Command
Understanding the Participant section
Now let’s get more information from “The gang of four” . The following information’s are from the Participant section of the command pattern:
- Command:
- declares an interface for executing an operation
- ConcreteCommandOne:
- define a binding between a receiver action and an action
- implements Execute by invoking the corresponding operation on receiver
- Client:
- creates a ConcreteCommandOne and sets its receiver
- Invoker:
- asks the command to carry out the request
- Receiver:
- knows to perform the operations associated with carrying out a request
- any class may serve as a receiver
Concluding we could extract the following:
- A Command interface realization must be created for each class that has an operation to execute.
- ConcreteCommandOne class implements the execute method which calls the action from the Receiver class (we need a concrete command for each tower type).
- The Client instantiates the Command interface realizations
- The Invoker class runs the execute method for each Command class
3. Search for examples
You can use the following resources to get more examples:
4. Choose names for pattern participants
The Client class is the one that instantiates the concrete commands.
In our case this happens in the main method of the TowerDefense class.
The Invoker class is the one who calls each command. In our case this functionality is done by the startUnit method from the TowerDefense class.
For Command interface we add a new interface and call it ICommand (I know very original name :p).
Each tower type( IOffensiveTower, IDelayTower, IMoneyGeneratorTower) represent our receiver classes
From ICommand interface we derive OffensiveCommand class for classes inheriting from IOffensiveTower, DelayCommand class for classes inheriting IDelayTower etc.
For simplicity I only made the diagram for offensive unit types.

5. Define the interfaces and classes
In this step we create the ICommand interface and its realizations.
6. Define application names for method and members for the method participants.
In my opinion the execute is a suggestive name for the ICommand method. It executes the action for each unit type.
7. Implement the methods that carryout the responsibility in the pattern.
Here I will provide you snippets of code from the full implementation that can be found here.
The ICommand interface contains the execute method.
class ICommand
{
public:
virtual void execute() = 0;
};
The OffensiveCommand class receives an instance of a realization of IOffensiveTower and calls the shooTroll method of it.
class OffensiveCommand : public ICommand
{
public:
OffensiveCommand(std::unique_ptr<IOffensiveTower>tower_)
:tower(std::move(tower_))
{}
virtual void execute()
{
tower->shootTroll();
}
private:
std::unique_ptr<IOffensiveTower> tower;
};
In main we instantiate 3 tower types that we use as parameters for 3 commands.
In startUnit we got rid off the switch case and static_casts (HOORAY!!!). Note:See implementation from PART1.
int main()
{
unique_ptr<IOffensiveTower> offensive = make_unique<OffensiveTower>();
unique_ptr<IDelayTower> delay = make_unique<DelayTower>();
unique_ptr<IMoneyGeneratorTower> money = make_unique<MoneyGeneratorTower>();
unique_ptr<ICommand> delayCommand = make_unique<DelayCommand>(move(delay));
unique_ptr<ICommand> moneyCommand = make_unique<MoneyGeneratorCommand>(move(money));
unique_ptr<ICommand> offensiveCommand = make_unique<OffensiveCommand>(move(offensive));
startUnit(move(delayCommand));
startUnit(move(moneyCommand));
startUnit(move(offensiveCommand));
getchar();
return 0;
}
// Function used by the map to start the tower's ability
void startUnit(unique_ptr<ICommand> command)
{
if (command != nullptr)
{
command->execute();
}
}
Extending our code
Now lets see what we have to do to extend our code with a new unity type:
- Create a new interface for that unit type derived from IUnit.
- Add a realization for each new unit of the specified type.
- Add a new concrete command class.
Now we fully respect the “open close principle” we extend the existing code but not modify it.
The steps to add the new witch unit type that bewitches trolls is the following:
- We create the IWitchTower interface with the bewitch method (derived from IUnit).
- We add a concrete class WitchTower that implements the bewitch method.
- Add a concrete command that wraps the WitchTower request int the execute method.
IWitchTower interface:
class IWitchTower : public IUnit
{
public:
virtual void bewitchTroll() = 0;
};
WitchTower class:
class WitchTower : public IWitchTower
{
public:
virtual void bewitchTroll()
{
std::cout << "attack another troll" << std::endl;
}
virtual Type getType()
{
return Type::Witch;
}
};
WitchCommand class:
class WitchCommand : public ICommand
{
public:
WitchCommand(std::unique_ptr<IWitchTower>tower_)
:tower(std::move(tower_))
{
}
virtual void execute()
{
tower->bewitchTroll();
}
private:
std::unique_ptr<IWitchTower> tower;
};
Notes:
- the starUnit method and the other classes remain unchanged.
- the Type enum and getType method from IUnit can be removed.
Can we do better? Depending on our use case the following chapter presents an alternative solution in which we discard the command classes.
Alternative solution
I propose an optimization where the execute method is part of IUnit and each class implements also the execute method.
In this case we don’t need the command classes.
The new structure is presented in the following diagram:

IUnit has the following implementation:
class IUnit
{
public:
virtual void execute() = 0;
};
IOffensiveTower has the following implementation:
class IOffesniveTower : public IUnit
{
public:
virtual void shootTroll() = 0;
};
OffensiveTower has the following implementation:
class OffesniveTower : public IOffesniveTower
{
public:
OffesniveTower() = default;
virtual void shootTroll()
{
std::cout << "shooting" << std::endl;
}
void execute()
{
shootTroll();
}
};
And in TowerDefense we have the following usage:
int main()
{
unique_ptr<IUnit> offensive = make_unique<OffesniveTower>();
unique_ptr<IUnit> delay = make_unique<MoneyGeneratorTower>();
unique_ptr<IUnit> money = make_unique<DelayTower>();
unique_ptr<IUnit> brokenTower = nullptr;
startUnit(move(offensive));
startUnit(move(delay));
startUnit(move(money));
getchar();
return 0;
}
// Function used by the map to start the tower's ability
void startUnit(unique_ptr<IUnit> unit)
{
if (unit != nullptr)
{
unit->execute();
}
}
In case we want to extend with a new tower type we have to do the following:
- create a new interface for that unit type, derived from IUnit.
- add a realization for each new unit of the specified type.
The following question arises: do we still have a command pattern ?
In very strict manner maybe not. In my personal opinion yes because patterns are a general solution that can be tailored for our needs( even if it is a simplified use case – we do not encapsulate the behavior in a command object), but we solve the same problem type.
The complete code can be found here.
Another solution would be to use lambda functions instead of commands but this is a topic for another post. This feature can be used only if we have C++11 or higher. So as we see there are many possible solutions and we have to choose the one that fits our projects needs.
Conclusions
We learned the following:
- how to solve a design problem with a pattern
- it is possible to tailor the pattern
- other possibilities may exists (ex: like using lambda function if supported by compilers)
I recommend to take the following into consideration when wanting to change, refactor or rewrite a piece of code:
- why do we want to refactor the current code (why we don’t like it)
- identify possible solutions (take into consideration also the project restrictions)
- analyze benefits and drawbacks of each solutions
- does the effort to implement the solution bring benefits for the future.
Also don’t worry if you won’t succeed from the beginning software development is an iterative and incremental process.
You can find here PART1 and PART2. In the next post will dive into the Abstract Factory creational pattern.
If you liked my post please add a comment and share it .
If you see things that you want to be improved write a comment or contact me at blog@adriannecula.eu. Thanks, Adrian.
1 thought on “Introduction to design patterns PART 3”