博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
10.装饰模式--Decorator
阅读量:2392 次
发布时间:2019-05-10

本文共 2579 字,大约阅读时间需要 8 分钟。

原文地址:

Decorator模式:

Decorator模式动态的给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活。
在OO设计和开发过程,可能会经常遇到以下的情况:我们需要为一个已经定义好的类添加新的职责(操作),通常的情况我们会给定义一个新类继承自定义好的类,这样会带来一个问题,新加的代码通常加入了新的字段,新的方法或新的逻辑,从而增加了类的复杂度,而些新加入的东西仅仅是为了满足一些只在某种特定情况下才会执行的特殊行为的需要。通过继承的方式解决这样的情况还带来了系统的复杂性,因为继承的深度会变得很深。
而Decorator提供了一种给类增加职责的方法,不是通过继承实现的,而是通过组合,它把每个要装饰的功能放在单独的类中,并让这个类包装它所需要装饰的对象,因此,当需要执行特殊行为时,客户代码就可以在运行时根据需要有选择、按顺序的使用装饰功能包装对象了。

Decorator模式典型的结构图为:

 

在结构图中,ConcreteComponent和Decorator需要有同样的接口,因此ConcreteComponent和Decorator有着一个共同的父类。这里有人会问,让Decorator直接维护一个指向ConcreteComponent引用(指针)不就可以达到同样的效果,答案是肯定并且是否定的。肯定的是你可以通过这种方式实现,否定的是你不要用这种方式实现,因为通过这种方式你就只能为这个特定的ConcreteComponent提供修饰操作了,当有了一个新的ConcreteComponent你又要去新建一个Decorator来实现。但是通过结构图中的ConcreteComponent和Decorator有一个公共基类,就可以利用OO中多态的思想来实现只要是Component型别的对象都可以提供修饰操作的类,这种情况下你就算新建了100个Component型别的类ConcreteComponent,也都可以由Decorator一个类搞定。这也正是Decorator模式的关键和威力所在了。

当然如果你只用给Component型别类添加一种修饰,则Decorator这个基类就不是很必要了。

这里引用《大话设计模式》中给人做装饰为例子实现Decorator模式,下面是Decorator模式的实现代码:

//Decorator.h#ifndef _DECORATOR_H_#define _DECORATOR_H_// 人class Person{public: virtual ~Person(); virtual void Show();protected: Person();private:};// 美眉class Girl : public Person{public: Girl(); ~Girl(); void Show();protected:private:};// 装饰的基类class Decorator : public Person{public: Decorator(Person* com); virtual ~Decorator(); void Show();protected: Person* _com;private:};// 用T恤装饰的类class Tshirt : public Decorator{public: Tshirt(Person* com); ~Tshirt(); void Show(); void AddedBehavior();protected:private:};// 用裤子装饰的类class Trousers : public Decorator{public: Trousers(Person* com); ~Trousers(); void Show(); void AddedBehavior();protected:private:};#endif //~_DECORATOR_H_//Decorator.cpp#include "Decorator.h"#include 
Person::Person(){}Person::~Person(){}void Person::Show(){}Girl::Girl(){}Girl::~Girl(){}void Girl::Show(){ std::cout<<"Girl::Show...本来面目是个灰姑娘"<
_com = com;}Decorator::~Decorator(){ delete _com;}void Decorator::Show(){}Tshirt::Tshirt(Person* com):Decorator(com){}Tshirt::~Tshirt(){}void Tshirt::AddedBehavior(){ std::cout<<"Tshirt::AddedBehavior....穿T恤装饰"<
Show(); this->AddedBehavior();}Trousers::Trousers(Person* com): Decorator(com){}Trousers::~Trousers(){}void Trousers::AddedBehavior(){ std::cout<<"Trousers::AddedBehavior....穿裤子装饰"<
Show(); this->AddedBehavior();}//main.cpp#include "Decorator.h"#include
using namespace std;int main(int argc,char* argv[]){ // 一个美眉 Person* com = new Girl(); // T恤装饰她 Decorator* dec1 = new Tshirt(com); dec1->Show(); // 裤子装饰她 Decorator* dec2 = new Trousers(com); dec2->Show(); return 0;}

你可能感兴趣的文章
java基础| 多线程基础五:AQS详解
查看>>
java基础| 多线程基础六:Condition接口分析和ThreadLocal类解析
查看>>
java基础| 多线程基础七:JUC工具包中的工具类
查看>>
java基础| 多线程基础八:线程池及使用
查看>>
Centos7| 远程连接vncserver时输入账户密码后闪退
查看>>
java源码| HashMap源码分析
查看>>
JVM基础一| java se体系结构及jvm概述
查看>>
前端| js动态修改video标签视频不刷新的问题
查看>>
JVM基础二| 深入理解JVM内存对象
查看>>
IDEA| centos Unable to open debugger port(127.0.0.1:60157) socket closed
查看>>
JVM基础三| 深入理解垃圾回收及算法
查看>>
JVM基础四| 深入理解JVM执行子系统
查看>>
代码实现| springboot+mybatis+PageHelper实现Mysql数据分页
查看>>
代码规范| 面向对象六大基本原则
查看>>
IDEA| Error resolving template [index], template might not exist or might not be accessible by any
查看>>
力扣题解| 169. 多数元素
查看>>
力扣题解| 999. 可以被一步捕获的棋子数
查看>>
力扣题解| 225. 用队列实现栈
查看>>
力扣题解| 912. 排序数组
查看>>
力扣题解| 1160. 拼写单词
查看>>