版权声明:本文为博主原创文章,未经博主同意不得转载。 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. 29.QT-自定义窗口拖动、自定义QToolButton/QPushButton开关按钮、界面阴影,声音等总结

    自定义窗口及拖动 1.自定义无边框窗口时,需要将窗口标志设为: Qt::FramelessWindowHint |Qt::WindowSystemMenuHint | Qt::WindowMinMax ...

  2. springMVC_05结果跳转方式

    一.总结 总共有四个, 1.设置ModelAndView的值,根据view和视图解析器跳转到指定的页面 2.通过servletapi对象来实现,不需要视图解析器 3.通过springmvc来实现转发和 ...

  3. 10. Condition 控制线程通信

    1. 是什么 ? 2. 示例 package com.gf.demo09; import java.util.concurrent.locks.Condition; import java.util. ...

  4. HTTP与HTTPs的区别?

    简而言之:   HTTPS = HTTP + SSL HTTP 的 URL 以 http:// 开头,而 HTTPS 的 URL 以 https:// 开头 HTTP 是不安全的,而 HTTPS 是安 ...

  5. js 判断数组中是否有某值

    function arrHasValue(v, arr) { var output = false; for (var i in arr) { if (v == arr[i]) { output = ...

  6. Android图片的Base64编码与解码

    Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法. Base64编码是从二进制到字符的过程,可用于在HTTP环境下传递较 ...

  7. C# RichTextBox 制作文本编辑器

    本文利用一个简单的小例子[文本编辑器],讲解RichTextBox的用法,仅供学习分享使用,如有不足之处,还请指正. Windows窗体中的RichTextBox控件用于显示,输入和操作格式化的文本, ...

  8. Windows服务器防火墙配置规范

    本文属于一篇内部规范文档,整理的初衷是为了规范.统一集团的Windows服务器(仅仅SQL Server数据库服务器)防火墙设置,仅仅供内部其它同事设置Windows防火墙时作为参考的文档资料.如有不 ...

  9. django静态模版使用

    第一步:在app目录下建立static文件夹,将CSS文件.js文件放到static文件夹下 第二步:TEMPLATES = [ { 'BACKEND': 'django.template.backe ...

  10. python创建列表和向列表添加元素方法

    今天的学习内容是python中的列表的相关内容. 一.创建列表 1.创建一个普通列表 >>> tabulation1 = ['大圣','天蓬','卷帘'] >>> ...