第一节

前言

各位好,首先我要先恭喜下自己粉丝即将破百,也谢谢各位的捧场,不过也跟我自己的努力密不可分,我也要继续加油,输出更好的文章来回报大家,也希望大家多提建议,有问题我也会及时改进。争取早日跟上各位大佬的步伐。

今天讲解的是创建型设计模式第三篇—装饰者模式(也叫修饰者模式),同样我们通过模式的名字去看实现过程,所谓装饰,就是在本体原有功能的基础上加上修饰,但不能更改原有本体的结构,使得原本的类在原有的结构不变动的基础上增加更多的功能,来拥有更多的功能,这个不修改本体去完成扩展的方式,就叫装饰者模式。

第二节

装饰者模式

装饰者(Decorator)模式的定义:指在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式。大多情况下,扩展一个类的功能许多人会选择继承的方式。但是继承的耦合度比较高,随着需要扩展功能的增加,子类会变得越来越复杂和臃肿,装饰者模式使用组合关系来创建一个包装对象来包含真实对象(原有对象),并且在原有对象的结构体不变的前提下,增加额外的功能,这个就是装饰者的实现过程。

装饰者模式组成

1

抽象构件(Component)角色:定义一个抽象接口以规范准备接收附加责任的对象,就是扩展前对象的抽象。

2

具体构件(ConcreteComponent)角色:实现抽象构件,通过装饰角色为其添加一些职责,即需要装饰的原有对象本体。

3

抽象装饰(Decorator)角色:继承抽象构件,并包含具体构件的实例,可以通过其子类扩展具体构件的功能,即装饰原有对象的对象的抽象。

4

具体装饰(ConcreteDecorator)角色:实现抽象装饰的相关方法,并给具体构件对象添加附加的责任,具体的装饰者,扩展的功能其实还是具体装饰者做的。

场景举例

我们小区楼下有一个卖鸡蛋灌饼的大妈,他们家每天的生意都很好,需要吃个灌饼都需要排队,一个基础版的灌饼就是灌饼+榨菜+生菜,在灌饼原有基础上老板也推出了套餐A和套餐B和豪华版套餐,A套餐可以加一种食物、B套餐可以加两种食物,豪华版就是三种食物,食物分别是辣条、煎蛋、烤肠,我和我的朋友对食物的喜欢程度不同,我喜欢加烤肠,我的朋友家底比较厚,他喜欢豪华版套餐,但是仔细想想,其实我们吃的都还是个灌饼,但是老板在原有灌饼的基础上进行修饰,抽象出了三个修饰的灌饼套餐版本,具体的套餐内容由每个顾客决定,这个不修改本体但又给本体扩展的过程,使用的就是修饰者模式。

UML图

第三节

代码实现

1.创建抽象构建“灌饼”类

package com.yang.decorator;/** * @ClassName AbstractComponent * @Description 抽象构建角色灌饼 * @Author IT小白架构师之路 * @Date 2020/12/20 20:44 * @Version 1.0 **/publicinterfaceAbstractPancake{/**     * 灌饼可以吃     */publicvoideat();}

2.创建具体构件角色“鸡蛋灌饼类”

package com.yang.decorator;/** * @ClassName EggPancake * @Description 具体构件角色-鸡蛋灌饼 * @Author IT小白架构师之路 * @Date 2020/12/20 20:48 * @Version 1.0 **/publicclassEggPancakeimplementsAbstractPancake{@Overridepublicvoideat(){        System.out.println("鸡蛋灌饼本来有生菜、榨菜");    }}

3.创建装饰抽象角色类

package com.yang.decorator;/** * @ClassName DecoratorPancake * @Description 装饰抽象角色 装饰的鸡蛋灌饼的抽象 * @Author IT小白架构师之路 * @Date 2020/12/20 20:50 * @Version 1.0 **/publicclassDecoratorPancakeimplementsAbstractPancake{//成员对象引入具体构件角色,就是要修饰的对象private AbstractPancake abstractPancake;//构造赋值具体构件publicDecoratorPancake(AbstractPancake abstractPancake){this.abstractPancake = abstractPancake;    }@Overridepublicvoideat(){        abstractPancake.eat();    }}

4.创建具体装饰角色A和B“灌饼套餐A和B”

package com.yang.decorator;/** * @ClassName ConcreteDecoratorPakageOne * @Description 具体装饰者A套餐 * @Author IT小白架构师之路 * @Date 2020/12/20 20:53 * @Version 1.0 **/publicclassConcreteDecoratorAextendsDecoratorPancake{publicConcreteDecoratorA(AbstractPancake abstractPancake){super(abstractPancake);    }@Overridepublicvoideat(){        addOne();super.eat();    }/**     * 加一种吃的     */publicvoidaddOne(){        System.out.println("给鸡蛋灌饼增加了烤肠");    }}package com.yang.decorator;/** * @ClassName ConcreteDecoratorB * @Description 具体装饰者B套餐 * @Author IT小白架构师之路 * @Date 2020/12/20 20:57 * @Version 1.0 **/publicclassConcreteDecoratorBextendsDecoratorPancake{publicConcreteDecoratorB(AbstractPancake abstractPancake){super(abstractPancake);    }@Overridepublicvoideat(){        addTwo();super.eat();    }publicvoidaddTwo(){        System.out.println("灌饼增加了烤肠、辣条");    }}

5.创建客户端进行测试

package com.yang.decorator;/** * @ClassName Client * @Description 客户端 * @Author IT小白架构师之路 * @Date 2020/12/20 20:59 * @Version 1.0 **/publicclassClient{publicstaticvoidmain(String[] args){//生成具体构件        AbstractPancake abstractPancake = new EggPancake();//生成具体扩展构件A套餐        DecoratorPancake decoratorPancake = new ConcreteDecoratorA(abstractPancake);//调用原有的基础方法        decoratorPancake.eat();        System.out.println("-------------我是分割线------------------");//生成具体扩展构件B套餐        decoratorPancake = new ConcreteDecoratorB(abstractPancake);        decoratorPancake.eat();    }}

6.程序运行结果如下,在原有的类结构保持不变的情况下完成装饰,增加更多的功能

给鸡蛋灌饼增加了烤肠鸡蛋灌饼本来有生菜、榨菜-------------我是分割线------------------灌饼增加了烤肠、辣条鸡蛋灌饼本来有生菜、榨菜

第四节

装饰者模式的优缺点及适用场景

优点:

1.在原有对象结构不变的情况下完成功能扩展,比较灵活。

2.装饰类可以增加多个,使用不同的装饰类可以完成不同的功能扩展。

3.具体构件类与具体装饰类可以独立变化,可以根据需要增加新的具体构件和具体装饰类,原类库不需要改变。

缺点:

1.使用装饰者模式,当需要的装饰场景较多时,会产生大量的具体装饰类,会增加系统资源占用,可能会影响程序性能。

2.使用装饰模式虽然比继承更灵活,但是当对象被多次修饰时,当程序运行过程中出现问题,排错过程会变得更加复杂。

适用场景:

1.需要在不影响原有对象的情况下,动态、透明的给原有对象扩展功能内容场景时。

2.不能采用继承的方式对原有对象进行扩展时,可以使用装饰模式。

常用设计模式系列(十)—装饰者模式相关推荐

  1. 【Java设计模式系列】装饰器模式(Decorator Pattern)

    简介 一般有两种方式可以给一个类或对象新增行为: 继承 子类在拥有自身方法同时还拥有父类方法.但这种是静态的,用户无法控制增加行为的方式和时机. 关联 将一个类的对象嵌入另一个对象,由另一个对象决定是 ...

  2. 云计算设计模式(十)——守门员模式

    云计算设计模式(十)--守门员模式 通过使用充当客户端和应用程序或服务之间的代理,验证和进行消毒的请求,并将它们之间的请求和数据的专用主机实例保护的应用程序和服务.这可以提供一个额外的安全层,并限制了 ...

  3. php 规格,PHP 设计模式系列之 specification规格模式_PHP

    Plus.php left = $left; $this->right = $right; } /** * 返回两种规格的逻辑与评估 * * @param Item $item * * @ret ...

  4. 设计模式学习笔记——装饰(Decorator)模式

    设计模式学习笔记--装饰(Decorator)模式 @(设计模式)[设计模式, 装饰模式, decorator] 设计模式学习笔记装饰Decorator模式 基本介绍 装饰案例 类图 实现代码 Dis ...

  5. 设计模式系列——三个工厂模式(简单工厂模式,工厂方法模式,抽象工厂模式)...

    转自:http://www.cnblogs.com/stonehat/archive/2012/04/16/2451891.html 设计模式系列--三个工厂模式(简单工厂模式,工厂方法模式,抽象工厂 ...

  6. 设计模式之【装饰器模式】

    和表妹去喝奶茶 表妹:哥啊,我想喝奶茶. 我:走啊,去哪里喝? 表妹:走,我带你去,我经常去的那家,不但好喝,还可以自由搭配很多小料.我每次都是不同的搭配,换着喝,嘻嘻. 我:你倒是挺会喝的嘛~ 你看 ...

  7. 【设计模式系列20】解释器模式原理及其在JDK和Spring源码中的体现

    解释器模式原理及其在JDK源码中的体现 设计模式系列总览 前言 什么是解释器模式 终结符表达式和非终结符表达式 解释器模式示例 解释器模式角色 解释器模式在JDK和Spring源码中应用 解释器模式应 ...

  8. JavaScript设计模式系列四之外观模式(附案例源码)

    文章初衷 设计模式其实旨在解决语言本身存在的缺陷, 目前javaScript一些新的语法特性已经集成了一些设计模式的实现, 大家在写代码的时候,没必要为了用设计模式而去用设计模式, 那么我这边为什么还 ...

  9. C#设计模式之十二代理模式(Proxy Pattern)【结构型】

    一.引言 今天我们要讲[结构型]设计模式的第七个模式,也是"结构型"设计模式中的最后一个模式,该模式是[代理模式],英文名称是:Proxy Pattern.还是老套路,先从名字上来 ...

最新文章

  1. ASP.NET设置ie打印两法 (精)(转)
  2. 记录最近的一些遇到的前端面试题
  3. Android背景色渐变效果(shape,gradient) (转)
  4. 程序员除了上班,还可以怎么赚钱?
  5. 飞鸽传书为什么传书?
  6. java 数据抓取 动态获得cookies里变动的属性_@CookieValue获取Cookie信息,使用Servlet API作为入参,处理模型数据...
  7. prince和学生们侃侃而谈系列03
  8. wincap linux部署
  9. 转载蓝叠模拟器与android studio连接步骤
  10. 【LaTeX 教程】01. LaTeX 简介与安装
  11. Python之线程的同步互斥与死锁
  12. 超全面的JavaWeb笔记day01HTML等
  13. mysql 存储用户头像_node+vue用户头像处理上传并保存
  14. 关于js实现分页效果的简单代码
  15. 排序算法之冒泡排序及鸡尾酒排序
  16. 国内4A级户外广告企业一致选择的广告管理软件
  17. MapStruct - Consider defining a bean of type in your configuration.
  18. 【已解决】华硕ASUS PA279 与 MacBook Pro M1 外接type-c显示器显示无输入信号仅充电
  19. ASP.NET之ViewState对象
  20. 第八届蓝桥杯-第四题方格分割

热门文章

  1. Mysql中事务是什么?有什么用?
  2. 读《开放式文本信息抽取》赵军
  3. 微信分享链接不显示缩略图
  4. Requests库常用方法及参数介绍
  5. 查询指定数据库指定表的指定字段的SQL语句
  6. 若一头小母牛,从出生起第四个年头开始每年生一头母牛,按此规律,第n年时有多少头母牛?
  7. python:ocr图文识别(百度智能云API文字识别)
  8. altium 网口差分走线长度_Altium Design 中差分走线的设置
  9. 台式计算机如何判断电源损坏,台式电脑电源坏了的表现有哪些
  10. ISME:二型糖尿病患者中与牙周炎相关的龈下菌群