版权声明:本文为博主原创文章,未经博主同意不得转载。 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. Spring Bean的生命周期相关博客

    最近得面试题一直 问 Spring 得生命周期,鉴于自己还未阅读过源码 所以只能是自己 背一波了.属实不懂硬背得作用,但是无奈被各位面试官打败了.等以后有时间了 一定要阅读几遍spring的 源码 有 ...

  2. 回客科技 面试的 实现ioc 容器用到的技术,简述BeanFactory的实现原理,大搜车面试的 spring 怎么实现的依赖注入(DI)

    前言:这几天的面试,感觉自己对spring 的整个掌握还是很薄弱.所以需要继续加强. 这里说明一下spring的这几个面试题,但是实际的感觉还是不对的,这种问题我认为需要真正读了spring的源码后说 ...

  3. tomcat端口修改以及jvm启动参数设置

    1.端口更改:找到config目录下server.xml文件 如下 <?xml version='1.0' encoding='utf-8'?> <!-- Licensed to t ...

  4. Android Service解析

    Android Service是一个可以在后台执行长时间运行操作而不提供用户界面的应用组件,它分为两种工作状态,一种是启动状态,主要用于执行后台计算:另一种是绑定状态,主要用于其他组件和Service ...

  5. 3.类和接口_EJ

    第13条: 使类和成员的可访问性最小化 良好的模块设计能隐藏其内部数据和其他实现细节,模块之间只通过它们的API进行通信.java语言提供了许多机制来协助隐藏信息.访问控制机制决定了类.接口和成员的可 ...

  6. 【Web前端】用CSS3实现弹幕

    初版 用css3来实现弹幕确实比较简单,只需要设置动画让弹幕从屏幕右侧移动到屏幕左侧即可,一开始是这样实现的 .danmu { position: fixed; left: %; animation: ...

  7. 28-30 js 文本全选

    要点:使用select(); 上代码: if (e.keyCode === 27){ document.getElementById('input').select() } //当点击键盘esc键时候 ...

  8. HTTP与HTTPs的区别?

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

  9. CSS使用position:sticky 实现粘性布局

    简介 前面写了一篇文章讲解了position常用的几个属性:<CSS 属性之 position讲解>一般都知道下面几个常用的: { position: static; position: ...

  10. vuejs-指令详解

    v-if v-if指令可以完全根据表达式的值在DOM中生成或移除一个元素.如果v-if表达式赋值为false,那么对应的元素就会从DOM中移除:否则,对应元素的一个克隆将被重新插入DOM中,代码如下: ...