Go和Java实现装饰器模式
Go和Java实现装饰器模式
我们通过人穿着打扮自己的实例来演示装饰器模式的用法。
1、装饰器模式
装饰器模式允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它
是作为现有的类的一个包装。
装饰器模式通过将对象包装在装饰器类中,以便动态地修改其行为。
这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。
-
意图:动态地给一个对象添加一些额外的职责。就增加功能来说,装饰器模式相比生成子类更为灵活。
-
主要解决:一般的,我们为了扩展一个类经常使用继承方式实现,由于继承为类引入静态特征,并且随着扩展
功能的增多,子类会很膨胀。
-
何时使用:在不想增加很多子类的情况下扩展类。
-
如何解决:将具体功能职责划分,同时继承装饰者模式。
-
关键代码:1、Component 类充当抽象角色,不应该具体实现。 2、修饰类引用和继承 Component 类,具
体扩展类重写父类方法。
-
应用实例:1、孙悟空有 72 变,当他变成"庙宇"后,他的根本还是一只猴子,但是他又有了庙宇的功能。 2、
不论一幅画有没有画框都可以挂在墙上,但是通常都是有画框的,并且实际上是画框被挂在墙上。在挂在墙上
之前,画可以被蒙上玻璃,装到框子里;这时画、玻璃和画框形成了一个物体。
-
优点:装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态
扩展一个实现类的功能。
-
缺点:多层装饰比较复杂。
-
使用场景:1、扩展一个类的功能。 2、动态增加功能,动态撤销。
-
注意事项:可代替继承。
-
装饰器模式包含以下几个核心角色:
抽象组件(Component):定义了原始对象和装饰器对象的公共接口或抽象类,可以是具体组件类的父类或
接口。
具体组件(Concrete Component):是被装饰的原始对象,它定义了需要添加新功能的对象。
抽象装饰器(Decorator):继承自抽象组件,它包含了一个抽象组件对象,并定义了与抽象组件相同的接
口,同时可以通过组合方式持有其他装饰器对象。
具体装饰器(Concrete Decorator):实现了抽象装饰器的接口,负责向抽象组件添加新的功能。具体装饰
器通常会在调用原始对象的方法之前或之后执行自己的操作。
-
适用性:
在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
处理那些可以撤消的职责。
当不能采用生成子类的方法进行扩充时。
装饰器模式通过嵌套包装多个装饰器对象,可以实现多层次的功能增强。每个具体装饰器类都可以选择性地增加新
的功能,同时保持对象接口的一致性。
2、Go实现装饰器模式
package decorator// ========== Person ==========
type Person interface {// 形象展示Show()
}
package decoratorimport "fmt"// ========== 服饰类 ==========
type Finery struct {
}func (finery *Finery) Show() {fmt.Println("穿着了如下衣服:")
}
package decorator// ========== FineryDecorator =========
type FineryDecorator interface {Decorate(Person)
}
package decoratorimport "fmt"// ========== Tshirt =========
type Tshirt struct {person Person
}func (tshirt *Tshirt) Decorate(person Person) {tshirt.person = person
}func (tshirt *Tshirt) Show() {tshirt.person.Show()fmt.Println("大T恤")
}
package decoratorimport "fmt"// ========== Trouser =========
type Trouser struct {person Person
}func (trouser *Trouser) Decorate(person Person) {trouser.person = person
}func (trouser *Trouser) Show() {trouser.person.Show()fmt.Println("阔腿裤")
}
package decoratorimport "fmt"// ========== Shoe =========
type Shoe struct {person Person
}func (shoe *Shoe) Decorate(person Person) {shoe.person = person
}func (shoe *Shoe) Show() {shoe.person.Show()fmt.Println("运动鞋")
}
package mainimport . "proj/decorator"func main() {person := &Finery{}tshirt := &Tshirt{}trouser := &Trouser{}shoe := Shoe{}tshirt.Decorate(person)trouser.Decorate(tshirt)shoe.Decorate(trouser)shoe.Show()
}
# 输出
穿着了如下衣服:
大T恤
阔腿裤
运动鞋
3、Java实现装饰器模式
package com.decorator;// ========== Person ==========
public interface Person {// 形象展示void show();
}
package com.decorator;// ========== 服饰类 ==========
public class Finery implements Person{@Overridepublic void show() {System.out.println("穿着了如下衣服:");}
}
package com.decorator;// ========== FineryDecorator =========
public class FineryDecorator implements Person{protected Person person;public void decorator(Person person){this.person = person;}@Overridepublic void show() {this.person.show();}
}
package com.decorator;// ========== Tshirt =========
public class Tshirt extends FineryDecorator{@Overridepublic void show() {super.show();System.out.println("大T恤");}
}
package com.decorator;// ========== Trouser =========
public class Trouser extends FineryDecorator {@Overridepublic void show() {super.show();System.out.println("阔腿裤");}}
package com.decorator;// ========== Shoe =========
public class Shoe extends FineryDecorator{@Overridepublic void show() {super.show();System.out.println("运动鞋");}
}
package com.decorator;public class Test {public static void main(String[] args) {Person person = new Finery();FineryDecorator fineryDecorator = new FineryDecorator();Tshirt tshirt = new Tshirt();Trouser trouser = new Trouser();Shoe shoe = new Shoe();fineryDecorator.decorator(person);tshirt.decorator(fineryDecorator);trouser.decorator(tshirt);shoe.decorator(trouser);shoe.show();}
}
# 输出
穿着了如下衣服:
大T恤
阔腿裤
运动鞋
相关文章:
Go和Java实现装饰器模式
Go和Java实现装饰器模式 我们通过人穿着打扮自己的实例来演示装饰器模式的用法。 1、装饰器模式 装饰器模式允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它 是作为现有的类的一个包装。 装饰器模式通过…...
Android中级——RemoteView
RemoteView RemoteView的应用NotificationWidgetPendingIntent RemoteViews内部机制模拟RemoteViews RemoteView的应用 Notification 如下开启一个系统的通知栏,点击后跳转到某网页 public class MainActivity extends AppCompatActivity {private static final …...
SpringBoot核心内容梳理
1.SpringBoot是什么? Spring Boot是一个基于Spring框架的快速开发应用程序的工具。它简化了Spring应用程序的创建和开发过程,使开发人员能够更快速地创建独立的、生产就绪的Spring应用程序。它采用了“约定优于配置”的原则,尽可能地减少开发人员需要进…...
Benchmarking Augmentation Methods for Learning Robust Navigation Agents 论文阅读
论文信息 题目:Benchmarking Augmentation Methods for Learning Robust Navigation Agents: the Winning Entry of the 2021 iGibson Challenge 作者:Naoki Yokoyama, Qian Luo 来源:arXiv 时间:2022 Abstract 深度强化学习和…...
面试题:HTTP Code码及应用场景分析
1xx 消息(临时响应) 属于临时相应,代表所发出的请求已经被接受,需要继续进行处理。只包含状态行和某些可选的响应头信息,并以空行结束。由于 HTTP/1.0 协议中没有定义任何 1xx 状态码,所以除非在某些试验条件下,服务器…...
The ‘kotlin-android-extensions‘ Gradle plugin is no longer supported.
Android使用kotlin开发,运行报错 The kotlin-android-extensions Gradle plugin is no longer supported. Please use this migration guide (https://goo.gle/kotlin-android-extensions-deprecation) to start working with View Binding (https://developer.an…...
vi 编辑器入门到高级
vi 编辑器的初级用法vi 编辑器的工作模式1. 命令模式2. 文本输入模式3. 状态行vi 工作模式切换存储缓冲区 vi 编辑器命令1. 启动 vi2. 文本输入3. 退出 vi4. 命令模式下的 光标移动5. 命令模式下的 文本修改6. 从 命令模式 进入 文本输入模式7. 搜索字符串8. vi 在线帮助文档 v…...
【大数据】Flink 详解(二):核心篇 Ⅰ
Flink 详解(二):核心篇 Ⅰ 14、Flink 的四大基石是什么? Flink 的四大基石分别是: Checkpoint(检查点)State(状态)Time(时间)Windowÿ…...
Day 75:通用BP神经网络 (2. 单层实现)
代码: package dl;import java.util.Arrays; import java.util.Random;/*** Ann layer.*/ public class AnnLayer {/*** The number of input.*/int numInput;/*** The number of output.*/int numOutput;/*** The learning rate.*/double learningRate;/*** The m…...
PHP序列化,反序列化
一.什么是序列化和反序列化 php类与对象 类是定义一系列属性和操作的模板,而对象,就是把属性进行实例化,完事交给类里面的方法,进行处理。 <?php class people{//定义类属性(类似变量),public 代表可…...
Android google admob Timeout for show call succeed 问题解决
项目场景: 项目中需要接入 google admob sdk 实现广告商业化 问题描述 在接入Institial ad 时,onAdLoaded 成功回调,但是onAdFailedToShowFullScreenContent 也回调了错误信息 “Timeout for show call succeed.” InterstitialAd.load(act…...
EFLFK——ELK日志分析系统+kafka+filebeat架构
环境准备 node1节点192.168.40.16elasticsearch2c/4Gnode2节点192.168.40.17elasticsearch2c/4GApache节点192.168.40.170logstash/Apache/kibana2c/4Gfilebeat节点192.168.40.20filebeat2c/4G https://blog.csdn.net/m0_57554344/article/details/132059066?spm1001.2014.30…...
C# MVC controller 上传附件及下载附件(笔记)
描述:Microsoft.AspNetCore.Http.IFormFileCollection 实现附件快速上传功能代码。 上传附件代码 [Route("myUploadFile")][HttpPost]public ActionResult MyUploadFile([FromForm] upLoadFile rfile){string newFileName Guid.NewGuid().ToString(&quo…...
安装element-plus报错:Conflicting peer dependency: eslint-plugin-vue@7.20.0
VSCode安装element-plus报错: D:\My Programs\app_demo>npm i element-plus npm ERR! code ERESOLVE npm ERR! ERESOLVE could not resolve npm ERR! npm ERR! While resolving: vue/eslint-config-standard6.1.0 npm ERR! Found: eslint-plugin-vue8.7.1 npm E…...
【操作系统】进程和线程对照解释
进程(Process)和线程(Thread)都是操作系统中用于执行任务的基本单位,但它们有着不同的特点和使用方式。 进程(Process): 进程是正在运行的程序的实例。一个程序在运行时会被操作系统…...
4用opencv玩转图像2
opencv绘制文字和几何图形 黑色底图 显示是一张黑色图片 使用opencv画圆形 #画一个圆 cv2.circle(imgblack_img,center(400,400),radius100,color(0,0,255),thickness10) 画实心圆 只需要把thickness-1。 cv2.circle(imgblack_img,center(500,600),radius50,color(0,0,255),t…...
Swagger的使用
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言1 .介绍2. 使用步骤完整的WebMvcConfiguration.java 3. 常用注解 前言 1 .介绍 Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RE…...
python高阶技巧
目录 设计模式 单例模式 具体用法 工厂模式 优点 闭包 案例 修改闭包外部变量 闭包优缺点 装饰器 装饰器原理 装饰器写法 递归 递归的调用过程 递归的优缺点 用递归计算阶乘 设计模式 含义:设计模式是一种编程套路,通过这种编程套路可…...
Linux和Windows安装MySQL服务
Linux和Windows安装MySQL服务 1 Linux安装MySQL服务1.1 安装1.2 服务端启动1.3 客户端连接 2 Windows安装MySQL服务2.1官网下载安装包(windows)并解压2.2 配置系统环境变量2.3 服务端启动(管理员DOS)2.4 客户端连接(管理员DOS) 3 修改密码4 Windows问题 1 Linux安装MySQL服务 …...
Vue3 第四节 自定义hook函数以及组合式API
1.自定义hook函数 2.toRef和toRefs 3.shallowRef和shallowReactive 4.readonly和shallowReadonly 5.toRaw和markRaw 6.customref 一.自定义hook函数 ① 本质是一个函数,把setup函数中使用的Composition API 进行了封装,类似于vue2.x中的mixin 自定义hook函数…...
SoftSPIB:支持任意位宽的软件模拟SPI库
1. SoftSPIB:面向非字节对齐SPI通信的软件实现方案1.1 问题起源:硬件SPI的固有局限性在嵌入式系统开发中,SPI(Serial Peripheral Interface)作为最常用的同步串行总线协议,其标准实现通常以8位(…...
Intel集成显卡加速PyTorch:从环境搭建到模型训练实战指南
1. 为什么选择Intel集成显卡加速PyTorch? 很多朋友刚接触深度学习时,第一反应都是"得买块N卡"。但你可能不知道,手头的Intel集成显卡也能跑PyTorch,而且效果还不错。我去年给团队配开发机时,就专门测试过Int…...
Windows窗口置顶3分钟快速上手指南:告别频繁切换的烦恼
Windows窗口置顶3分钟快速上手指南:告别频繁切换的烦恼 【免费下载链接】PinWin Pin any window to be always on top of the screen 项目地址: https://gitcode.com/gh_mirrors/pin/PinWin 你是否曾在处理多个窗口时感到手忙脚乱?当你在写代码时…...
oklog架构深度解析:如何实现无协调的分布式日志存储
oklog架构深度解析:如何实现无协调的分布式日志存储 【免费下载链接】oklog A distributed and cordination-free log management system 项目地址: https://gitcode.com/gh_mirrors/ok/oklog 在当今云原生和微服务架构盛行的时代,分布式日志管理…...
关于爬虫源影视资源设置
1.首先目前的omnibox的版本已更新到2.0.3版本,之前的配置会丢失,原本的资源都会无法使用,这里以新版本增加数据源,看完以下教程再下载脚本。 2.添加爬虫源,这里以猫眼资源为主测试: 增加脚本之后,点击保存即可! 复制以下脚本,修复改site_api即可,一般公用的资源都是正…...
解决Ubuntu中libc6-dev:i386依赖问题的完整指南
1. 理解libc6-dev:i386依赖问题的本质 当你正在愉快地使用Ubuntu系统,突然在执行sudo apt-get upgrade时遇到一堆红色错误提示,特别是看到"libc6-dev:i386 : 依赖: libc6:i386 ( 2.31-0ubuntu9.14) 但无法安装它"这样的报错,是不是…...
避坑指南:Java Robot类在Windows/Linux下的兼容性问题及解决方案
Java Robot类跨平台避坑实战:Windows与Linux环境差异全解析 当你第一次尝试用Java Robot类实现自动化测试脚本时,可能会惊讶地发现:在Windows上运行完美的代码,放到Linux服务器上却莫名其妙报错。这不是你的代码问题,而…...
无人机新手必看:Remote ID和ADS-B到底选哪个?从原理到实战全解析
无人机新手必看:Remote ID和ADS-B到底选哪个?从原理到实战全解析 刚入手的无人机在阳光下闪着金属光泽,充电时发出的细微电流声让人心跳加速——直到你发现说明书最后一页印着"需遵守Remote ID或ADS-B监管要求"。这两个陌生术语瞬…...
交付前批量人脸脱敏自动模糊的一点记录
客户给了一批线下沙龙现场图,两百三十张上下,要用于对外案例页,合同里写了人脸需做不可辨认处理。手工框选不现实,我这次用【批量图片面部识别自动模糊工具】走完整交付链,只记和排期、验收相关的点。输入支持拖文件夹…...
MelonLoader终极指南:7个步骤掌握Unity游戏模组加载器的完整教程
MelonLoader终极指南:7个步骤掌握Unity游戏模组加载器的完整教程 【免费下载链接】MelonLoader The Worlds First Universal Mod Loader for Unity Games compatible with both Il2Cpp and Mono 项目地址: https://gitcode.com/gh_mirrors/me/MelonLoader Me…...
