Go中的函数选项模式(Functional Options Pattern)详解

 更新时间:2023年06月08日 08:23:13   作者:陈明勇  
在 Go 语言中,函数选项模式是一种优雅的设计模式,用于处理函数的可选参数,本文将对其进行讲解,准备好了吗,快跟随着本文一探究竟吧

前言

在日常开发中,有些函数可能需要接收许多参数,其中一些参数是必需的,而其他参数则是可选的。当函数参数过多时,函数会变得臃肿且难以理解。此外,如果在将来需要添加更多参数,就必须修改函数签名,这将影响到已有的调用代码。

而函数选项模式(functional options)的出现解决了这个问题,本文将对其进行讲解,准备好了吗?准备一杯你最喜欢的饮料或茶,随着本文一探究竟吧。

函数选项模式

什么是函数选项模式

Go 语言中,函数选项模式是一种优雅的设计模式,用于处理函数的可选参数。它提供了一种灵活的方式,允许用户在函数调用时传递一组可选参数,而不是依赖于固定数量和顺序的参数列表。

函数选项模式的好处

  • 易于使用:调用者可以选择性的设置函数参数,而不需要记住参数的顺序和类型;
  • 可读性强:函数选项模式的代码有着自文档化的特点,调用者能够直观地理解代码的功能;
  • 扩展性好:通过添加新的 Option 参数选项,函数可以方便地扩展功能,无需修改函数的签名;
  • 函数选项模式可以提供默认参数值,以减少参数传递的复杂性。

函数选项模式的实现

函数选项模式的实现一般包含以下几个部分:

  • 选项结构体:用于存储函数的配置参数
  • 选项函数类型:接收选项结构体参数的函数
  • 定义功能函数:接收 0 个或多个固定参数和可变的选项函数参数
  • 设置选项的函数:定义多个设置选项的函数,用于设置选项

代码示例:

type Message struct {
   // 标题、内容、信息类型
   title, message, messageType string

   // 账号
   account     string
   accountList []string

   // token
   token     string
   tokenList []string
}

type MessageOption func(*Message)

func NewMessage(title, message, messageType string, opts ...MessageOption) *Message {
   msg := &Message{
      title:       title,
      message:     message,
      messageType: messageType,
   }

   for _, opt := range opts {
      opt(msg)
   }

   return msg
}

func WithAccount(account string) MessageOption {
   return func(message *Message) {
      message.account = account
   }
}

func WithAccountList(accountList []string) MessageOption {
   return func(message *Message) {
      message.accountList = accountList
   }
}

func WithToken(token string) MessageOption {
   return func(message *Message) {
      message.token = token
   }
}

func WithTokenList(tokenList []string) MessageOption {
   return func(message *Message) {
      message.tokenList = tokenList
   }
}

func main() {
   // 单账号推送
   _ = NewMessage(
      "来自陈明勇的信息",
      "你好,我是陈明勇",
      "单账号推送",
      WithAccount("123456"),
   )

   // 多账号推送
   _ = NewMessage(
      "来自陈明勇的信息",
      "你好,我是陈明勇",
      "多账号推送",
      WithAccountList([]string{"123456", "654321"}),
   )
}

上述例子中,使用了函数选项模式来创建 Message 结构体,并根据消息类型配置不同消息的属性。

首先定义了 Message 结构体,其包含 7 个字段;

其次定义 MessageOptionm选项函数类型,用于接收 Message 参数的函数;

再次定义 NewMessage 函数,用于创建一个 Message 指针变量,在 NewMessage 函数中,固定参数包括 titlemessagemessageType,它们是必需的参数。然后,通过可选参数 opts ...MessageOption 来接收一系列的函数选项;

然后定义了四个选项函数:WithAccountWithAccountListWithTokenWithTokenList。这些选项函数分别用于设置被推送消息的账号、账号列表、令牌和令牌列表。

最后,在 main 函数中,展示了两种不同的用法。第一个示例是创建单账号推送的消息,通过调用 NewMessage 并传递相应的参数和选项函数(WithAccount)来配置消息。第二个示例是创建多账号推送的消息,同样通过调用 NewMessage 并使用不同的选项函数(WithAccountList)来配置消息。

这种使用函数选项模式的方式可以根据需要消息类型去配置消息的属性,使代码更具灵活性和可扩展性。

函数选项模式的缺点

前面提到了函数选项模式的优势(好处),但也必须承认它存在一些缺点。

  • 复杂性:函数选项模式引入了更多的类型和概念,需要更多的代码和逻辑来处理。这增加了代码的复杂性和理解的难度,尤其是对于初学者来说。
  • 可能存在错误的选项组合:由于函数选项模式允许在函数调用中指定多个选项,某些选项之间可能存在冲突或不兼容的情况。这可能导致意外的行为或错误的结果。
  • 不适用于所有情况:函数选项模式适用于有大量可选参数或者可配置选项的函数,但对于只有几个简单参数的函数,使用该模式可能过于复杂和冗余。在这种情况下,简单的命名参数可能更直观和易于使用。

小结

本文对 Go 函数选项模式(Functional Options Pattern)进行了详细介绍,并通过封装一个消息结构体的例子,展示了如何使用函数选项模式进行代码实现。

在合适的情况下,我们可以使用函数选项模式来封装一些功能,定制函数的行为,提高代码的可读性和可扩展性。

到此这篇关于Go中的函数选项模式(Functional Options Pattern)详解的文章就介绍到这了,更多相关Go函数选项模式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • GoFrame框架gset交差并补集使用实例

    GoFrame框架gset交差并补集使用实例

    这篇文章主要为大家介绍了GoFrame框架gset交差并补集使用实例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-06-06
  • golang time包的用法详解

    golang time包的用法详解

    这篇文章主要介绍了golang time包的用法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-04-04
  • 利用Go语言遍历目录下所有文件的示例代码

    利用Go语言遍历目录下所有文件的示例代码

    这篇文章主要介绍了如何使用 Go 语言遍历指定目录,递归地列出该目录及其所有子目录下的所有文件路径,并有详细的代码示例供大家参考,需要的朋友可以参考下
    2025-07-07
  • 详解go如何优雅的使用接口与继承

    详解go如何优雅的使用接口与继承

    Go语言中的接口和嵌套结构体是两种重要的代码设计方式,接口定义了一组方法签名,使得不同的类型能够以相同的方式进行交互,本文将给大家介绍go语言如何优雅的使用接口与继承,文中有详细的代码供大家参考,需要的朋友可以参考下
    2024-06-06
  • golang并发编程中Goroutine 协程的实现

    golang并发编程中Goroutine 协程的实现

    Go语言中的协程是一种轻量级线程,通过在函数前加go关键字来并发执行,具有动态栈、快速启动和低内存使用等特点,本文就来详细的介绍一下,感兴趣的可以了解一下
    2024-10-10
  • 一文搞懂Golang 时间和日期相关函数

    一文搞懂Golang 时间和日期相关函数

    这篇文章主要介绍了Golang 时间和日期相关函数,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-12-12
  • GoLang读取文件的10种方法实例

    GoLang读取文件的10种方法实例

    读取文件是所有编程语言中最常见的操作之一,下面这篇文章主要给大家介绍了关于GoLang读取文件的10种方法,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-06-06
  • 实用的Go语言开发工具及使用示例

    实用的Go语言开发工具及使用示例

    这篇文章主要为大家介绍了实用的Go语言开发工具及使用示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-06-06
  • Go并发编程sync.Cond的具体使用

    Go并发编程sync.Cond的具体使用

    Go 标准库提供 Cond 原语的目的是,为等待 / 通知场景下的并发问题提供支持,本文主要介绍了Go并发编程sync.Cond的具体使用,具有一定的参考价值,感兴趣的可以了解一下
    2022-05-05
  • Go Uber静态分析工具NilAway使用初体验

    Go Uber静态分析工具NilAway使用初体验

    这篇文章主要介绍了Go Uber静态分析工具NilAway使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2024-01-01

最新评论