买了新房(毛坯房)需要装修,对新房进行装修并没有改变房子用于居住的本质,但它让房子变得更漂亮,更加满足居家的需求。在软件设计中,我们也可以用类似的技术对原有对象(新房)的功能进行扩展(装修),以获得更加符合用户需求的对象。这种技术在设计模式中称为装饰模式

装饰模式可以在不改变一个对象本身的基础上给对象增加额外的新行为,在现实生活中,这种情况比比皆是,如一张照片,可以不改变照片本身,给它增加一个相框,使得它具有防潮的功能,而且用户可以根据需要给它增加不同类型的相框,甚至可以在一个小相框的外面再套一个大相框

使用继承机制是给现有类添加功能的一种有效途径,通过继承一个现有类可以使得子类拥有自身方法的同时还拥有父类的方法,但是这种方法是静态的,用户不能控制增加行为的方式和时时机。例如我们要给奶茶加料,料有珍珠、椰果、葡萄干,如果使用继承我们就要把这三个类都要继承下来,此时类个数增多,且多继承本身就会存在一定的问题,使用不当会导致和预期不一样的结果

思想定义:动态地给以个对象增加一些额外的职责,就增加对象功能来说,装饰模式比生成子类实现更加灵活。其别名也可以称为包装器

优点

  1. 装饰模式可以提供比继承更多的灵活性
  2. 可以通过一种动态的方式来扩展一个对象的功能
  3. 具体构建类和具体装饰类可以独立变化,在添加新的具体构建类和具体装饰类时不需要修改原有代码,符合开闭原则

缺点

  1. 使用装饰模式进行系统设计时将产生很多小对象和具体装饰类,这些小对象和装饰类的产生增加系统的复杂度,加大学习与理解的难度
  2. 装饰模式比继承更加容易出错,排错也很困难,对于多次装饰的对象,调试时寻找错误可能需要逐级排查,较为烦琐

适用场景

  1. 在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责
  2. 需要动态地给一个对象添加功能,这些功能也可以动态地撤销

代码:给诺手添加狂徒和黑切

//抽象英雄
class AbstractHero
{public:virtual void ShowStatus() = 0;
public:int mHp;//血量int mMp;//蓝量int mAt;//攻击力int mDf;//防御力
};//具体英雄--诺手
class NuoShou : public AbstractHero
{public:NuoShou(){mHp = 500;mMp = 200;mAt = 100;mDf = 80;}virtual void ShowStatus(){cout << "血量:" << mHp << endl;cout << "蓝量:" << mMp << endl;cout << "攻击力:" << mAt << endl;cout << "防御力:" << mDf << endl;}
};//英雄添加装备,添加完后还是一个英雄,所以要继承 AbstractHero
class AbstractEquipment :public AbstractHero
{public:AbstractEquipment(AbstractHero* hero){this->hero = hero;}virtual void ShowStatus(){}
protected:AbstractHero* hero;
};//狂徒装备
class KuangtuEquipment : public AbstractEquipment
{public:KuangtuEquipment(AbstractHero* hero): AbstractEquipment(hero){}//增加额外的功能void AddKuangtu(){cout << "英雄购买了狂徒之后" << endl;this->mHp = this->hero->mHp + 1000;this->mMp = this->hero->mMp;this->mAt = this->hero->mAt;this->mDf = this->hero->mDf;}virtual void ShowStatus(){AddKuangtu();cout << "血量:" << mHp << endl;cout << "蓝量:" << mMp << endl;cout << "攻击力:" << mAt << endl;cout << "防御力:" << mDf << endl;}
};//黑切
class HeiqieEquipment : public AbstractEquipment
{public:HeiqieEquipment(AbstractHero* hero): AbstractEquipment(hero){}//增加额外的功能void AddHeiqie(){cout << "英雄购买了黑切之后" << endl;this->mHp = this->hero->mHp;this->mMp = this->hero->mMp;this->mAt = this->hero->mAt + 55;this->mDf = this->hero->mDf;}virtual void ShowStatus(){AddHeiqie();cout << "血量:" << mHp << endl;cout << "蓝量:" << mMp << endl;cout << "攻击力:" << mAt << endl;cout << "防御力:" << mDf << endl;}
};

测试:

void test()
{AbstractHero* hero = new NuoShou();cout << "英雄初始属性" << endl;hero->ShowStatus();cout << endl;hero = new KuangtuEquipment(hero);hero->ShowStatus();cout << endl;hero = new HeiqieEquipment(hero);hero->ShowStatus();
}

截图:

设计模式 C++装饰模式相关推荐

  1. 设计模式之装饰模式20170726

    结构型设计模式之装饰模式: 一.含义 动态地给一个对象添加一些额外的职责.就增加功能来说,装饰模式相比生成子类更为灵活. 通俗来讲,装饰模式是对类的功能进行加强或减弱. 二.代码说明 1.主要有两个角 ...

  2. java设计模式之装饰模式_Java中的装饰器设计模式

    java设计模式之装饰模式 装饰器设计模式允许在运行时将附加职责或行为动态附加到对象. 它是一种结构模式,利用聚合来组合这些行为. 在本教程中,我们将学习实现装饰器模式. UML图: 让我们从装饰器模 ...

  3. 大话设计模式之装饰模式(python实现)

    大话设计模式之装饰模式 使用场景 定义 装饰模式结构图 python实现装饰模式 代码结构图 优点 使用场景 建造过程不稳定,不确定.把所需的功能按照正确的顺序串联起来进行控制. 新加入的东西仅仅是为 ...

  4. 设计模式之装饰模式详解(附应用举例实现)

    文章目录 1 装饰模式介绍 2 装饰模式详解 2.1 装饰模式结构 2.2 装饰模式实现 2.3 装饰模式应用举例 3 透明装饰模式和半透明装饰模式 1 装饰模式介绍 在生活中,我们往往会给图片增加一 ...

  5. 设计模式之 装饰模式

    设计模式之 装饰模式 概述: 装饰模式(Decorator Pattern) 又叫装饰者模式:装饰模式指的是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能.它是通过创建一个包装对象,也 ...

  6. 设计模式之装饰模式(Decorator)摘录

    23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于如何创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而 ...

  7. 设计模式之三 装饰模式

    1.场景模拟 这样让想起了老李,我跟老李是很要好的哥们,当然他不像我还是光棍,所以他不光有友情还有爱情了,不过,就在最近几天他们吵架啦,什么原因?就不多说啦,总之身为男人的老李还是决定主动认错挽回女方 ...

  8. 大话设计模式之装饰模式

    装饰模式 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 通过下列代码加深下理解 ...

  9. (C#)设计模式之装饰模式

    1.装饰模式 动态的给一个对象添加一些额外的职责,就添加功能来说,装饰模式比生成子类更加灵活.*装饰模式是为已有功能动态添加更多功能的一种方式.*装饰模式将原有类中的核心职责与装饰功能分离.简化了原有 ...

  10. JAVA设计模式之装饰模式

    在阎宏博士的<JAVA与模式>一书中开头是这样描述装饰(Decorator)模式的: 装饰模式又名包装(Wrapper)模式.装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替 ...

最新文章

  1. 让电影动漫统统变丝滑,480帧也毫无卡顿,交大博士生开源插帧软件DAIN
  2. robotframework常见问题解决汇总
  3. boost::intrusive::list_member_hook用法的测试程序
  4. LG新能源新设首席数字官 首任是英伟达前数据科学家
  5. getchar(关于键盘缓冲区)
  6. amqp rabbitmq_Spring AMQP RabbitMQ示例
  7. 线性模型第1讲:最小二乘法
  8. 【jiasuba】巧妙运用win键
  9. python实现机器学习算法——K均值聚类算法
  10. vue的UI框架之有赞移动端vant-ui
  11. python练习题:u2.1求三角形斜边长度
  12. 计算机网络整理(上)
  13. windows安装软件出现“command line option syntax error”错误
  14. sqli-labs简单安装
  15. 主成分分析时,如果矩阵秩亏,会发生什么后果?
  16. 剪视频一点都不难,多款超实用剪辑软件全方位评测!
  17. 同一个局域网下的两台电脑实现定时或者实时拷贝数据
  18. WeiXin组件Senpac(一)【环境搭建】【Senparc架构】
  19. Apache Hudi - 2 - 基础功能特性实践
  20. 某大学教务在线登录逆向

热门文章

  1. 力控数据写入mysQL_绝对干货,教你4分钟插入1000万条数据到mysql数据库表,快快进来...
  2. js ajax 访问java函数,将url分配给Java EE项目中的ajax(js)函数
  3. HPUX分析Crash Dump_q4pxdb vmunix
  4. chrome浏览器fitler中的XHR作用是什么
  5. matlab mcc 安装,matlab中安装mcc
  6. jupyter报错Invalid credentials
  7. 第四十三篇 面向对象进阶2
  8. [Swift通天遁地]二、表格表单-(14)实时调整表单元素的激活和失效
  9. Java学习笔记17(面向对象十:综合案例)
  10. Golang--defer的mi魂汤