当前位置: 首页 > news >正文

如何优雅的用golang封装配置项(Functional Options)

导读

最近要封装一个公共服务,涉及到配置项的地方总是找不到合理的方案,后来看了一下grpc在配置方面的封装,了解到原来是golang特有的Functional Options编程模式,今天分享给大家,希望你能用到,咱们直接来看代码

版本V1

alt 上面代码很容易,就是想初始化一下Server的配置选项,看起来好像没什么问题,其实问题非常多

  • 既然是初始化一些配置选项,那么当然是有的是必选项(Addr, Port),有的是可选项(Timeout,MaxConns),可选项不选的话还得给个默认值,显然这种方式是不满足的
  • 因为Server的属性都是公有方法,所以在外部任何地方都能修改属性,存在很严重的代码安全隐患
  • 上面Server和main函数虽然在同一个文件里面,其实Server是作为外部包使用的,下面的case都同理 既然上面无法满足咱们的需求,那么咱们就来修改一下

版本V2

既然配置项想要可选,那么咱们直接来个排列组合,调用不同的初始化方法即可只初始化自己想初始化的非必要选项 alt

  • Server的属性都是私有变量,的确是解决了包的属性被恶意篡改的行为,降低了代码风险
  • 但是排列组合太多,新增一个属性得新增指数级的方法,我上面的demo可选参数只有两个timeout和maxConns,但是如果有十几个可选参数,那么需要构造的初始化方法是非常多的
  • 一般情况下,对一个工具初始化都是统一的方法,这样处理的话初始化方法太多了,这一块的内容对使用者来说是不关心的,所以很不友好
  • 不想传的参数的默认值依然没有解决

版本V3

既然上面的例子封装的初始化方法太多,那么咱们就统一用一个方法来解决

alt
  • 这样做的确是解决了初始化方法太多的问题,但是太不灵活
  • 比如有100个可选参数,那而且你只想给最后一个可选参数赋值,但是前面99个你也得写,写的话具体写几? 我既然不关心前面99个可选参数,但是为什么还要写呢?这给人感觉就很奇怪

版本V4

咱们引入一个新的结构体Config,把必填的参数放在server里面,非必要的参数放在Congfig里面

alt
  • 解决了非必要参数可以有选择性的传一部分的问题,比如上面的case种只需要传Timeout
  • 也解决了不传的参数,能有默认值的问题,比如MaxConns不传的话 就是10
  • 但是如果只传必传的参数,那么在NewDefaultServer的时候,最后一个参数只能传nil,传nil的情况是不允许的,也是不友好的。
  • 用这种方式的话,Config的属性必须是公共变量,当然就有在运行的过程中属性被篡改的风险

版本V5

咱们来学一学java中的builder模式

alt
  • 其实就是在Server对象外部包了一层ServerBuilder,最后在ServerBuilder.Build()中返回了Server对象
  • 其实这个方法挺完美,满足了我们之前提的全部需求,但是问题在于,golang中的err处理,在这种方式中不是很好体现

版本V6

接下来咱们就看一看最后的终极解决方案 FUNCTIONAL OPTIONS模式

alt
  • 这个需要注意的是 type Option func(*Server)
  • 这个看起来比较整洁和优雅,对外的接口只有一个Create。
  • 相比于Builder模式,不需要引入一个Builder对象。
  • 对比配置化的模式,也不需要引入一个新的Config。

总结

Golang 由于语言本身的特性,不支持函数重载,函数式选项 的编程模式在一定程度上解决了其他语言需要通过函数重载解决的问题。 函数式选项 编程有以下优点:

  • 任意顺序传递参数
  • 支持默认值
  • 向后兼容性
  • 很容易维护和扩展

虽然 函数式选项 编程模式有很多优点,但是设计模式的存在都是为了弥补语言特性的缺陷的一种手段。它是为了解决代码扩展性的问题,往往是通过增加抽象牺牲了简单性,切勿过度使用。有些简单的配置,就不需要设计的这么通用了。

函数式选项模式的使用场景有哪些呢:

我们一般用来配置一些基础的服务配置,比如MySQL,Redis,Kafka的配置,很多可选参数,可以方便动态灵活的配置想要配置的参数。

本文由 mdnice 多平台发布

相关文章:

如何优雅的用golang封装配置项(Functional Options)

导读 最近要封装一个公共服务,涉及到配置项的地方总是找不到合理的方案,后来看了一下grpc在配置方面的封装,了解到原来是golang特有的Functional Options编程模式,今天分享给大家,希望你能用到,咱们直接来看…...

Springboot 使用thymeleaf 服务器无法加载resources中的静态资源异常处理

目录一、异常错误二、原因三、解决方法方法1. 将无法编译的静态资源放入可编译目录下方法2. 重新编译项目加载资源方法3. 修改pom.xml资源配置文件方法4. 不连接远程数据库启动,使用本地数据库一、异常错误 Springboot使用thymeleaf,并连接远程数据库启…...

服务端IOS订阅类型支付接入详细说明与注意事项

一、说明 由于本人在开发ios订阅类型支付接入的时候,遇到了很多坑,也查了不少资料,逐步完善了整个ios订阅支付服务端接入的功能,在这里写下总结和一些注意事项的记录,方便未来需要重新接入或者避免一些不必要的坑,这里…...

【剑指Offer】重建二叉树(递归+迭代)

重建二叉树一、递归法二、迭代法题目链接 题目描述: 输入某二叉树的前序遍历和中序遍历的结果,请构建该二叉树并返回其根节点。 假设输入的前序遍历和中序遍历的结果中都不含重复的数字。 示例 1: Input: preorder [3,9,20,15,7], inorder [9,3,15,…...

注解@Transactional 原理和常见的坑

这篇文章,会先讲述 Transactional 的 4 种不生效的 Case,然后再通过源码解读,分析 Transactional 的执行原理,以及部分 Case 不生效的真正原因1 项目准备下面是 DB 数据和 DB 操作接口:uidunameusex1张三女2陈恒男3楼仔…...

2023年全国最新交安安全员精选真题及答案4

百分百题库提供交安安全员考试试题、交安安全员考试预测题、交安安全员考试真题、交安安全员证考试题库等,提供在线做题刷题,在线模拟考试,助你考试轻松过关。 31.特种劳动防护用品必须具有“三证”,下列不属于“三证”的是&#…...

扬帆优配|半天翻倍,“蹭热点”翻车,前期“牛股”已近腰斩

周五上午,A股商场整体走低,多数职业板块和个股跌落,军工和核算机等板块逆势上涨,北向资金半天净卖出额约38亿元。 个股方面,昨夜公告被证监会立案查询的奥联电子股价再度大跌,盘中最贱价较近期高位已腰斩。…...

6 种易于上手的编程副业,每月赚取 1,000 多美元——没有废话

没有自由职业者或博客,也不需要前期费用。你们中的大多数人阅读这样的故事是希望其中的一些故事能帮助您赚更多的钱。好吧,几年前我还是同一个人。我希望尝试一些新的副业并赚点钱。其中一个视频建议我在网上写作,此后我写了很多技术文章。在…...

第九届蓝桥杯省赛 C++ B组 - 日志统计

✍个人博客:https://blog.csdn.net/Newin2020?spm1011.2415.3001.5343 📚专栏地址:蓝桥杯题解集合 📝原题地址:日志统计 📣专栏定位:为想参加蓝桥杯的小伙伴整理常考算法题解,祝大家…...

记一次服务器入侵事件的应急响应

0x01 事件背景 8月某日,客户官网被黑,需在特定时间内完成整改。为避免客户业务受到影响,实验室相关人员第一时间展开本次攻击事件的应急处理。 0x02 事件分析 网站源码被篡改,攻击者一定获取到了权限,那么接下来的思…...

作用域链查找机制(回顾)

全局 / 私有变量作用域的概念作用域链 scopeChain 的概念作用域链 scopeChain 的形成函数执行步骤作用域链查找机制 全局 / 私有变量 全局变量:在全局上下文EC(G)中的全局变量对象VO(G)中,存储的变量 私有变量:在函数执行形成的私有上下文EC(XXX)中的变…...

前端基础之HTML扫盲

文章目录一. 第一个HTML程序1. 创建一个HTML文件并运行2. HTML的基本结构二. HTML常见标签1. 注释标签2. 标题标签3. 段落标签4. 换行标签5. 格式化标签6. 图片标签7. 超链接标签8. 表格标签9. 列表标签10. 表单标签10.1 input标签10.2 select标签10.3 textarea标签11. 无语义标…...

大规模食品图像识别:T-PAMI 2023论文解读

美团基础研发平台视觉智能部与中科院计算所展开科研课题合作,共同构建大规模数据集Food2K,并提出渐进式区域增强网络用于食品图像识别,相关研究成果已发表于T-PAMI 2023。本文主要介绍了数据集特点、方法设计、性能对比,以及基于该…...

【java】Spring Cloud --Spring Cloud Alibaba RocketMq 异步通信实现

文章目录介绍RocketMQ特点Spring Cloud StreamWindow搭建部署RocketMQ下载启动NameServer服务启动Broker服务示例创建 RocketMQ 消息生产者创建 RocketMQ 消息消费者使用示例示例关联项目运行示例测试介绍 RocketMQ 是一款开源的分布式消息系统,基于高可用分布式集…...

玫瑰花变蚊子血,自动化无痕浏览器对比测试,新贵PlayWright Vs 老牌Selenium,基于Python3.10

也许每一个男子全都有过这样的两个女人,至少两个。娶了红玫瑰,久而久之,红的变了墙上的一抹蚊子血,白的还是床前明月光;娶了白玫瑰,白的便是衣服上沾的一粒饭黏子,红的却是心口上一颗朱砂痣。–…...

Spring Cloud入门篇 Hello World | Spring Cloud 1

一、专栏说明 Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如:服务发现/注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署。 本文主要介绍Spring C…...

C++学习笔记-数据结构

结构 是C中另一种用户自定义的可用数据类型,允许存储不同类型的数据项。 C/C 数组允许定义可存储相同类型数据项的变量,但是结构是 C 中另一种用户自定义的可用的数据类型,它允许存储不同类型的数据项。 结构用于表示一条记录,假…...

【C++的OpenCV】第五课-OpenCV图像常用操作(二):OpenCV的基本绘图、平滑滤波(模糊)处理

让我们继续一、OpenCV基本绘图1.1 OpenCV关于绘图的操作1.1.1 cv::Point()1.1.2 cv::Scalar()1.1.3 cv::line()画线1.1.4 cv::rectangle()画矩形1.1.5 cv::circle()画圆二、图像的平滑滤波处理2.1 概念2.2 OpenCV关于图像模糊的操作2.2.1 常用滤波器的分类2.2.2 各种滤波方法具…...

[SSD固态硬盘技术 19] 谁是数据的守护神? 盘内RAID1/RAID5图文详解_盘内数据冗余保护

版权声明: 付费作品,禁止转载前言提到冗余保护,最容易想到的就是RAID(Redundant Arrays of Independent Disks) , 独立冗余磁盘阵列。它是一种把多块独立的物理硬盘按不同方式组合形成一个硬盘组,以此提供比单个硬盘更高的存储性能…...

linux相对于windows环境为啥相对来说更加具有安全性

linux相对于windows环境为啥相对来说更加具有安全性 文章目录linux相对于windows环境为啥相对来说更加具有安全性前言一、linux不需要防病毒软件1.1Linux 桌面的恶意软件很少见1.2Linux 的软件安装更安全1.3Linux 保护自己免受恶意软件的侵害1.4杀毒效果存疑1.5Linux 良好的安全…...

如何在看板中体现优先级变化

在看板中有效体现优先级变化的关键措施包括:采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中,设置任务排序规则尤其重要,因为它让看板视觉上直观地体…...

基于服务器使用 apt 安装、配置 Nginx

🧾 一、查看可安装的 Nginx 版本 首先,你可以运行以下命令查看可用版本: apt-cache madison nginx-core输出示例: nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...

高频面试之3Zookeeper

高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个?3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制(过半机制&#xff0…...

自然语言处理——Transformer

自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效,它能挖掘数据中的时序信息以及语义信息,但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN,但是…...

Qemu arm操作系统开发环境

使用qemu虚拟arm硬件比较合适。 步骤如下: 安装qemu apt install qemu-system安装aarch64-none-elf-gcc 需要手动下载,下载地址:https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-x…...

根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的----NTFS源代码分析--重要

根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的 第一部分: 0: kd> g Breakpoint 9 hit Ntfs!ReadIndexBuffer: f7173886 55 push ebp 0: kd> kc # 00 Ntfs!ReadIndexBuffer 01 Ntfs!FindFirstIndexEntry 02 Ntfs!NtfsUpda…...

热门Chrome扩展程序存在明文传输风险,用户隐私安全受威胁

赛门铁克威胁猎手团队最新报告披露,数款拥有数百万活跃用户的Chrome扩展程序正在通过未加密的HTTP连接静默泄露用户敏感数据,严重威胁用户隐私安全。 知名扩展程序存在明文传输风险 尽管宣称提供安全浏览、数据分析或便捷界面等功能,但SEMR…...

WebRTC调研

WebRTC是什么,为什么,如何使用 WebRTC有什么优势 WebRTC Architecture Amazon KVS WebRTC 其它厂商WebRTC 海康门禁WebRTC 海康门禁其他界面整理 威视通WebRTC 局域网 Google浏览器 Microsoft Edge 公网 RTSP RTMP NVR ONVIF SIP SRT WebRTC协…...

算法250609 高精度

加法 #include<stdio.h> #include<iostream> #include<string.h> #include<math.h> #include<algorithm> using namespace std; char input1[205]; char input2[205]; int main(){while(scanf("%s%s",input1,input2)!EOF){int a[205]…...

java+webstock

maven依赖 <dependency><groupId>org.java-websocket</groupId><artifactId>Java-WebSocket</artifactId><version>1.3.5</version></dependency><dependency><groupId>org.apache.tomcat.websocket</groupId&…...