基本的装饰者模式
#include <iostream>
#include <memory>
using namespace std;
class Component {
public:
virtual void doSomething() = 0;
virtual ~Component() {}
};
class Person : public Component {
public:
void doSomething() override {
cout << "Person information like this" << endl;
}
};
class Decorator : public Component {
private:
shared_ptr<Component> _component;
virtual void doSomethingElse() = 0;
public:
Decorator(shared_ptr<Component> component) : _component(component) {}
virtual void doSomething() override {
_component->doSomething();
doSomethingElse();
}
};
class DecoratorWithClothes : public Decorator {
public:
DecoratorWithClothes(shared_ptr<Component> component) : Decorator(component) {}
void doSomethingElse() override {
cout << "decorator with clothes" << endl;
}
};
class DecoratorWithShoes : public Decorator {
public:
DecoratorWithShoes(shared_ptr<Component> component) : Decorator(component) {}
void doSomethingElse() override {
cout << "decorator with shoes" << endl;
}
};
class DecoratorWithHair : public Decorator {
public:
DecoratorWithHair(shared_ptr<Component> component) : Decorator(component) {}
void doSomethingElse() override {
cout << "decorator with hair" << endl;
}
};
class DecoratorWithGloves : public Decorator {
public:
DecoratorWithGloves(shared_ptr<Component> component) : Decorator(component) {}
private:
void doSomethingElse() override {
cout << "decorator with gloves" << endl;
}
};
int main() {
auto pcs = make_shared<DecoratorWithHair>(
make_shared<DecoratorWithShoes>(
make_shared<DecoratorWithClothes>(
make_shared<Person>())));
pcs->doSomething();
cout << endl;
auto pcsg = make_shared<DecoratorWithGloves>(pcs);
pcsg->doSomething();
}
输出
内存安全的进阶模式
#include <iostream>
#include <string>
#include <memory>
#include <cassert>
using namespace std;
string doubleToStr(double price) {
char buffer[128];
snprintf(buffer, sizeof(buffer), "%.2lf", price);
return buffer;
}
string descriptionFormat(const string &name, double price) {
return "with " + name + "(" + doubleToStr(price) + ")\n";
}
#define shared_instance_func(name, ...) \
template<typename ...Args> \
static shared_ptr<name> getInstance(const Args& ...args) { \
return shared_ptr<name>(new name(args...)); \
}
#define DecoratorDefaultFunc(name) \
private: \
shared_ptr<Beverage> beverage; \
public: \
explicit name(const shared_ptr<Beverage>& bev) : beverage(bev){} \
shared_instance_func(name)
class Decorator;
class Beverage : public enable_shared_from_this<Beverage> {
public:
string _description;
virtual string getDescription() {
return _description + "(" + doubleToStr(totalCost()) + ")\n";
}
virtual double totalCost() = 0;
virtual ~Beverage() = default;
};
class Decorator : public Beverage {
public:
virtual string getDescription() override = 0;
double totalCost() override = 0;
virtual double cost() = 0;
};
class Espresso : public Beverage {
private:
Espresso() {
_description = "Espresso";
}
public:
shared_instance_func(Espresso)
double totalCost() override {
return 1.99;
}
};
class Mocha : public Decorator {
public:
DecoratorDefaultFunc(Mocha)
string getDescription() override {
assert(nullptr != beverage);
return beverage->getDescription() + descriptionFormat("Mocha", cost());
}
double totalCost() override {
assert(nullptr != beverage);
return beverage->totalCost() + cost();
}
double cost() override {
return .32;
}
};
class Whip : public Decorator {
public:
DecoratorDefaultFunc(Whip)
string getDescription() override {
return beverage->getDescription() + descriptionFormat("Whip", cost());
}
double totalCost() override {
return beverage->totalCost() + cost();
}
double cost() override {
return .23;
}
};
int main() {
auto res = Whip::getInstance(Mocha::getInstance(Whip::getInstance(Espresso::getInstance())));
cout << res->getDescription() << endl;
cout << res->totalCost() << endl;
}
输出