解析option设计模式

解析option设计模式

  • 一、背景
  • 二、应用demo
  • 三、Gin中的应用


一、背景

有时候一个函数会有很多参数,为了方便函数的使用,我们会给希望给一些参数设定默认值,调用时只需要传与默认值不同的参数即可。因此选项设计模式顾名思义,就是在构造一个复杂的对象时,能以可选参数(选项)的形式,传入构造对象的函数中,为结构体字段赋值。先直接说下它的应用:

  • 需要构造对象比较复杂,有较多的参数需要赋值
  • 有默认的参数项,然后其余部分的参数需要通过插拔的形式进行配置
  • 以后可能还会有新的参数不断加进来

二、应用demo

现在以一个具体的应用场景来解析下具体怎么构造一个options的设计模式,假如现在业务场景会构造一个配置对象,但是这个配置是有很多默认的配置,只有少部分需要更改。因此可以利用以下的options模式实现对应的业务场景。

type Config struct {param1  stringparam2  stringoption1 stringoption2 string
}// 声明一个函数类型的变量,用于传参
type Option func(config *Config)func InitConfig(opts ...Option) *Config {config := &Config{param1: "default1",param2: "default2",}for _, opt := range opts {opt(config)}return config
}func WithStringOption1(str string) Option {return func(config *Config) {config.option1 = str}
}func WithStringOption2(str string) Option {return func(config *Config) {config.option2 = str}
}func main() {config1 := InitConfig(WithStringOption1("option1"),WithStringOption2("option2"),)config2 := InitConfig(WithStringOption1("option1"),)fmt.Println(*config1)fmt.Println(*config2)
}
  • 代码中param1和param2则是默认配置的参数,option1和option2则是需要进行配置的参数。而最关键的则是通过函数式的变量,将不同的赋值操作统一,最终通过闭包赋值给对应构造对象。
type Option func(config *Config)

三、Gin中的应用

gin中最典型的应用options模式的就是在构建engine的时候。

  • New(opts …OptionFunc)
func New(opts ...OptionFunc) *Engine {debugPrintWARNINGNew()engine := &Engine{RouterGroup: RouterGroup{Handlers: nil,basePath: "/",root:     true,},FuncMap:                template.FuncMap{},RedirectTrailingSlash:  true,RedirectFixedPath:      false,HandleMethodNotAllowed: false,ForwardedByClientIP:    true,RemoteIPHeaders:        []string{"X-Forwarded-For", "X-Real-IP"},TrustedPlatform:        defaultPlatform,UseRawPath:             false,RemoveExtraSlash:       false,UnescapePathValues:     true,MaxMultipartMemory:     defaultMultipartMemory,trees:                  make(methodTrees, 0, 9),delims:                 render.Delims{Left: "{{", Right: "}}"},secureJSONPrefix:       "while(1);",trustedProxies:         []string{"0.0.0.0/0", "::/0"},trustedCIDRs:           defaultTrustedCIDRs,}engine.RouterGroup.engine = engineengine.pool.New = func() any {return engine.allocateContext(engine.maxParams)}return engine.With(opts...)
}

从代码中可以看出函数中构造了一大堆默认参数,然后在return时返回了engine.With(opts…),继续深入:

type OptionFunc func(*Engine)func (engine *Engine) With(opts ...OptionFunc) *Engine {for _, opt := range opts {opt(engine)}return engine
}

可以发现这里是通过With函数传入函数式参数实现了options模式。在 golang 的很多开源项目里面也用到了选项模式,比如 grpc 中的 rpc 方法就是采用选项模式设计的,除了必填的 rpc 参数外,还可以一些选项参数,grpc_retry 就是通过这个机制实现的,可以实现自动重试功能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/769752.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Redis 缓存穿透是什么?如何缓解缓存穿透?

缓存穿透是指在使用缓存技术时,恶意或无效的请求无法从缓存中获取到数据,从而直接落到底层存储系统(如数据库)上,导致频繁地查询底层存储系统,增加系统负载并降低性能。 缓存通常用于存储经常被请求的数据…

QB 系统配置模板

查询的时候,直接 在下面添加 一个字段就行! public function getDeatil(){$post $this->request->post();if(!isset($post[id])){return out(请传递活动的id);}$builder new Builder($this->getModel());$builder->setFilter([id > …

轨迹预测后处理之非极大值抑制(NMS)

非极大值抑制是图像处理里面的一种算法(比如边缘检测会使用到) 轨迹预测这里借鉴了其思想,比如说对于某个场景中的某辆车,我们使用模型预测 64 条轨迹或者更多,以很好地捕获多模态性,同时每条轨迹对应一个…

看似简单的SQL,实则就是简单

加班遇到一个SQL问题,本想把别人的SQL改下成SparkSQL,在YARN上运行,然而数据一直对不上。 原SQL ⚠️说明:a.id,b.id没有空的,数据1:1,b.name可能存在空的 select a.id,b.id,b.name from tab…

机器学习方法

机器学习是人工智能(AI)的一个分支,它使计算机系统能够从数据中学习并改进其性能,而无需进行明确的编程。机器学习的核心是开发算法,这些算法可以从大量数据中识别模式,并用这些模式来做出预测或决策&#…

MySQL数据库的备份

文章目录 MySQL数据库的备份MySQL备份方法完全备份物理备份备份 逻辑热备完全备份逻辑热备恢复恢复库恢复表 增量备份备份增量备份恢复基于位置进行恢复基于时间 MySQL数据库的备份 MySQL备份方法 物理备份: 物理备份涉及直接复制MySQL的数据文件和日志文件。这种…

Javascript中的严格模式 “use strict“

一、为什么使用严格模式? 在普通的 JavaScript 中,写错变量名会创建新的全局变量, 在严格模式中,写错变量名会抛出错误来提醒开发者 二、声明严格模式 通过在脚本或函数的开头添加 “use strict”; 来声明严格模式。"use …

FANUC机器人某个轴编码器损坏时进行单轴零点标定的具体方法

FANUC机器人某个轴编码器损坏时进行单轴零点标定的具体方法 前提: FANUC机器人编码器或其线路有损坏,一般先将机器人移动至零点位置,编码器相关部件更换完毕后,直接进行零点标定即可。但是对于突发的状况,这种方法显然是不行的,比如在生产过程中突然发生碰撞导致编码器相…

暴雨讲堂:AI时代第五代英特尔CPU能做什么?

如果把科技圈比作娱乐圈,那么这两年的顶流一定是AI。2023年,世人见证了ChatGPT在全球范围内的大火,以生成式AI为代表的新一轮人工智能应用问世,改变了人工智能(AI)技术与应用的发展轨迹,并开始在…

Rancher(v2.6.3)——Rancher部署Nacos(单机版)

Rancher部署Nacos详细说明文档:https://gitee.com/WilliamWangmy/snail-knowledge/blob/master/Rancher/Rancher%E4%BD%BF%E7%94%A8%E6%96%87%E6%A1%A3.md#5rancher%E9%83%A8%E7%BD%B2nacos ps:如果觉得作者写的还行,能够满足您的需求&#x…

Android AIDL编译 程序包 .aidl 不存在

错误: 程序包 aidl 不存在 本文仅针对 AGP 8.0 android gradle plugin 以上 buildFeatures {aidl true } 在模块gradle android { }中增加. 详见: https://developer.android.com/build/releases/past-releases/agp-8-0-0-release-notes?hlzh-cn#default-changes

什么是进程

目录 一. 进程的概念二. 进程的组成三. 进程的特征四. 进程的状态与转换4.1 进程的状态4.2 进程状态的转换4.3 进程的组织方式 五. 进程控制5.1 进程控制5.2 进程创建 六. 进程之间的通信6.1 共享存储6.2 消息传递 \quad 一. 进程的概念 \quad 思考:操作系统是这些进程的管理者…

面试算法-110-课程表

题目 你这个学期必须选修 numCourses 门课程,记为 0 到 numCourses - 1 。 在选修某些课程之前需要一些先修课程。 先修课程按数组 prerequisites 给出,其中 prerequisites[i] [ai, bi] ,表示如果要学习课程 ai 则 必须 先学习课程 bi 。 …

【分布式websocket】表情怎么做?自制表情包和Unicode表情符号区别?表情编解码?【20期】

前言 表情包是聊天系统中一个比较常见的功能。常见的表情表分为两种是类型。 一种是Unicode表情,另外一种是图片表情。我们这篇文章两种都会涉及。 图片类表情包会涉及到编解码。不会将发送消息的图片的url地址也一并存入数据库中。 文章将会从表情分类。表情编解码…

添加网址到主页

基于localStorage的网址收藏夹-CSDN博客 为了通过安卓菜单添加网址到主页中,调试了几个小时,主要踩了几个坑。 1.localStorage 通过域名隔离,需要加载主页才能读写。 2.WebView 可以不显示,但是 JS 代码要放在 window.onload 中…

oracle19c单机版补丁19.3.0.0升级到19.22.0.0

oracle19c单机版补丁升级到19.22.0.0 一、获取补丁包 查看之前的版本 column product format A30 column version format A15 column version_full format A20 column status format A15 select * from product_component_version;二、备份opatch和数据库文件 su - oracle …

封装-练习

T2、以面向对象的思想,编写自定义类描述IT从业者。设定属性包括:姓名,年龄,技术方向,工作年限;方法包括:工作。 要求: 设置属性的私有访问权限,通过公有的get,set方法实现…

AD域的使用

一,部署共享网络驱动器 1/根目录下创建共享资料库-共享 2/用户-首选项-windows设置-网络驱动器-新建-映射驱动器 3/创建-共享路径-驱动器号(可固定/可随机) 4/更新策略:gpupdate /force 5/客户端查看 首先我们打开服务器此电脑 建立一个文件夹 右击文件夹点击属…

node整理学习(二)

模块化的概念 一、什么是模块化 模块化是指解决一个复杂问题时,自顶向下逐层把系统划分成若干模块的过程,模块是可组合、分解和更换的单元 二、模块化的好处 1、提高了代码的复用性 2、提高了代码的可维护性 3、可以实现按需加载 三、模块化规范 …

Avalonia(11.0.2)+.NET6 打包设置发布包的版本号

Avalonia11.0.2+.NET6 打包设置发布包的版本号 系统版本如何打包设置打包的版本号本文是对上一篇打包文章的补充,后台好多人私信我说打包的版本号如何设置,今天出个补充说明 Avalonia(11.0.2)+.NET6 打包运行到银河麒麟V10桌面系统 系统版本 如何打包 Avalonia(11.0.2)+.NET…