栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

c++-装饰者模式二

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

c++-装饰者模式二

#include 
#include 
#include 
#include 

using namespace std;

// 反射相关
class funcValidPolicy {
 public:
    template
    static false_type Valid(...);

    template()(declval()...))>
    static true_type Valid(void *);
};

template
struct TypeT {
    using type = T;
};

template
constexpr auto type = TypeT{};

template
T ValueT(TypeT);

auto is_valid = [](auto f) {
    return [](auto ...args) {
        return decltype(funcValidPolicy::template Valid(nullptr)){};
        //return isInvokeAble::value;
    };
};

// 类型必须要getInstance函数
auto has_getInstance = is_valid([](auto t) -> decltype(decltype(ValueT(t))::getInstance()) {
});


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) 
     static shared_ptr getInstance() { 
        return shared_ptr(new name); 
    }

#define DecoratorDefaultFunc(name) 
 private:                          
    shared_ptr beverage;                           
    explicit name(Beverage* bev = nullptr) : beverage(bev){} 
                                   
 public:                               
    void setBeverage(const shared_ptr& bev) override{ 
        beverage = bev;         
    }
    shared_instance_func(name)

class Decorator;

class Beverage : public enable_shared_from_this {
 public:
    string _description;

    virtual string getDescription() {
        return _description + "(" + doubleToStr(totalCost()) + ")n";
    }

    virtual double totalCost() = 0;

    virtual ~Beverage() = default;

    virtual void setBeverage(const shared_ptr &) {}

    template> &&
            has_getInstance(type)
    >>
    auto withDecorator();

    template> &&
            has_getInstance(type)
    >>
    auto withDecorator(shared_ptr);
};

// 抽象类,带数据
class Decorator : public Beverage {
 public:
    //
    string getDescription() override = 0;

    double totalCost() override = 0;

    virtual double cost() = 0;
};

template
auto Beverage::withDecorator() {
    auto beverage = T::getInstance();
    beverage->setBeverage(shared_from_this());
    return beverage;
}

template
auto Beverage::withDecorator(shared_ptr beverage) {
    beverage->setBeverage(shared_from_this());
    return beverage;
}

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

class NoGetInstance : public Decorator {
 public:
    string getDescription() override {
        return Decorator::getDescription();
    }

    double totalCost() override {
        return Decorator::totalCost();
    }

    double cost() override {
        return 0;
    }
};

int main() {
    // 用法一
    auto a = Espresso::getInstance();
    auto ab = a->withDecorator()->withDecorator()->withDecorator();
    cout << ab->getDescription() << "total : ";
    cout << ab->totalCost() << endl << endl;


    // 用法二
    auto d = Espresso::getInstance();
    auto de = d->withDecorator(Mocha::getInstance())->withDecorator(Whip::getInstance())->withDecorator(
            Mocha::getInstance());
    cout << de->getDescription() << "total : ";
    cout << de->totalCost() << endl;

}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/396062.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号