装饰器模式

装饰器模式是给对象动态的增加某些特性,比如咖啡店买咖啡,可以加坚果,加奶,加糖。设计一个咖啡类,如果每次新增一个选项都要修改这个类,就会破坏类的开放-封闭原则(对扩展开放,对修改封闭)。装饰器模式是在外部给类增加选项,避免直接修改类
下面我们通过一个简单的咖啡类来看看具体的装饰器模式

class ICoffee {  //咖啡基类
public:
    virtual std::string description() = 0;
    virtual double cost() = 0;
};

class LatteCoffee : public ICoffee { //拿铁
public:
    std::string description() {
        return "this is Coffee latte ";
    }

    double cost() {
        return 12.1;
    }
};

class  AmericanoCoffee : public ICoffee {  //美式
public:
    std::string description() {
        return "this is Coffee Americano ";
    }

    double cost() {
        return 10.0;
    }
};
class IDecrator : public ICoffee { //装饰器基类
public:
protected:
    std::shared_ptr<ICoffee> sp_coffee_;
};

class milk : public IDecrator { //加奶
public:
    milk(const std::shared_ptr<ICoffee>& sp_coff) {
        sp_coffee_ = sp_coff;
    }

    std::string description() {
        std::string strdescription = "";
        if (sp_coffee_) {
            strdescription = sp_coffee_->description();
        }
        strdescription += " add milk ";
        return strdescription;
    }

    double cost() {
        if (!sp_coffee_) {
            return 0.0;
        }
        return sp_coffee_->cost() + 1.2;
    }
};

class sugar : public IDecrator { //加糖
public:
    sugar(const std::shared_ptr<ICoffee>& sp_coff) {
        sp_coffee_ = sp_coff;
    }

    std::string description() {
        std::string strdescription = "";
        if (sp_coffee_) {
            strdescription = sp_coffee_->description();
        }
        strdescription += "add sugar. ";
        return strdescription;
    }

    double cost() {
        if (!sp_coffee_) {
            return 0.0;
        }
        return sp_coffee_->cost() + 0.8;
    }
};
int main() {
    {
        std::shared_ptr<LatteCoffee> sp_latte(make_shared<LatteCoffee>());      //拿铁
        std::shared_ptr<sugar> sp_decrator(make_shared<sugar>(sp_latte));       //加糖
        std::shared_ptr<sugar> sp_decrator1(make_shared<sugar>(sp_decrator));   //加糖
        std::shared_ptr<milk> sp_decrator2(make_shared<milk>(sp_decrator1));    //加奶
        if (sp_decrator2) {
            std::cout << sp_decrator2->description() << "cost: " << sp_decrator2->cost() << std::endl;
        }
    }
    return 0;
}

this is Coffee latte add sugar. add sugar.  add milk cost: 14.9

优点:对于已经存在的对象,可以很方便的进行包装修改而不需要修改原来的类,可以灵活的扩展功能
缺点:会增加大量的装饰类,增加了程序的复杂度,新增一个功能不但需要实例化原本的类,还需要把类添加到装饰类中

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容