I just learned about the decorator pattern and tried to write an example that uses the code. The example is about beverages and some condiments. Inside the Decorator I have a reference variable to a beverage. The beverages available are Decaf and Espresso. The condiments available are Soy and Caramel. If I define a Decaf with more than one Caramel for example, the result I get is just a Decaf with one decorator. So define Caramel->Caramel->Decaf gives me Caramel->Decaf. Defining Caramel->Soy->Caramel->Decaf works fine. Defining Caramel->Soy->Caramel->Caramel->Decaf gives me Caramel->Soy->Caramel->Decaf. Long story short, I can't have two or more condiments of the same type right one after the other. They become only one condiment. If I use pointers it works fine.
The code:
#include <iostream>
//#include "Decaf.h"
//#include "Espresso.h"
//#include "SoyDecorator.h"
//#include "CaramelDecorator.h"
class Beverage
{
public:
virtual std::string GetDescription() const = 0;
virtual int GetCost() const = 0;
};
class CondimentDecorator : public Beverage
{
public:
Beverage& beverage;
CondimentDecorator(Beverage& beverage) : beverage(beverage) {}
};
class Espresso : public Beverage
{
virtual std::string GetDescription() const override
{
return "Espresso";
}
virtual int GetCost() const override
{
return 5;
}
};
class Decaf : public Beverage
{
virtual std::string GetDescription() const override
{
return "Decaf";
}
virtual int GetCost() const override
{
return 4;
}
};
class CaramelDecorator : public CondimentDecorator
{
public:
CaramelDecorator(Beverage& beverage) : CondimentDecorator(beverage) {}
virtual std::string GetDescription() const override
{
return this->beverage.GetDescription() + " with Caramel";
}
virtual int GetCost() const override
{
return this->beverage.GetCost() + 2;
}
};
class SoyDecorator : public CondimentDecorator
{
public:
SoyDecorator(Beverage& beverage) : CondimentDecorator(beverage) {}
virtual std::string GetDescription() const override
{
return this->beverage.GetDescription() + " with Soy";
}
virtual int GetCost() const override
{
return this->beverage.GetCost() + 1;
}
};
int main()
{
Decaf d;
SoyDecorator s(d);
CaramelDecorator c(s);
CaramelDecorator cc(c);
std::cout << cc.GetDescription() << std::endl;
std::cout << cc.GetCost() << std::endl;
}
output:
Decaf with Soy with Caramel
7
// Expected:
// Decaf with Soy with Caramel with Caramel
// 9
Here is the same code but using pointers and works just fine: https://ideone.com/7fpGSp