最近看到《设计之禅》的装饰器模式,特用C++实现了一遍,发现有些有意思的东西需要探究一下。
UML类图:
一. C++实现
#include <stdio.h> /// Base class Component { public: virtual ~Component(){} virtual int operate() = 0; }; /// ConcreteComponent class ConcreteComponent: public Component { public: ConcreteComponent() { } virtual ~ConcreteComponent() { printf("ConcreteComponent Destroy %#04x\n", this); } int operate() { printf("ConcreteComponent operate\n"); return 0; } }; /// Decorator class Decorator: public Component { public: virtual ~Decorator() { printf("Decorator destroy:%#04x base:%#04x\n", this, m_component); delete m_component; m_component = NULL; } protected: Component* m_component; }; /// ConcreteDecoratorA class ConcreteDecoratorA: public Decorator { public: explicit ConcreteDecoratorA(Component *ins) { m_component = ins; } ~ConcreteDecoratorA() { printf("ConcreteDecoratorA destroy:%#04x\n", this); } int operate() { int ret = m_component->operate(); printf("ConcreteDecoratorA operate\n"); return ret; } }; /// ConcreteDecoratorB class ConcreteDecoratorB: public Decorator { public: explicit ConcreteDecoratorB(Component *ins) { m_component = ins; } ~ConcreteDecoratorB() { printf("ConcreteDecoratorB destroy:%#04x\n", this); } int operate() { int ret = m_component->operate(); printf("ConcreteDecoratorB operate\n"); return ret; } }; // 检测指针是否释放 Component *p = NULL, *q = NULL, *h = NULL; /** * main */ int main(int argc, char **argv) { Component *component = new ConcreteComponent(); p = component; component = new ConcreteDecoratorA(component); q = component; component = new ConcreteDecoratorB(component); h = component; component->operate(); printf("Concrete:%#04x Concrete1:%#04x Concrete2:%#04x\n\n", p, q, h); // 内存是否泄露? delete component; component = NULL; return 0; }
装饰器模式提供比继承更有弹性的扩展方案,缺点产生了大量包装类,业务逻辑比较复杂。
上图实现是调用了三次new,却只delete一次,是否会发生内存泄露?
先看结果:
ConcreteComponent operate ConcreteDecoratorA operate ConcreteDecoratorB operate Concrete:0x21d9010 Concrete1:0x21d9030 Concrete2:0x21d9050 ConcreteDecoratorB destroy:0x21d9050 Decorator destroy:0x21d9050 base:0x21d9030 ConcreteDecoratorA destroy:0x21d9030 Decorator destroy:0x21d9030 base:0x21d9010 ConcreteComponent Destroy 0x21d9010
分析:在析构ConcreteDecoratorB后,会再析构父类Decorator,但此次的Decorator已被构造函数替换成ConcreteDecoratorA,则析构ConcreteDecoratorA,同理再析构ConcreteComponent。通过Componenet成员变量达到析构了所有堆变量,实在是高!
二. java IO
Java IO提供很多实用的工具类,各种read(), readLine() 调用,典型的装饰器模式。
FileInputStream fis = new FileInputStream("~/test.txt"); BufferedInputStream bis = new BufferedInputStream(fis); bis.read(b, off, len);
源码跟踪:
BufferedInputStream::read(b, off, len);
getInIfOpen().read(b, off, len);
InputStream::read(b, off, len);
BufferedInputStream利用缓冲输入改善行为,底层调用FileInputStream的read(),而FileInputStream调用InputStream的read()。
相关推荐
54-Spring设计模式之装饰器模式1
装饰模式 PPT 前端 javascript 讲解了装饰模式在前端的运用,举例说明,ppt内的代码连起来可执行
本文实例讲述了PHP设计模式之装饰器模式定义与用法。分享给大家供大家参考,具体如下: 什么是装饰器模式 作为一种结构型模式, 装饰器(Decorator)模式就是对一个已有结构增加”装饰”. 适配器模式, 是为现在有结构...
实际上Java提供的工具包中,IO相关工具就普遍大量使用了装饰器模式,例如充当装饰功能的IO类如BufferedInputStream等,又被称为高级流,通常将基本流作为高级流构造器的参数传入,将其作为高级流的一个关联对象,...
本文实例讲述了PHP设计模式之装饰器模式。分享给大家供大家参考,具体如下: 装饰器模式又叫装饰者模式。装饰模式是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也...
本文实例讲述了PHP设计模式之装饰器模式定义与用法。分享给大家供大家参考,具体如下: 装饰器模式: 如果已有对象的部分内容或功能性发生改变,但是不需要修改原始对象的结构或不使用继承,动态的扩展一个对象的...
c++设计模式-结构型模式-装饰器模式;QT工程;c++简单源码; 装饰器(Decorator)模式的定义:指在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式,它属于对象结构型模式。
ios平台中通过最简单的代码讲解装饰器模式,可在博客http://blog.sina.com.cn/s/blog_161d504630102wxis.html中查看简单解释
主要为大家详细介绍了java设计模式之装饰器模式Decorator,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
java常用设计模式-装饰器模式
控制访问,装饰器设计的四个名词,装饰器模式与代理模式的区别,
装饰器模式,设计模式.
装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。 这种模式创建了一个装饰类,用来包装原有的类,并在...
结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。 行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、...
NULL 博文链接:https://alaric.iteye.com/blog/1911949
结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。 行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、...
设计模式主要分为三大类: 1.创建型模式:工厂模式、抽象工厂模式、单例模式、建造者模式、原型模式。 2.结构型模式:适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式。 4.行为型模式:...