博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
装饰者模式(decorator pattern)
阅读量:7154 次
发布时间:2019-06-29

本文共 1937 字,大约阅读时间需要 6 分钟。

装饰者模式:

    能够动态地往一个类中添加新的行为。相比继承是在编译时添加行为,装饰模式是在运行时添加行为。

星巴克咖啡是讲述装饰者模式的一个很好的例子。

    假设现在有两种咖啡:HouseBlend、DarkRoast,同时有两种调料:Milk、Mocha。那么此时我们可以给顾客提供以下咖啡:

HouseBlend、HouseBlendWithMilk、HouseBlendWithMocha、HouseBlendWithMilkandMocha、

DarkRoast、DarkRoastWithMilk、DarkRoastWithMocha、DarkRoastWithMilkandMocha。如果每种搭配都是一个类,那么随着咖啡和调料种类的增加,将会出现类爆炸:

此时装饰者模式应运而生,结构图如下:

C++实现:

class Coffee {public:    virtual double getCost() = 0;    virtual string getDescription() = 0;};class HouseBlend : public Coffee {public:    double getCost() { return 1.24; }    string getDescription() { return "HouseBlend"; }};class DarkRoast : public Coffee {public:    double getCost() { return 2.73; }    string getDescription() { return "DarkRoast"; }};class CoffeeDecorator : public Coffee {private:    Coffee *decoratedCoffee;public:    CoffeeDecorator(Coffee *c): decoratedCoffee(c) {}    double getCost() { return decoratedCoffee->getCost(); }    string getDescription() { return decoratedCoffee->getDescription(); }};class Milk : public CoffeeDecorator {public:    Milk(Coffee *c): CoffeeDecorator(c) {}    double getCost() { return CoffeeDecorator::getCost() + 0.5; }    string getDescription() {
return CoffeeDecorator::getDescription() + ", Milk"; }};class Mocha : public CoffeeDecorator {public: Mocha(Coffee *c): CoffeeDecorator(c) {} double getCost() { return CoffeeDecorator::getCost() + 0.7; } string getDescription() {
return CoffeeDecorator::getDescription() + ", Mocha"; }};int main(){ Coffee *pc = new HouseBlend; cout << "description: " << pc->getDescription() << " cost: " << pc->getCost() << endl; pc = new Milk(pc); cout << "description: " << pc->getDescription() << " cost: " << pc->getCost() << endl; pc = new Mocha(pc); cout << "description: " << pc->getDescription() << " cost: " << pc->getCost() << endl; delete pc;}

装饰者模式的一个特征是:装饰者和被装饰对象具有相同的超类型。

reference:

 

转载于:https://www.cnblogs.com/gattaca/p/4737586.html

你可能感兴趣的文章
vs皮肤 插件
查看>>
几种任务调度的 Java 实现方法与比较
查看>>
js 使用swiper实现层叠轮播
查看>>
BZOJ4196 NOI2015 软件包管理器
查看>>
怎样打开64位 Ubuntu 的32位支持功能?
查看>>
解决 asp.net 伪静态 IIS设置后 直正HTML无法显示的问题
查看>>
命名空间、全局/局部作用域、作用域链、闭包
查看>>
hdu 1163 Eddy's digital Roots
查看>>
秦曾昌人工智能课程---1、机器学习中的数学基础
查看>>
炼数成金数据分析课程---13、回归分析
查看>>
PHP SPL标准库之数据结构栈(SplStack)介绍(基础array已经可以解决很多问题了,现在开始解决问题)...
查看>>
显示随机键盘
查看>>
amazeui学习笔记--css(HTML元素1)--按钮Button
查看>>
28335外部中断的简单介绍和配置
查看>>
1+2+...+n>=max问题的求解
查看>>
HDU2296 Ring [AC自动机+DP]
查看>>
Linux Shell编程,使用随机数
查看>>
下半部和推后执行的工作
查看>>
Python简单的用户交互
查看>>
第一天开技术博客
查看>>