您的当前位置:首页正文

c++-装饰者模式一

2024-12-02 来源:个人技术集锦

基本的装饰者模式

#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;
}

输出

显示全文