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函数选项模式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Go语言单线程运行也会有的并发问题解析

    Go语言单线程运行也会有的并发问题解析

    这篇文章主要为大家介绍了Go语言单线程运行的并发问题解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-12-12
  • Go语言学习教程之反射的示例详解

    Go语言学习教程之反射的示例详解

    这篇文章主要通过记录对reflect包的简单使用,来对反射有一定的了解。文中的示例代码讲解详细,对我们学习Go语言有一定帮助,需要的可以参考一下
    2022-09-09
  • 玩转Go命令行工具Cobra

    玩转Go命令行工具Cobra

    这篇文章主要介绍了玩转Go命令行工具Cobra,本文介绍了Cobra的最基本也是最常用的使用部分,但是Cobra仍然有很多优秀的操作值得我们学习,需要的朋友可以参考下
    2022-08-08
  • Go语言原子操作及互斥锁的区别

    Go语言原子操作及互斥锁的区别

    原子操作就是不可中断的操作,本文主要介绍了Go语言原子操作及互斥锁的区别,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-12-12
  • GO使用阿里云,解决go get下载项目慢或无法下载的情况

    GO使用阿里云,解决go get下载项目慢或无法下载的情况

    这篇文章主要介绍了GO使用阿里云,解决go get下载项目慢或无法下载的情况,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-01-01
  • Linux系统下Go语言开发环境搭建

    Linux系统下Go语言开发环境搭建

    这篇文章主要介绍了Linux系统下Go开发环境搭建,需要的朋友可以参考下
    2022-04-04
  • Go 日志封装实战示例详解

    Go 日志封装实战示例详解

    这篇文章主要为大家介绍了Go 日志封装实战示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-04-04
  • 使用Go语言进行安卓开发的详细教程

    使用Go语言进行安卓开发的详细教程

    本文将介绍如何使用Go语言进行安卓开发,我们将探讨使用Go语言进行安卓开发的优点、准备工作、基本概念和示例代码,通过本文的学习,你将了解如何使用Go语言构建高效的安卓应用程序,需要的朋友可以参考下
    2023-11-11
  • Go-家庭收支记账软件项目实现

    Go-家庭收支记账软件项目实现

    这篇文章主要介绍了Go-家庭收支记账软件项目实现,本文章内容详细,具有很好的参考价值,希望对大家有所帮助,需要的朋友可以参考下
    2023-01-01
  • Go并发编程中sync/errGroup的使用

    Go并发编程中sync/errGroup的使用

    本文主要介绍了Go并发编程中sync/errGroup的使用,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-12-12

最新评论