文章目录

  • 一、基本知识
    • 1.定义
    • 2.背景示例
    • 3.要点
  • 二、结构图
  • 三、实例说明
    • 1.普通代码
    • 2.装饰器模式代码

一、基本知识

在我第一次接触装饰器模式的时候,将它和责任链模式分不开,但是事实上它们是有区别的。

1.定义

动态地给一个对象增加一些额外的职责。就增加功能而言,装饰器模式比生产子类更为灵活。

2.背景示例

普通员工有销售奖金,累计奖金,部门经理除此之外还有团队奖金;后面可能会添加环比增长奖金,同时可能针对不同的职位产生不同的奖金组合。

3.要点

①通过采用组合而非继承的手法, 装饰器模式实现了在运行时动态扩展对象功能的能力,而且可以根据需要扩展多个功能。 避免了使用继承带来的“灵活性差”和“多子类衍生问题”。
②不是解决“多子类衍生问题”问题,而是解决“父类在多个方向上的扩展功能”问题。
③装饰器模式把一系列复杂的功能分散到每个装饰器当中,一般一个装饰器只实现一个功能,实现复用装饰器的功能。

二、结构图


对于本人来说,先看结构图的话,看不懂,都是先看示例代码,回头来再看结构图才看得懂。

三、实例说明

1.普通代码

#include<iostream>
#include<string>
using namespace std;// 普通员工有销售奖金,累计奖金,部门经理除此之外还有团队奖金;后面可能会添加环比增长奖金,同时可能产生不同的奖金组合;
// 销售奖金 = 当月销售额 * 4%
// 累计奖金 = 总的回款额 * 2%
// 部门奖金 = 团队销售额 * 1%
// 环比奖金 = (当月销售额-上月销售额) * 1%
// 销售后面的参数可能会调整
class Context {public:bool isMgr;string name;double groupsale;
};class Bonus {public:double CalcBonus(Context& ctx) {double bonus = 0.0;bonus += CalcMonthBonus(ctx);bonus += CalcSumBonus(ctx);if (ctx.isMgr) {bonus += CalcGroupBonus(ctx);}return bonus;}
private:double CalcMonthBonus(Context& ctx) {double bonus;/*一系列操作求销售奖金*/return bonus;}double CalcSumBonus(Context& ctx) {double bonus;/*一系列操作求总的回款额*/return bonus;}double CalcGroupBonus(Context& ctx) {double bonus;/*一系列操作求部门奖金*/return bonus;}
};int main() {Context ctx;// 设置 ctxBonus* bonus = new Bonus;bonus->CalcBonus(ctx);
}

2.装饰器模式代码

#include <iostream>
#include <string>
// 普通员工有销售奖金,累计奖金,部门经理除此之外还有团队奖金;后面可能会添加环比增长奖金,同时可能产生不同的奖金组合;
// 销售奖金 = 当月销售额 * 4%
// 累计奖金 = 总的回款额 * 0.2%
// 部门奖金 = 团队销售额 * 1%
// 环比奖金 = (当月销售额-上月销售额) * 1%
// 销售后面的参数可能会调整
using namespace std;
class Context {public:bool isMgr;string name;double groupsale;
};// 试着从职责出发,将职责抽象出来
class CalcBonus {
public:CalcBonus(CalcBonus * c = nullptr) : cc(c) {}virtual double Calc(Context &ctx) {return 0.0; // 基本工资}virtual ~CalcBonus() {}protected:CalcBonus* cc;//通过组合的方式
};class CalcMonthBonus : public CalcBonus {public:CalcMonthBonus(CalcBonus * c) : CalcBonus(c) {}virtual double Calc(Context &ctx) {double mbonus;/*求销售奖金操作*/return mbonus + cc->Calc(ctx);}
};class CalcSumBonus : public CalcBonus {public:CalcSumBonus(CalcBonus * c) : CalcBonus(c) {}virtual double Calc(Context &ctx) {double sbonus;/*求累计奖金操作*/return sbonus + cc->Calc(ctx);}
};class CalcGroupBonus : public CalcBonus {public:CalcGroupBonus(CalcBonus * c) : CalcBonus(c) {}virtual double Calc(Context &ctx) {double gbnonus;/*求部门奖金操作*/return gbnonus + cc->Calc(ctx);}
};class CalcCycleBonus : public CalcBonus {public:CalcCycleBonus(CalcBonus * c) : CalcBonus(c) {}virtual double Calc(Context &ctx) {double gbnonus ;/*求环比奖金操作*/return gbnonus + cc->Calc(ctx);}
};int main() {// 1. 普通员工Context ctx1;ctx1.isMgr = false;CalcBonus *base = new CalcBonus();CalcBonus *cb1 = new CalcSumBonus(base);CalcBonus *cb2 = new CalcMonthBonus(cb1);cb2->Calc(ctx1);//普通员工奖金只求销售奖金和部门奖金// 2. 部门经理Context ctx2;ctx2.isMgr = true;CalcBonus *cb3 = new CalcGroupBonus(cb2);cb3->Calc(ctx2);//部门奖金求销售、累计、部门奖金(环比奖金暂时没有设置)
}

可以看见,装饰器和责任链最大的区别是装饰器模式是最主要的是组合手法。而责任链是继承,然后每个子类的实例之间通过链表的方式低度耦合。装饰器之所以采用组合,是因为子类并不只是其中一个子类符合条件进行操作,而是多个子类都要操作,比如奖金,是通过多个子类求出来的。
而责任链模式通常是某个子类来解决这个事情,而链表是通常按照一定的先后顺序将子类低度耦合起来,有事件要处理时,通过链表遍历这个链表上的类,找到适合处理这个事情的类,这个往往是一个类就可以处理完。
当然,其实大部分可以用装饰器模式的很可能也可以用责任链模式,因为责任链模式只是往往一个事件只需要一个类处理,但是也可以是多个类都要处理,但是通过执行先后顺序将类用链表连接起来,就像是一个工厂的流水线一样。

设计模式——装饰器模式相关推荐

  1. Python设计模式-装饰器模式

    Python设计模式-装饰器模式 代码基于3.5.2,代码如下; #coding:utf-8 #装饰器模式class Beverage():name = ""price = 0.0 ...

  2. Go 设计模式 - 装饰器模式

    装饰模式使用对象组合的方式动态改变或增加对象行为.Go语言借助于匿名组合和非入侵式接口可以很方便实现装饰模式.使用匿名组合,在装饰器中不必显式定义转调原对象方法. 设计模式 装饰器模式 装饰器模式主要 ...

  3. Spring设计模式(装饰器模式)

    Spring设计模式(装饰器模式) 模式的定义: 装饰者模式定义: ​ 动态地为一个对象添加一些额外的职责,若要扩展一个对象的功能,装饰者提供了比继承更有弹性的替代方案. 模式的结构图 : 模式包含角 ...

  4. Java设计模式-装饰器模式 理论代码相结合

    继Java设计模式适配器模式后的装饰器模式来啦,让我们一起看看吧. 会了就当复习丫,不会来一起来看看吧. 很喜欢一句话:"八小时内谋生活,八小时外谋发展". 如果你也喜欢,让我们一 ...

  5. 设计模式--装饰器模式

    装饰器模式 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装.简单来说,装饰器模式就是 ...

  6. PHP设计模式——装饰器模式

    声明:本系列博客参考资料<大话设计模式>,作者程杰. 装饰器模式又叫装饰者模式.装饰模式是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能.它是通过创建一个包装对象,也就是装 ...

  7. 设计模式-装饰器模式 C++

    一.简介 1.什么是装饰器模式 装饰器模式是结构型设计模式. 装饰器是现有类的一个包装,可以在不修改现有类且不增加子类的情况下扩展现有类. [注]可以实现向一个现有对象添加新的功能,同时又不改变其结构 ...

  8. 设计模式---装饰器模式(C++实现)

    装饰器模式(Decorator Pattern)允许向一个现有对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创建了一个装饰类,用来包装原 ...

  9. C++设计模式 装饰器模式

    文章目录 1. 先验知识 2. 装饰器模式相关概念 3. 装饰器模式的应用 3.1 应用1: 给形状添加新的特征 不同形状加红 3.2 应用2: 给一个人穿不同的衣服 a 直接person类, 增加穿 ...

  10. 白话设计模式-装饰器模式的使用和意义

    装饰器模式展示 在学习设计模式的过程中,将自己对于设计模式的理解,以最简单,最白话的方式,分享给大家.个人觉得,对于设计模式的理解,需要将他从最抽象的理论里,真实的代入到实际的业务场景中,将会有最深刻 ...

最新文章

  1. google gn构建系统的介绍
  2. Mysql 源码安装
  3. 使用JDBC进行批处理
  4. [YTU]_2435 ( C++ 习题 输出日期时间--友元函数)
  5. Silverlight和WCF交互式的实战项目(更新完毕)
  6. IntelliJ IDEA for Mac在MacOS模式下的导航快捷键(Navigation Shortcut)
  7. java在什么环境变量_Java-环境变量
  8. 普通地图的六大要素_地理知识点总结之地图基本要素
  9. 高考学文的能报计算机吗,高考志愿填报时,文科生能申报计算机类相关专业吗?...
  10. CentOS install btsync
  11. 基于MATLAB的线性规划
  12. python中的snip用法_mac版截图软件Snip详细使用教程及常见问题
  13. 视频解码芯片GM7150BC功能CVBS转BT656/601低功耗替代TVP5150
  14. 学科分类号 计算机技术,学科分类号 0806.DOC
  15. 微信小程序实现图片翻转效果
  16. IGame游戏公司的故事
  17. 济南市全国计算机二级,山东省济南市2019年下半年全国计算机等级考试报名时间...
  18. 天气预报php xml接口,php调用天气预报接口
  19. 自动适配跳转电脑PC端和手机WAP端
  20. 计算机网络 路由器的端口ip,给路由器的一个接口上配置两个IP地址

热门文章

  1. 用Unity3D实现简单的井字棋小游戏
  2. 各种拿webshell
  3. [Python爬虫] 在Windows下安装PIP+Phantomjs+Selenium
  4. App设计灵感之十二组精美的房产App设计案例
  5. 树莓派搭建Django服务器通过远程访问
  6. 2017第八届蓝桥杯C/C++ B组省赛 —— 第一题:购物单
  7. 第六章 定积分的应用 —— 第一节 定积分的元素法
  8. 【ARM】ARM汇编程序设计(四) 选择结构
  9. 【Linux】一步一步学Linux——rmdir命令(22)
  10. mongodb 输出数组字段_JMeter之Groovy对MongoDB操作