GO 函数式选项模式(Functional Options Pattern)

Golang 开发者遇到的许多问题之一是尝试将一个函数的参数设置为可选. 这是一个非常常见的用例, 有些对象应该使用一些基本的默认设置来开箱即用, 并且你偶尔可能需要提供一些更详细的配置.

在很多语言中这很容易; 在 C 族语言中, 可以使用不同数量的参数提供相同函数的多个版本; 在像 PHP 这样的语言中, 可以给参数一个默认值,并在调用方法时忽略它们. 但是在 Golang 中, 这两种方式你哪个也用不了. 那么你如何创建一个函数, 用户可以指定一些额外的配置?

有很多可能的方法可以做到这一点, 但是大多数都不能满足要求, 或者需要在服务端的代码中进行额外的检查和验证, 或者通过传递额外的客户端不关心的参数来为客户端做额外的工作.

下面介绍GO 函数式选项模式(Functional Options Pattern),内容如下:

Option模式的优缺点
优点:
    1. 支持传递多个参数,并且在参数个数、类型发生变化时保持兼容性
    2. 任意顺序传递参数
    3. 支持默认值
    4. 方便拓展
缺点:
    1. 增加许多function,成本增大
    2. 参数不太复杂时,尽量少用

DEMO

package main

import "fmt"

type Client struct {
	Id        int64
	AppKey    string
	AppSecret string
}

type Option func(*Client) //  go函数的参数都是值传递 因此想要修改Client(默认值) 必须传递指针

func WithAppKey(appKey string) Option {
	return func(client *Client) {
		client.AppKey = appKey
	}
}

func WithAppSecret(appSecret string) Option {
	return func(client *Client) {
		client.AppSecret = appSecret
	}
}

//
//  NewClient
//  @Description 将一个函数的参数设置为可选的功能
//  @param id 固定参数,也可以将所有都放进可选参数 opts 中
//  @param opts
//  @return Client 返回 *Client 和 Client 都可以
//
func NewClient(id int64, opts ...Option) Client {
	o := Client{
		Id:        id,
		AppKey:    "key_123456",
		AppSecret: "secret_123456",
	}

	for _, opt := range opts {
		opt(&o) //  go函数的参数都是值传递 因此想要修改Client(默认值) 必须传递指针
	}

	return o
}

func main() {
	//  使用默认值
	fmt.Println(NewClient(1)) //  {1 key_123456 secret_123456}
	//  使用传入的值
	fmt.Println(NewClient(2, WithAppKey("change_key_222"))) //  {2 change_key_222 secret_123456}
	//  不按照顺序传入
	fmt.Println(NewClient(3, WithAppSecret("change_secret_333"))) //  {3 key_123456 change_secret_333}
	fmt.Println(NewClient(4, WithAppSecret("change_secret_444"), WithAppKey("change_key_444"))) //  {4 change_key_444 change_secret_444}
}

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

(0)

相关推荐

  • Go语言中的函数式编程实践

    本文主要讲解Go语言中的函数式编程概念和使用,分享给大家,具体如下: 主要知识点: Go语言对函数式编程的支持主要体现在闭包上面 闭包就是能够读取其他函数内部变量的函数.只有函数内部的子函数才能读取局部变量,所以闭包可以理解成"定义在一个函数内部的函数".在本质上,闭包是将函数内部和函数外部连接起来的桥梁. 学习闭包的基本使用 标准的闭包具有不可变性:不能有状态,只能有常量和函数,而且函数只能有一个参数,但是一般可以不用严格遵守 使用闭包 实现 斐波那契数列 学习理解函数实现接口 使用

  • GO 函数式选项模式(Functional Options Pattern)

    Golang 开发者遇到的许多问题之一是尝试将一个函数的参数设置为可选. 这是一个非常常见的用例, 有些对象应该使用一些基本的默认设置来开箱即用, 并且你偶尔可能需要提供一些更详细的配置. 在很多语言中这很容易; 在 C 族语言中, 可以使用不同数量的参数提供相同函数的多个版本; 在像 PHP 这样的语言中, 可以给参数一个默认值,并在调用方法时忽略它们. 但是在 Golang 中, 这两种方式你哪个也用不了. 那么你如何创建一个函数, 用户可以指定一些额外的配置? 有很多可能的方法可以做到这一

  • 如何使用.NET Core 选项模式【Options】

    ASP.NET Core引入了Options模式,使用类来表示相关的设置组.简单的来说,就是用强类型的类来表达配置项,这带来了很多好处.利用了系统的依赖注入,并且还可以利用配置系统.它使我们可以采用依赖注入的方法直接使用绑定的一个POCO对象,这个POCO对象就叫做Options对象.也可以叫做配置对象. 以下大多内容来自官方文档,我只是个翻译官或者叫搬运工吧! 引入Options扩展包 PM>Package-install Microsoft.Extensions.Options 绑定分层配置

  • 详解Golang函数式选项(Functional Options)模式

    概览 最近阅读源码的时候看到一段不错的代码,但是当时却不是非常理解为什么这么写. 我们先来看一下源代码: type User struct { ID string Name string Age int Email string Phone string Gender string } type Option func(*User) func WithAge(age int) Option { return func(u *User) { u.Age = age } } func WithEma

  • ASP.NET Core中的Options选项模式

    1.前言 选项(Options)模式是对配置(Configuration)的功能的延伸.在12章(ASP.NET Core中的配置二)Configuration中有介绍过该功能(绑定到实体类.绑定至对象图.将数组绑定至类)而选项模式又有个选项类(TOptions),该选项类作用是指:把选项类中的属性与配置来源中的键关联起来.举个例,假设json文件有个Option1键,选项类中也有个叫Option1的属性名,经过选项配置,这样就能把json中的键的值映射到选项类属性值中.也可以理解在项目应用中,

  • java 过滤器模式(Filter/Criteria Pattern)详细介绍

    java 过滤器模式(Filter/Criteria Pattern) 过滤器模式(Filter Pattern)或标准模式(Criteria Pattern)是一种设计模式,这种模式允许开发人员使用不同的标准来过滤一组对象,通过逻辑运算以解耦的方式把它们连接起来.这种类型的设计模式属于结构型模式,它结合多个标准来获得单一标准. 过滤器模式(Filter Pattern)或标准模式(Criteria Pattern)是一种设计模式,这种模式允许开发人员使用不同的标准来过滤一组对象,通过逻辑运算以

  • java 桥模式(Bridge Pattern)详解

    java 桥模式(Bridge Pattern) Bridge模式解耦,其实施的定义.它是一种结构模式.本模式涉及充当桥的接口.这座桥使具体的类独立的接口实施者类. Bridge模式解耦,其实施的定义.它是一种结构模式. 本模式涉及充当桥的接口.这座桥使具体的类独立的接口实施者类. 这两种类型的类可以在不影响彼此被改变. 实例: interface Printer { public void print(int radius, int x, int y); }//from www.j a v a

  • C#对象为Null模式(Null Object Pattern)实例教程

    本文以实例形式简单讲述了C#对象为Null模式(Null Object Pattern),分享给大家供大家参考.具体实现方法如下: 所谓的"对象为Null模式",就是要求开发者考虑对象为Null的情况,并设计出在这种情况下的应对方法. 以前面"C#策略模式(Strategy Pattern) "一文中的例子来说,在我们的客户端程序中只考虑了用户输入1,2,3的情况,如果用户输入其它数字,比如4,就没有一个对应的IBall接口实现类实例产生,于是会报如下的错: 为了应

  • java实现装饰器模式(Decorator Pattern)

    一.什么是装饰器模式   装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装.   这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能.   在不想增加更多子类的情况下扩展类,动态地给一个对象添加一些额外的职责.就增加功能来说,装饰器模式相比生成子类更为灵活. 二.装饰器模式的具体实现 1.结构图 2.分析 装饰器模式由组件和装饰者组成. 抽

  • java实现建造者模式(Builder Pattern)

    一.什么是建筑者模式?   建造者模式(Builder Pattern)使用多个简单的对象一步一步构建一个复杂的对象.   一个 Builder 类会一步一步构造最终的对象,该 Builder 类独立于其他对象.   建造者模式主要解决在软件系统中,有时候面临着"一个复杂对象"的创建工作,其通常由各个部分的子对象用一定的算法构成:由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定. 二.建造者模式的具体实现 结构图 建造者模式中的四个角色:

  • C#模板方法模式(Template Method Pattern)实例教程

    本文以一个简单的实例形式讲述了C#模板方法模式的实现方法,分享给大家供大家参考.具体实现方法如下: 这里假设要做一道红烧肉,做法有很多,在不同的做法中都有相同的部分,比如都要放油.放肉.放调料等.也有不同之处,比如有些做法放可乐,有些做法放甜蜜酱,等等. 先提炼出一个抽象类,该类不仅有制作红烧肉的各个步骤,而且还把各个步骤归纳到另一个方法,我们把这个方法称作模版方法.另外,在模版方法中,对于一些不确定的方面先用抽象方法. public abstract class HongShaoRou { p

随机推荐