Headfirst设计模式的C++实现——装饰者模式(Decorater)
Beverage.h
#ifndef BEVERAGE_H_INCLUDED
#define BEVERAGE_H_INCLUDED #include <string> class Beverage
{
public:
Beverage( std::string description = "Unknown Beverage" ) : m_description ( description ) {}
virtual std::string getDescription() { return m_description; }
virtual double cost() = ;
private:
std::string m_description;
}; #endif // BEVERAGE_H_INCLUDED
CondimentDecorator.h
#ifndef CONDIMENTDECORATOR_H_INCLUDED
#define CONDIMENTDECORATOR_H_INCLUDED #include <string>
#include "Beverage.h" class CondimentDecorator : public Beverage
{
public:
virtual std::string getDescription() = ;
}; #endif // CONDIMENTDECORATOR_H_INCLUDED
HouseBlend.h
#ifndef HOUSEBLEND_H_INCLUDED
#define HOUSEBLEND_H_INCLUDED #include "Beverage.h" class HouseBlend : public Beverage
{
public:
HouseBlend () : Beverage( "House Blend Coffee" ) {}
double cost() { return .; }
}; #endif // HOUSEBLEND_H_INCLUDED
Mocha.h
#ifndef MOCHA_H_INCLUDED
#define MOCHA_H_INCLUDED #include "CondimentDecorator.h" class Mocha : public CondimentDecorator
{
public:
Mocha ( Beverage * p_beverage ) : m_p_beverage ( p_beverage ) {}
std::string getDescription() { return m_p_beverage->getDescription() + ", Mocha"; }
double cost() { return . + m_p_beverage->cost(); }
private:
Beverage *m_p_beverage;
}; #endif // MOCHA_H_INCLUDED
main.cpp
#include <iostream>
#include "HouseBlend.h"
#include "Mocha.h"
int main()
{
HouseBlend house_blend;
std::cout << house_blend.getDescription() << ": " << house_blend.cost() << std::endl; Mocha mocha_house_blend( &house_blend );
std::cout << mocha_house_blend.getDescription() << ": " << mocha_house_blend.cost() << std::endl; Mocha mocha_mocha_house_blend( &mocha_house_blend );
std::cout << mocha_mocha_house_blend.getDescription() << ": " << mocha_mocha_house_blend.cost() << std::endl; return ;
}
一点个人理解:
起初对于为什么Mocha类要从CondimentDecorator类继承也就是CondimentDecorator类存在的意义感到疑惑,并做了一次尝试:跳过CondimentDecorator类,让Mocha类直接从Beverage类继承,发现效果是一样的。那为什么还要有CondimentDecorator类的存在呢?
原书上有这么一段解释:
“所有的调料装饰着都必须重新实现getDescription()方法。稍后我们会解释为什么......”
"我们希望叙述不只是描述饮料,而是完整的连调料都描述出来......"
我推测作者的意思是说通过CondimentDecorator类,并且把getDescription方法设置为纯虚函数就可以强制让所有调料类实现此方法。如果不通过getDescription类,那么调料类就可以不实现此方法从而不符合需求。
Headfirst设计模式的C++实现——装饰者模式(Decorater)的更多相关文章
- headfirst设计模式(3)—装饰者模式
序 好久没写设计模式了,自从写了两篇之后,就放弃治疗了,主要还是工作太忙了啊(借口,都是借口),过完年以后一直填坑,填了好几个月,总算是稳定下来了,可以打打酱油了. 为什么又重新开始写设计模式呢?学习 ...
- HeadFirst设计模式读书笔记(3)-装饰者模式(Decorator Pattern)
装饰者模式:动态地将责任附件到对象上.若要扩展功能,装饰者提东了比继承更有弹性的替代方案. 装饰者和被装饰对象有相同的超类型 你可以用一个或者多个装饰者包装一个对象. 既然装饰者和被装饰对象有相同的超 ...
- 设计模式(八)装饰器模式Decorator(结构型)
设计模式(八)装饰器模式Decorator(结构型) 1. 概述 若你从事过面向对象开发,实现给一个类或对象增加行为,使用继承机制,这是所有面向对象语言的一个基本特性.如果已经存在的一个类缺少某些方法 ...
- php设计模式课程---7、装饰器模式如何使用
php设计模式课程---7.装饰器模式如何使用 一.总结 一句话总结: 装饰器的核心是获取了文章类整个类,而不是获取了文章内容,有了这个文章类,我想给你加多少装饰就给你加多少装饰(将文章这个类封装进去 ...
- 大型Java进阶专题(八)设计模式之适配器模式、装饰者模式和观察者模式
前言 今天开始我们专题的第八课了.本章节将介绍:三个设计模式,适配器模式.装饰者模式和观察者模式.通过学习适配器模式,可以优雅的解决代码功能的兼容问题.另外有重构需求的人群一定需要掌握装饰者模式. ...
- 【设计模式 - 9】之装饰者模式(Decorator)
1 模式简介 装饰者模式允许向一个现有的对象添加新的功能,同时又不改变其结构. 装饰者模式的思路是用"调料"对象将原始对象进行层层包裹,同时其属性.动作层层传递,达到最终 ...
- C#设计模式(11)——装饰者模式
1.装饰者模式介绍 装饰者顾名思义就是对一个类添加一些额外的装饰(功能).我们想给一个对象添加一些额外的功能又不改变对象内方法的签名怎么做呢?最常用的方法就是继承了,子类继承父类,然后重写父类的方法. ...
- 《大话设计模式》c++实现 装饰者模式
一.UML图 介绍 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创 ...
- 设计模式(九)装饰者模式(Decorator Pattern)
一.引言 在软件开发中,我们经常想要对一类对象添加不同的功能,例如要给手机添加贴膜,手机挂件,手机外壳等,如果此时利用继承来实现的话,就需要定义无数的类,如StickerPhone(贴膜是手机类).A ...
随机推荐
- 归并排序,递归法,C语言实现。
利用归并排序法对序列排序的示意图(递归法): 一.算法分析:利用递归的分治方法:1.将原序列细分,直到成为单个元素:2.在将分割后的序列一层一层地按顺序合并,完成排序.细分通过不断深入递归完成,合并通 ...
- XML与XHTML
什么是XML XML的基本格式 XML的定义文档 HTML5的文档定义 XHTML1.0的文档定义 XHTML1.0标记格式 12.1 什么是XML XML中文翻译为可扩展标记语言,顾名思义,它比HT ...
- thinkphp3.2.3 版本使用redis缓存的时候无法使用认证
我在使用thinkphp3.2.3的时候 发现如果是使用redis缓存 设置了认证的redis能连接成功 却无法 set 操作 ,检查发现是没有认证导致的 $redis->auth这一步没有, ...
- redis缓存技术
初学redis缓存技术,如果文章写得不好还请谅解 应用环境:win7 实现环境:cmd,eclipse redis缓存技术的特点就在于高效,因为目前涉及的数据量逐渐增多,在对于数据的存储上面和sql以 ...
- jQuery获取Select选中的Text和Value,根据Value值动态添加属性
语法解释:1. $("#select_id").change(function(){//code...}); //为Select添加事件,当选择其中一项时触发2. var chec ...
- Linux select TCP并发服务器与客户端编程
介绍:运行在ubuntu linux系统,需要先打开一个终端运行服务端代码,这时,可以打开多个终端同时运行多个客户端代码(注意客户端数目要小于MAX_FD);在客户端输入数据后回车,可以看见服务器收到 ...
- cocos2d-x jsb 防止触摸事件传递
在游戏中要实现消息弹窗,让用户点击确认,其他区域产生遮罩,阻挡下层的事件被点击到,这是个很常用的功能,在cocos2d-x中,可以通过为layer添加事件代理来实现: pDirector->ge ...
- 系统数据文件和信息之附加组ID
4.2BSD引入了附加组ID(supplementary group ID)的概念.我们不仅可以属于口令文件记录项中组ID所对应的组,也可属于多达16个另外的组.文件访问权限检查相应被修改为:不仅将进 ...
- Kafka 0.8: 多日志文件夹机制
kafka 0.7.2 中对log.dir的定义如下: log.dir none Specifies the root directory in which all log data is kept. ...
- 玩转Android之Picasso使用详详详详详详解,从入门到源码剖析!!!!
Picasso是Squareup公司出的一款图片加载框架,能够解决我们在Android开发中加载图片时遇到的诸多问题,比如OOM,图片错位等,问题主要集中在加载图片列表时,因为单张图片加载谁都会写.如 ...