C ++ design mode: decorator pattern)

Source: Internet
Author: User

Definition:

The modifier mode dynamically attaches the responsibility to the object. To expand the functionality, the decorator provides an alternative solution that is more flexible than inheritance.

Scenario:

When purchasing coffee, we can add a variety of spices, such as steamed milk, soy milk, Moka or covered milk, and the coffee shop will charge different fees based on the spices we add, so when we design the order system, we need to consider these spices. Customers have different requirements. If we declare a class for each recipe, system maintenance will be a headache. In this case, the modifier mode will be used. We can dynamically expand the customized coffee according to the customer's needs, add different spices to them, and finally calculate the customer's fees. Its implementation is a bit similar to recursion, which can be realized in actual use.

Class diagram:

The C ++ code is as follows:

Do not use the pointer version:

# Include <iostream>
# Include <string>
Using namespace STD;

Class Beverage
{
Public:
Virtual ~ Beverage (){};
Virtual string getdescription (); // it must be a virtual function. Otherwise, the description is incorrectly displayed during later use.
Virtual double cost () = 0;
Protected:
String m_description;
};

Class condimentdecorator: Public Beverage
{
Public:
Virtual string getdescription () = 0;
};

Class espresso: Public Beverage
{
Public:
Espresso ();
Double cost ();
};

Class houseblend: Public Beverage
{
Public:
Houseblend ();
Double cost ();
};

Class darkroast: Public Beverage
{
Public:
Darkroast ();
Double cost ();
};

Class decaf: Public Beverage
{
Public:
Decaf ();
Double cost ();
};

Class mocha: Public condimentdecorator
{
Public:
Mocha (beverage * pbeverage );
String getdescription ();
Double cost ();
Protected:
Beverage * m_pbeverage;
};

Class Milk: Public condimentdecorator
{
Public:
Milk (beverage * pbeverage );
String getdescription ();
Double cost ();
Protected:
Beverage * m_pbeverage;
};

Class soy: Public condimentdecorator
{
Public:
Soy (beverage * pbeverage );
String getdescription ();
Double cost ();
Protected:
Beverage * m_pbeverage;
};

Class whip: Public condimentdecorator
{
Public:
Whip (beverage * pbeverage );
String getdescription ();
Double cost ();
Protected:
Beverage * m_pbeverage;
};

String beverage: getdescription ()
{
Return m_description;
}

Espresso: Espresso ()
{
M_description = "Espresso ";
}

Double espresso: cost ()
{
Return 1.99;
}

Houseblend: houseblend ()
{
M_description = "house blend coffee ";
}

Double houseblend: cost ()
{
Return 0.89;
}

Darkroast: darkroast ()
{
M_description = "dark roast coffee ";
}

Double darkroast: cost ()
{
Return 0.99;
}

Decaf: decaf ()
{
M_description = "decaf coffee ";
}

Double decaf: cost ()
{
Return 1.05;
}

Mocha: mocha (beverage * pbeverage)
{
M_pbeverage = pbeverage;
}

String mocha: getdescription ()
{
Return m_pbeverage-> getdescription () + "+ mocha ";
}

Double mocha: cost ()
{
Return 0.20 + m_pbeverage-> Cost ();
}

Milk: milk (beverage * pbeverage)
{
M_pbeverage = pbeverage;
}

String Milk: getdescription ()
{
Return m_pbeverage-> getdescription () + "+ milk ";
}

Double milk: cost ()
{
Return 0.10 + m_pbeverage-> Cost ();
}

Soy: soy (beverage * pbeverage)
{
M_pbeverage = pbeverage;
}

String soy: getdescription ()
{
Return m_pbeverage-> getdescription () + "+ soy ";
}

Double soy: cost ()
{
Return 0.15 + m_pbeverage-> Cost ();
}

Whip: whip (beverage * pbeverage)
{
M_pbeverage = pbeverage;
}

String whip: getdescription ()
{
Return m_pbeverage-> getdescription () + "+ whip ";
}

Double whip: cost ()
{
Return 0.10 + m_pbeverage-> Cost ();
}

Int main ()
{
Espresso espresso;
Cout <espresso. getdescription () <"$" <espresso. Cost () <Endl;

Darkroast;
Mocha mocha1 (& darkroast );
Mocha mocha2 (& mocha1 );
Whip whip1 (& mocha2 );
Cout <whip1.getdescription () <"$" <whip1.cost () <Endl;

Houseblend;
Soy soy1 (& houseblend );
Mocha mocha3 (& soy1 );
Whip whip2 (& mocha3 );
Cout <whip2.getdescription () <"$" <whip2.cost () <Endl;

Return 0;
}

 

Use Pointer version:

 

#include <iostream>
#include <string>
using namespace std;

class Beverage
{
public:
virtual ~Beverage() {};
virtual string getDescription();
virtual double cost() = 0;
protected:
string m_description;
};

class CondimentDecorator:public Beverage
{
public:
virtual string getDescription() = 0;
};

class Espresso:public Beverage
{
public:
Espresso();
double cost();
};

class HouseBlend:public Beverage
{
public:
HouseBlend();
double cost();
};

class DarkRoast:public Beverage
{
public:
DarkRoast();
double cost();
};

class Decaf:public Beverage
{
public:
Decaf();
double cost();
};

class Mocha:public CondimentDecorator
{
public:
Mocha(Beverage* pBeverage);
~Mocha();
string getDescription();
double cost();
protected:
Beverage* m_pBeverage;
};

class Milk:public CondimentDecorator
{
public:
Milk(Beverage* pBeverage);
~Milk();
string getDescription();
double cost();
protected:
Beverage* m_pBeverage;
};

class Soy:public CondimentDecorator
{
public:
Soy(Beverage* pBeverage);
~Soy();
string getDescription();
double cost();
protected:
Beverage* m_pBeverage;
};

class Whip:public CondimentDecorator
{
public:
Whip(Beverage* pBeverage);
~Whip();
string getDescription();
double cost();
protected:
Beverage* m_pBeverage;
};

string Beverage::getDescription()
{
return m_description;
}

Espresso::Espresso()
{
m_description = "Espresso";
}

double Espresso::cost()
{
return 1.99;
}

HouseBlend::HouseBlend()
{
m_description = "House Blend Coffee";
}

double HouseBlend::cost()
{
return 0.89;
}

DarkRoast::DarkRoast()
{
m_description = "Dark Roast Coffee";
}

double DarkRoast::cost()
{
return 0.99;
}

Decaf::Decaf()
{
m_description = "Decaf Coffee";
}

double Decaf::cost()
{
return 1.05;
}

Mocha::Mocha(Beverage* pBeverage)
{
m_pBeverage = pBeverage;
}

Mocha::~Mocha()
{
delete m_pBeverage;
}

string Mocha::getDescription()
{
return m_pBeverage->getDescription() + " + Mocha";
}

double Mocha::cost()
{
return 0.20 + m_pBeverage->cost();
}

Milk::Milk(Beverage* pBeverage)
{
m_pBeverage = pBeverage;
}

Milk::~Milk()
{
delete m_pBeverage;
}

string Milk::getDescription()
{
return m_pBeverage->getDescription() + " + Milk";
}

double Milk::cost()
{
return 0.10 + m_pBeverage->cost();
}

Soy::Soy(Beverage* pBeverage)
{
m_pBeverage = pBeverage;
}

Soy::~Soy()
{
delete m_pBeverage;
}

string Soy::getDescription()
{
return m_pBeverage->getDescription() + " + Soy";
}

double Soy::cost()
{
return 0.15 + m_pBeverage->cost();
}

Whip::Whip(Beverage* pBeverage)
{
m_pBeverage = pBeverage;
}

Whip::~Whip()
{
delete m_pBeverage;
}

string Whip::getDescription()
{
return m_pBeverage->getDescription() + " + Whip";
}

double Whip::cost()
{
return 0.10 + m_pBeverage->cost();
}
int main()
{
Beverage* pBeverage = new Espresso();
cout << pBeverage->getDescription() << " $" << pBeverage->cost() << endl;

Beverage* pBeverage2 = new DarkRoast();
pBeverage2 = new Mocha(pBeverage2);
pBeverage2 = new Mocha(pBeverage2);
pBeverage2 = new Whip(pBeverage2);
cout << pBeverage2->getDescription() << " $" << pBeverage2->cost() << endl;

Beverage* pBeverage3 = new HouseBlend();
pBeverage3 = new Soy(pBeverage3);
pBeverage3 = new Mocha(pBeverage3);
pBeverage3 = new Whip(pBeverage3);
cout << pBeverage3->getDescription() << " $" << pBeverage3->cost() << endl;
delete pBeverage;
delete pBeverage2;
delete pBeverage3;
return 0;
}

The result is as follows:

Espresso $1.99
Dark roast coffee + mocha + whip $1.49
House blend coffee + soy + mocha + whip $1.34

 

Reference books: head first design model

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.