Command - shoonie/StudyingDesignPattern GitHub Wiki
Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations.
- Command decouples the object that invokes the operation from the one that knows how to perform it.
- Command are first-class objects. They can be manipulated and extended like any other object.
- You can assemble commands into a composite command.
- It's easy to add new Commands, because you don't have to change existing classes
- How intelligent should a command be? A command can have a wide range of abilities.
- Supporting undo and redo.
- Avoiding error accumulation in the undo process.
- using C++ template
//https://ko.wikipedia.org/wiki/%EC%BB%A4%EB%A7%A8%EB%93%9C_%ED%8C%A8%ED%84%B4
#include <iostream>
#include <vector>
#include <string>
using namespace std;
class Command{
public:
virtual void execute(void) =0;
virtual ~Command(void){};
};
class Ingredient : public Command {
public:
Ingredient(string amount, string ingredient){
_ingredient = ingredient;
_amount = amount;
}
void execute(void){
cout << " *Add " << _amount << " of " << _ingredient << endl;
}
private:
string _ingredient;
string _amount;
};
class Step : public Command {
public:
Step(string action, string time){
_action= action;
_time= time;
}
void execute(void){
cout << " *" << _action << " for " << _time << endl;
}
private:
string _time;
string _action;
};
class CmdStack{
public:
void add(Command *c) {
commands.push_back(c);
}
void createRecipe(void){
for(vector<Command*>::size_type x=0;x<commands.size();x++){
commands[x]->execute();
}
}
void undo(void){
if(commands.size() >= 1) {
commands.pop_back();
}
else {
cout << "Can't undo" << endl;
}
}
private:
vector<Command*> commands;
};
int main(void) {
CmdStack list;
//Create ingredients
Ingredient first("2 tablespoons", "vegetable oil");
Ingredient second("3 cups", "rice");
Ingredient third("1 bottle","Ketchup");
Ingredient fourth("4 ounces", "peas");
Ingredient fifth("1 teaspoon", "soy sauce");
//Create Step
Step step("Stir-fry","3-4 minutes");
//Create Recipe
cout << "Recipe for simple Fried Rice" << endl;
list.add(&first);
list.add(&second);
list.add(&step);
list.add(&third);
list.undo();
list.add(&fourth);
list.add(&fifth);
list.createRecipe();
cout << "Enjoy!" << endl;
return 0;
}