简单理解常用设计模式(四)装饰模式

设计模式C++实现(11)——装饰模式 软件领域中的设计模式为开发人员提供了一种使用专家设计经验的有效途径。设计模式中运用了面向对象编程语言的重要特性:封装、继承、多态,真正领悟设计模式的精髓是可能一个漫长的过程,需要大量实践经验的积累。最近看设计模式的书,对于每个模式,用C++写了个小例子,加深一下理解。主要参考《大 阅读详情

下面说一个笔者理解了蛮久的模式,笔者基础仅一般,所以理解有些慢。各位如果和笔者相似,请debug代码一步步刨开理解。

现在有这样一个场景,类似qq秀(女生的话理解成暖暖,嘿嘿),用来换装穿衣,文字显示即可,简单代码实现,怎么做呢?

学生党并且基础不好的可能是这样:写一个persion类,属性包括姓名,方法有穿衣服,穿裤子,穿鞋子,方法实现就是打印这几个字,然后show方法用来打印人名,最后在main方法new Persion对象,对象调用穿着方法和show方法即可。

这样编写的代码属于死代码,假如要新增穿帽子方法就得修改源码的类,(三)文章里笔者写了开闭原则,意思是可以扩展但不能修改源码,上述写法就犯了这个错。

普通开发者,没有学习过设计模式的,可能这样写:抽象一个服装类接口,内有show方法,具体修饰类实现接口,最后写一个Perison类用于显示人名。

UML如下:


这样做是符合了开闭原则,但在调用时候每个具体装饰类的对象要各自调用自己的show方法,例如原书案例调用方式如下:


这样做不好,百度有一些理由大家可以搜搜,笔者就认为代码重复不好看,一个作用相同的方法干嘛调用三次呢。

所以下面就是前辈们搞出的装饰模式:动态的给一个对象添加额外的职责(功能,方法)

UML大致如下:


调用类如下:

package com.gcc.decoratorModel;
/**
 * 装饰者与被装饰者拥有共同的超类,继承的目的是继承类型,而不是行为
 */
public class TestDecorator {

	public static void main(String[] args) {
		Persion persion = new Persion("张三");
		Persion cpersion = new DecoratorClothes(persion);
		Persion ppersion = new DecoratorPants(cpersion);
		Persion spersion=new DecoratorShoes(ppersion);
		spersion.show();
	}
	
}

Persion类如下:

package com.gcc.decoratorModel;
/**
 * 定义被装饰者
 */
public class Persion {

	public Persion() {
		super();
	}

	public Persion(String name) {
		System.out.print(name);
	}

	public void show(){};
	
}

装饰类如下:

package com.gcc.decoratorModel;
/**
 *定义装饰者
 */
public class Decorator extends Persion {

	private Persion persion;

	public Decorator() {
		super();
	}

	public Decorator(Persion persion) {
		//super();//可以注解掉,也可以带上,因为再父类的构造方法没有操作,不影响结果
		this.persion = persion;
	}

	@Override
	public void show() {
		persion.show();
	}

	
	
}

具体装饰类如下:

package com.gcc.decoratorModel;

public class DecoratorClothes extends Decorator {

	public DecoratorClothes() {
		super();
	}
	//super()最近的一个父类,super相当于是指向当前对象的父类,super(参数),调用父类中的某一个构造函数。
	public DecoratorClothes(Persion persion) {
		super(persion);
	}
	
	/**
	 * 装饰动作
	 */
	@Override
	public void show() {
		super.show();
		wearClothes();
	}

	private void wearClothes() {
		System.out.print(" "+"穿衣服");
	}
	
}
package com.gcc.decoratorModel;

public class DecoratorPants extends Decorator {

	public DecoratorPants() {
		super();
	}

	public DecoratorPants(Persion persion) {
		super(persion);
	}
	
	@Override
	public void show() {
		super.show();
		wearPants();
	}

	private void wearPants() {
		System.out.print(" "+"穿裤子");
	}
	
}
package com.gcc.decoratorModel;

public class DecoratorShoes extends Decorator {

	public DecoratorShoes() {
		super();
	}

	public DecoratorShoes(Persion persion) {
		super(persion);
	}
	
	@Override
	public void show() {
		super.show();
		wearShoes();
	}

	private void wearShoes() {
		System.out.print(" "+"穿鞋子");
	}
	
}

输出结果如下:

张三 穿衣服 穿裤子 穿鞋子

这里说明下执行过程,原案例是c++的,笔者翻译成了java,笔者习惯是从main方法往上追溯,去理解代码。

首先测试类new了Person对象,debug可以看到代码执行到Person类的构造方法;

然后测试类new了具体的装饰类DecoratorClothes对象并传递Person类型参数,debug看到代码进入DecoratorClothes的构造方法,内部又调用父类构造方法,即Decorator的构造方法,得到的Person对象(注:此对象也可以是Person的子类类型)赋值给类的成员变量,同时提供由成员变量调用的show方法。

接着测试类new了具体的装饰类DecoratorPants对象并传递Person类型参数,此参数是DecoratorClothes对象向上转型到Person得到的,接着步骤和上述一样。

第三次装饰行为和第二次雷同。

最后执行show方法,这时有意思的东西来了,debug执行顺序是:

1:DecoratorShoes的show方法,执行第一行super.show();

2:Decorator的show方法,执行第一行persion.show();

3:DecoratorPants的show方法,执行第一行super.show();

4:Decorator的show方法,执行第一行persion.show();

5:DecoratorClothes的show方法,执行第一行super.show();

6:Decorator的show方法,执行第一行persion.show();

7:DecoratorClothes的wearClothes方法

8:Decorator的show方法,执行最后的"}"

9:DecoratorPants的wearPants方法

10:Decorator的show方法,执行最后的"}"

11:DecoratorShoes的wearShoes方法

12:结束

笔者的基础一般,如果不深究,装饰模式已经说明完毕,通过重写装饰类的show方法,并在方法内执行需要附加的方法,完成动态的装饰效果。

如果深究,笔者有两处不太理解:

一是执行顺序,先new的对象是DecoratorClothes,为什么测试类执行show方法先调用的却是DecoratorShoes的show方法?最后调用顺序却又按照了new对象的顺序又是为什么?笔者粗略猜测是堆栈的原因,但具体要请教各位geek了。

二是测试类的new对象方式像是套用在一起,最后new得到的对象只执行了一次show方法却能分别执行三个具体装饰类的show方法,这是为什么,不太理解原因,是java的哪个特性做到的?多态?和是不是单例有关吗?





【重温设计模式】装饰模式及其Java示例 在我们的编程世界中,有一种设计模式叫做装饰模式,它以一种独特的方式赋予了代码更多的灵活性。装饰模式是一种结构型设计模式,它允许我们在运行时动态地为对象添加新的行为。这就像是我们在装饰一个房间时,可以随意添加或更换装饰品,而不需要对整个房间进行改造。装饰模式的特点是,它可以保持代码的清晰和简洁,同时提供了强大的扩展性。这种模式在很多场景中都有应用,比如在Java的IO流中,我们就可以看到装饰模式的影子。@Override在上面的Java代码示例中,我们定义了一个基类OneMore和一个装饰器类。 阅读详情

相关推荐

SAP 屏幕增强:客户商主数据屏幕增强(KNA1、KNB1、KNVV)

本文介绍了SAP系统中针对客户主数据(KNA1、KNB1、KNVV)进行屏幕增强的具体实现方法。主要内容包括:1)在SPRO配置中创建新条目;2)通过SE80创建函数组和程序(LZKNA1TOP等);3)设置子屏幕9001并添加自定义结构字段;4)利用BADI(CUSTOMER_ADD_DATA等)实现数据交互逻辑。文章分别详细说明了针对客户主数据的一般数据(KNA1)、公司代码数据(KNB1)和销售数据(KNVV)三类不同数据的增强配置步骤,包括函数模块创建、屏幕设置和BADI方法调用等关键技术点。

SAP ABAP开发技能记录分享 1617

设计模式练习(9)——装饰模式

装饰模式 一、题目:简单的手机(SimplePhone)在接收到来电的时候,会发出声音来提醒主人,而现在我们需要为该手机添加一项功能,在接收来电的时候,除了有声音,还能产生震动(JarPhone),还可以得到更加高级的手机(ComplexPhone),来电时,它不仅能够发生,产生震动,而且有灯光闪烁提示,使用装饰模式来模拟手机功能的升级过程,要求绘制类图形编程模拟实现。 (1)给出装饰模式等结构视

秘密基地 6996

stm32学习笔记-启动文件

1、配置栈 Stack_Size EQU 0x00000400 AREA STACK, NOINIT, READWRITE, ALIGN=3 Stack_Mem SPACE Stack_Size __initial_sp EQU:相当于C中的define,定义Stack_Size = 0x00000400。 AREA: 指...

某风吾起的博客 4529

设计模式——装饰模式

**题目:**简单的手机(SimplePhone)在接收到来电的时候,会发出声音来提醒主人,而现在手机添加一项功能,在接收来电的时候,除了有声音还能产生振动(JarPhone);还可以得到更加高级的手机(ComplexPhone),来电时它不仅能够发声,产生振动,而且有灯光闪烁提示。现用装饰模式来模拟手机功能的升级过程,要求绘制类图并编程模拟实现。 类图: 代码部分: 1、 package simplePhone; /** * 抽象手机构件类:抽象构件类 * @author 9986 * */ p

Cici$的博客 2507

Rope DFM一键整合包AI脸部替换教程:使用DeepFaceLab模型实现专业级视频和直播脸部替换

在AI脸部替换工具中,Rope凭借其出色的自动遮罩处理拔得头筹,结合DFM模型中的DFL XSeg遮罩处理,效果更是提升了一个台阶。因为在训练模型时,它已经通过大量的侧脸图片进行训练,达到了单张图片无法企及的效果。然而,想要通过DeepFaceLab获得专业级的效果,不仅难度大,时间成本也相当高,训练模型也是个不小的挑战。举个简单的例子,使用图片脸部替换时,如果佩戴眼镜,脸部替换后的可能会显得很假。另外,在视频中,比如歌手演唱时,话筒遮挡住脸部,这种场景也可以通过遮罩训练后的模型来处理,呈现出更逼真的效果。

m0_72580657的博客 8162

吃透 AM32 无人机电调:从源码架构到工作原理的全方位解析(附实践指南)(中)

介绍了三相电机控制中的SVPWM算法实现及保护机制设计。SVPWM部分详细解析了电压矢量扇区判断、占空比计算和过调制保护,通过限制占空比范围(0-100%)防止电机失控,并提供了完整的代码实现。保护模块则重点分析了过流、过压/欠压、过温三种保护机制,采用分级处理策略(硬保护停机/软保护降功率)确保系统安全。此外,文章还介绍了参数管理模块在STM32 Flash中的存储方案,包括参数定义、数据结构和读写操作,为电机控制系统提供了完整的解决方案。

bother3000的博客 1389

Java23种设计模式之装饰者模式

描述:动态的给对象添加一些额外的属性或行为。相比于使用继承,装饰者模式更加灵活。也就是如果想对已经存在的对象进行装饰,那么就定义一个类,在类中对已经有的对象进行功能的增强或添加另外的行为,这个类就叫装饰者类,被修饰的类叫被装饰者类,是已经存在有的功能。在装饰者类之间又可以互相装饰。 装饰装饰,听起名知其意:用土话说,就是给自己打扮下,使其比原来的样子好看下(小编的见解哈)。    要实现...

wang_zqiang的专栏 208

汽车OTA自动化测试解决方案

目前OTA远程升级技术已成为众多汽车制造商的标配。由于OTA升级可能会带来潜在的风险(特别是包含ECU固件更新的FOTA升级),针对OTA系统的测试过程就尤为重要。

东舟技术的博客 7760

装饰你我,成全大家——装饰模式

一、引言 装饰模式是什么?为什么有装饰模式?装饰模式怎么实现? 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。 装饰模式就是用来给一个已有的类添加额外的功能。 二、实现方式 我们先来看一个需求: 简单的手机(SimplePhone)在接收来电的时候会发出声音来提醒主人;现在要将...

laowang__的博客 1012

SAP Group Reporting入门指南(8)--业务操作

关于资产负债表类的匹配,系统预设了SGR01和SGR02两个方法,主要区别在于数据的来源范围,SGR01取自ACDOCA和ACDOCU,如果是0F类型的就会直接显示日记账分录(期间是000的除外,这类凭证是年结结转的,系统不再跨年追溯),如果是其他类型就显示合并分录。这里是我觉得SAP还需要优化的地方。基于ICMR的抵消任务中通常将抵销差异细分为交易差异、货币换算差异和其他差异,这在基于重分类抵消任务是无法实现的,基于重分类抵消只知道一个差异总额,很难从合并抵消凭证看出差异的来源,也没有审计线索可言。

bflyfish的博客 276

XCP实战系列介绍09-基于Vehicle Spy进行XCP测量步骤详解

详细介绍如何使用Vehicle Spy进行XCP测量

initiallizer的博客 1393

装饰模式

装饰模式 设计模式java

HH 599

DSP篇--C6678功能调试系列之SPI调试

SPI传输数据分为线上直接收发和通过EDMA的数据传输两种。第一种是直接将数据放在线上(SPIDAT1),在寄存器(SPIBUF)中写入命令实现数据的收发;第二种需要配置EDMA,将数据buffer直接作为EDMA的数据源进行传输,其需要配置的参数和中断与EDMA一致。

nanke_yh的博客 1259

设计模式——装饰模式(Decorator)

要想正确理解设计模式,首先必须明确它是为了解决什么问题而提出来的。 设计模式学习笔记 ——Shulin 转载请注明出处:http://blog.youkuaiyun.com/zhshulin 1、概念         装饰模式又名包装(Wrapper)模式。装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案。         但是纯粹的装饰模式很难找到,大多数的装饰模式的实现

在路上 5万+

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

设计模式——装饰模式详解

装饰模式动态地给一个对象添加一些额外的功能,相对于继承的方式,更加灵活。 装饰模式经常被误认为是代理模式。装饰模式是以对客户透明的方式扩展对象的功能,是继承关系的一个替代方案。而代理模式则是给一个对象提供一个代理对象,并由代理对象来控制原有对象的引用。 前者重在增加功能,后者重在对代理对象施加控制,不是对对象本身功能的增强。...

关于Android开发的一些技术点总结 ╮( ̄▽ ̄”)╭ 1万+

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

简易理解设计模式之:装饰模式——穿衣服经典案例

介绍: 装饰模式属于结构型模式。它动态地给一个对象添加额外的职责,就增加功能来说,装饰模式比生成子类更加灵活。 类图: 装饰模式UML类图.png Component(抽象组件):接口或者抽象类,被装饰的最原始的对象。 ConcreteComponent(具体组件):实现抽象组件的接口。 Decorator(抽象装饰角色):一般是抽象类,持有一个被装饰者的引用,用来调用被装饰者的方...

TwcatL 1115

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

戏说设计模式--装饰模式

概述:作为ios常用设计模式之一,它是个啥?希望这篇文章能给你你一些启发。

java_grandpa的博客 1626

【设计模式】装饰(器)模式 透明装饰模式与半透明装饰模式

装饰模式摘要 装饰模式是一种结构型设计模式,允许动态地为对象添加功能而不改变其结构或使用继承。它通过组合对象的方式扩展功能,比继承更灵活。该模式包含四个角色:抽象构件、具体构件、抽象装饰类和具体装饰类。典型应用场景包括Java I/O流系统、需要动态添加功能的系统以及替代多重继承的情况。以咖啡加料为例,装饰模式可以灵活组合各种配料而不需创建大量子类。代码实现时,装饰器类继承自同一抽象构件,并持有构件对象的引用,通过嵌套调用实现功能叠加。这种模式符合开闭原则,提高了系统的可扩展性和维护性。

weixin_44131922的博客 792

常用设计模式之装饰模式

装饰(包装)模式是一种对象功能增强模式。类图如下 该类图的是把装饰对象也抽取出一个独立接口。当然,我本人比较常用的是使用DecoratorA,DecoratorB的方式。而不是另外抽取出Decorator接口。功能增强技术有三种,1)继承 2)装饰 3)代理 比较容易跟装饰模式混淆的是继承,代理是另一种模式,在这里就不说了。 比较来说,装饰是比较灵活和方便的,至于为什么这么说,等一

dansam的专栏 490

装饰模式的理解和实践

装饰模式动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。

huaqianzkh的专栏 1470

设计模式 - 装饰模式

什么是装饰模式? 装饰模式又名包装(Wrapper)模式。装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案。 适用范围 动态地给一个对象添加一些额外的职责。就增加功能来说,Decorator模式相比生成子类更为灵活。不改变接口的前提下,增强所考虑的类的性能。 何时使用: 1)需要扩展一个类的功能,或给一个类增加附加责任。 2)需要动态的给一个对象增加功能,这些功能可以再动态地撤销。 3)需要增加一些基本功能的排列组合而产生的非常大量的功能,从而使继承变得 不现实。 角色构成

Circ 4475

常用设计模式 - 装饰模式

听小洪讲故事,学习模板方法模式

weixin_40948132的博客 437

Java设计模式-装饰模式

装饰模式是一种非常有用的设计模式,它可以动态地为对象添加新的功能,而不需要修改原有的代码。通过定义一个抽象的装饰器类和具体的装饰器类,我们可以非常方便地扩展对象的功能,以满足不同的业务需求。虽然装饰模式增加了代码的复杂性和运行时开销,但是它在许多情况下仍然是一种非常有效的解决方案。

小薯条的博客 703

设计模式(十)—— 装饰模式(定义、案例分析、特点、缺点)

文章目录前言正文一、定义二、情景假设三、情景分析四、模式结构及分析(一) 两种组合模式(二) 两种组合模式的总结(三) 模式分析(1) 模式特点(2) 模式缺点五、使用情景六、延申及拓展总结 前言 文章内容主要参考了刘伟主编的《设计模式(第2版)》,同时也结合了自己的一些思考和理解,希望能帮到大家。 本篇讲解装饰模式,和组合模式一样分成两种类型,一个是透明装饰模式,一个是不透明装饰模式,仔细观察的人可能会发现好像两个的类图有点相像,但是说实话两个思想却是相差很远,我个人觉得如果你是学会模式的内在思考方式

weixin_43905387的博客 3021

设计模式学习[5]---装饰模式

近期在给一个已有的功能拓展新功能时,基于原有的设计类图进行讨论。其中涉及到了装饰模式,因为书本很早已经看过一遍,所以谈及到这个名词的时候有点印象,只知道它是加功能用的,更细则的内容已经忘了。这篇博客就是对装饰模式的一个复习。装饰模式看书的时候看的挺快的,但是想用自己的话写出来,还是得好好想想。这篇博客对装饰模式做了一个自我理解的阐述,结合书中的例子进行分阶段设计,最后到代码的具体展现。收获尚可。

Edwinwzy的博客 1294

设计模式之装饰模式

装饰模式 装饰模式 Decorator Pattern 装饰模式是属于GoF23中设计模式中的一种,又叫装饰者模式,属于结构型模式的一种。 装饰模式的描述为:动态的给一个对象添加一些额外的功能,前提是不该百年原文件和使用继承来进行对象功能的扩展。 简单的来说,就是将对象进行加一层包裹的意思,比如我们所熟悉的Java IO流是一种通过继承抽象类扩展功能的装饰着模式的使用。 使用到装饰模式的情况,...

小青的博客 217
上一篇: 简单理解常用设计模式(三)常用设计原则
下一篇: 简单理解常用设计模式(五)代理模式
gcc_front
博客等级 码龄9年 16粉丝 98原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值