文章目录

  • 一、基本知识
    • 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. 集团年终总结的几点体会
  2. Python命令行补全设置
  3. RocketMQ 4.5.1 双主双从异步复制环境搭建
  4. Tungsten Fabric SDN — Orchestrator 集成部署模式 — with Kubernetes
  5. leetcode算法题--Can I Win
  6. 【学术相关】热议:寒门硕士要不要继续读博士?
  7. informix和mysql的区别_DB2与Informix区别比较
  8. Java基础学习总结(97)——合格的Java的架构师需要具备的技术知识
  9. EntityFramework6.X 之 Operation
  10. 关于自定义任务(Tasks)的心得(转载)
  11. 算法知识点——(3)监督学习——逻辑回归与线性回归
  12. linux操作系统入门教学
  13. 论文写作—如何添加图注、公式、表注的序号,自动编号,交叉引用方式
  14. [python-opencv]滑动验证码打码
  15. 数字化转型时代,我们为什么越来越需要数据库云管平台?
  16. c++面试常见题·Part 3 TCP/IP多线程编程设计模式Linux基操等
  17. 使用restormer网络做2022年中兴捧月图像去噪
  18. 深入理解AQS--jdk层面管程实现【管程详解的补充】
  19. 剑未佩妥,出门已是江湖!聊聊2019学习和工作
  20. 函数求导及求微分的基本公式

热门文章

  1. FMS3 服务器集群虚拟服务器配置入门
  2. uwsgi+python+flask+nginx服务器部署
  3. C / C++ 软件项目的目录结构
  4. 解决安装ROS 时rosdep update 问题(time out)
  5. 【Linux】一步一步学Linux——ip命令(183)
  6. android edittext seterror,EditText之setError方法一二
  7. 【HDU 1276】士兵队列训练问题(两个队列模拟)
  8. 学习笔记-----C++模板类中友元函数重载输出运算符时提示无法解析的外部符号解决方案
  9. java系统反应慢怎么解决_为什么反应慢的Java程序员更容易成功
  10. 1007 素数对猜想 (20 分)(c语言)