版权声明:本文为博主原创文章,未经博主同意不得转载。 https://blog.csdn.net/walkerkalr/article/details/28633123

模式定义:

        装饰者模式动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。

        装饰者和被装饰者有同样的超累类型。

        能够用一个或多个装饰者包装一个对象。

        既然装饰者和被装饰者对象有同样的超累类型,所以在不论什么须要原始对象(被包装的)的场合,能够用装饰过的对象取代它。

        装饰者能够托付被装饰者的行为之前与或之后,加上自己的行为,以达到特定的目的。

        对象能够在不论什么时候被装饰,所以能够在执行时动态地、不限量地用你喜欢的装饰者来装饰对象。

模式结构:

举例:

        购买咖啡时,能够在当中增加各种调料,例如:蒸奶(Steamed Milk)。豆浆(Soy)。摩卡(Mocha)或覆盖奶泡。

咖啡馆会依据所增加的调料收取不同的费用。

        解决方法:我们以饮料为主体。然后在执行时以调料来装饰饮料。例如说顾客想要摩卡和奶泡深焙咖啡。那么,要做的是:拿一个深焙咖啡(DarkRoast)对象,以摩卡(Mocha)对象装饰它。以奶泡对象装饰它,调用cost()方法。并依赖托付将调料的价钱加上去。

UML设计:

编程实现及执行结果:

#include <iostream>
#include <string>
using namespace std; class Beverage
{
public:
Beverage(string str = "Unknow Beverage")
:description(str){} virtual string getDescription()
{
return description;
} virtual double cost(){return 0;} private:
string description;
}; class CondimentDecorator : public Beverage
{
public:
string getDescription(){return "";}
}; class Espresso : public Beverage
{
public: Espresso():Beverage("Espresso"){} double cost()
{
return 1.99;
}
}; class HouseBlend : public Beverage
{
public:
HouseBlend():Beverage("HouseBlend Coffee"){} double cost()
{
return 0.89;
}
}; class Mocha : public CondimentDecorator
{
public:
Mocha(Beverage* beve)
{
beverage = beve;
} string getDescription()
{
return beverage->getDescription()+", Mocha";
} double cost()
{
return 0.20 + beverage->cost();
}
private:
Beverage* beverage;
}; class Whip : public CondimentDecorator
{
public:
Whip(Beverage* beve)
{
beverage = beve;
} string getDescription()
{
return beverage->getDescription()+", Whip";
} double cost()
{
return 0.15 + beverage->cost();
}
private:
Beverage* beverage;
};
int main()
{
Beverage* pBeverage = new Espresso();
cout << pBeverage->getDescription() << " $" << pBeverage->cost() <<endl; Beverage* pBeverage2 = new Espresso();
pBeverage2 = new Mocha(pBeverage2);
pBeverage2 = new Mocha(pBeverage2);
cout << pBeverage2->getDescription() << " $" << pBeverage2->cost() <<endl; pBeverage2 = new Whip(pBeverage2);
cout << pBeverage2->getDescription() << " $" << pBeverage2->cost() <<endl; return 0;
}

        执行结果:

Espresso$1.99

Espresso,Mocha, Mocha $2.39

Espresso,Mocha, Mocha, Whip $2.54

请按随意键继续. . .

        这样就能够是不同饮料增加不同的配料,而不用改动源码。而且能够增加新的配料类型和饮料类型。

设计原则的应用:

        设计原则5:类应该对外扩展。对改动关闭。如装饰者模式中,我们的目标是同意类easy扩展,在不改动现有代码的情况下。就可搭配新的行为。

         參考:Head First设计模式

设计模式C++实现——装饰者模式的更多相关文章

  1. JAVA设计模式之【装饰者模式】

    JAVA设计模式之[装饰者模式] 装饰模式 对新房进行装修并没有改变房屋的本质,但它可以让房子变得更漂亮.更温馨.更实用. 在软件设计中,对已有对象(新房)的功能进行扩展(装修). 把通用功能封装在装 ...

  2. Java设计模式12:装饰器模式

    装饰器模式 装饰器模式又称为包装(Wrapper)模式.装饰器模式以多客户端透明的方式扩展对象的功能,是继承关系的一个替代方案. 装饰器模式的结构 通常给对象添加功能,要么直接修改对象添加相应的功能, ...

  3. 【读书笔记】读《JavaScript设计模式》之装饰者模式

    一.定义 装饰者模式可用来透明地把对象包装在具有同样接口的另一个对象之中.这样一来,你可以给一个方法添加一些行为,然后将方法调用传递给原始对象.相对于创建子类来说,使用装饰者对象是一种更灵活的选择(装 ...

  4. 设计模式学习心得<装饰器模式 Decorator>

    装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创建了一个装饰类,用来包装 ...

  5. 设计模式のDecoratorPattern(装饰器模式)----结构模式

    一.产生背景 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创建了一个装 ...

  6. 重学 Java 设计模式:实战装饰器模式(SSO单点登录功能扩展,增加拦截用户访问方法范围场景)

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 对于代码你有编程感觉吗 很多人写代码往往是没有编程感觉的,也就是除了可以把功能按照固 ...

  7. 《Head First 设计模式》之装饰者模式

    作者:Grey 原文地址:http://www.cnblogs.com/greyzeng/p/5922248.html 模式名称 装饰者模式(Decorator Pattern) 需求 定义咖啡厅中的 ...

  8. 设计模式学习之装饰者模式(Decorator,结构型模式)(16)

    参考地址:http://www.cnblogs.com/zhili/p/DecoratorPattern.html 一.定义:装饰者模式以对客户透明的方式动态地给一个对象附加上更多的责任,装饰者模式相 ...

  9. [设计模式] javascript 之 装饰者模式

    装饰者模式说明 说明:通一个类来动态的对另一个类的功能对象进行前或后的修饰,给它辅加一些额外的功能; 这是对一个类对象功能的装饰,装饰的类跟被装饰的类,要求拥有相同的访问接口方法(功能),这在动态面向 ...

随机推荐

  1. SpringBoot2.0 redis生成组建和读写配置文件

    @Component 生成组建 @ConfigurationProperties(prefix="redis") 读写redis配置文件 application.propertie ...

  2. 【Java深入研究】10、红黑树

    一.红黑树介绍 红黑树是二叉查找树,红黑树的时间复杂度为: O(lgn) 红黑树的特性:(1)每个节点或者是黑色,或者是红色.(2)根节点是黑色.(3)每个叶子节点(NIL)是黑色. [注意:这里叶子 ...

  3. Javascript继承2:创建即继承----构造函数继承

    //声明父类 function SuperClass(id){ //值类型公有属性 this.id = id; //引用类型公有属性 this.books = ['Html','Css']; } // ...

  4. angular ng-repeat radio取值

  5. CSS制作镂空字体

    1.效果图 2.html内容: <!doctype html><html lang="en"><head> <meta charset=& ...

  6. 淘宝cnpm

    npm install -g cnpm --registry=https://registry.npm.taobao.org

  7. vue单页应用添加百度统计

    前言 申请百度统计后,会得到一段JS代码,需要插入到每个网页中去,在Vue.js项目首先想到的可能就是,把统计代码插入到index.html入口文件中,这样就全局插入,每个页面就都有了;这样做就涉及到 ...

  8. Nginx 限制并发连接和并发请求数配置

    Nginx限制并发连接和并发请求数配置   by:授客  QQ:1033553122   测试环境 nginx-1.10.0 配置介绍 查看是否内置模块 # pwd /mnt/nginx-1.10.0 ...

  9. seajs的原理以及基本使用

    seajs模块化开发 模块化开发,把整个文件分割成一个一个小文件. 使用方法 使用方法特别简单,首先在官网中下载sea.js,然后在页面中引入. index.html // 1.路径 // 2.回调 ...

  10. [20190214]11g Query Result Cache RC Latches.txt

    [20190214]11g Query Result Cache RC Latches.txt --//昨天我重复链接http://www.pythian.com/blog/oracle-11g-qu ...