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

邵阳建设银行网站是多少钱百度一下你就知道官网新闻

邵阳建设银行网站是多少钱,百度一下你就知道官网新闻,购物网站建设过程视频,php做原生直播网站前言 通过这篇文章《为什么说Go的函数是”一等公民“》,我们了解到了什么是“一等公民”,以及都具备哪些特性,同时对函数的基本使用也更加深入。 本文重点介绍下Go设计模式之函数选项模式,它得益于Go的函数是“一等公民”&#…

前言

通过这篇文章《为什么说Go的函数是”一等公民“》,我们了解到了什么是“一等公民”,以及都具备哪些特性,同时对函数的基本使用也更加深入。

本文重点介绍下Go设计模式之函数选项模式,它得益于Go的函数是“一等公民”,很好的一个应用场景,广泛被使用。

什么是函数选项模式

函数选项模式(Functional Options Pattern) ,也称为选项模式(Options Pattern),是一种创造性的设计模式,允许你使用接受零个或多个函数作为参数的可变构造函数来构建复杂结构。我们将这些函数称为选项,由此得名函数选项模式。

看概念有点太生硬难懂了,下面通过例子来讲解下怎么使用,由浅入深,通俗易懂。

怎么使用函数选项模式

一般水平

先来一个简单例子,这个Animal结构体,怎么构造出一个实例对象

type Animal struct {Name   stringAge    intHeight int
}

通常的写法

func NewAnimal(name string, age int, height int) *Animal {return &Animal{Name:   name,Age:    age,Height: height,}
}a1 := NewAnimal("小白兔", 5, 100)

简单易懂,结构体有哪些属性字段,那么构造函数的参数,就相应做定义并传入

带来的问题

  1. 代码耦合度高:加属性字段,构造函数就得相应做修改,调用的地方全部都得改,势必会影响现有代码;
  2. 代码灵活度低:属性字段不能指定默认值,每次都得明确传入;

例如,现计划新加3个字段Weight体重CanRun是否会跑LegNum几条腿,同时要指定默认值CanRun=true、LegNum=4

新结构体定义

type Animal struct {Name   stringAge    intHeight intWeight intCanRun boolLegNum int
}

代码实现(函数加新参数定义,但默认值貌似实现不了,得调用构造函数时,明确传入):

func NewAnimal(name string, age int, height int, weight int, canRun bool, legNum int) *Animal {return &Animal{Name:   name,Age:    age,Height: height,Weight: weight,CanRun: canRun,LegNum: legNum,}
}a1 := NewAnimal("小白兔", 5, 100, 120, true, 4)

后续逐步加新字段,这个构造函数就会被撑爆了,如果调用的地方越多,那么越伤筋动骨。

高阶水平

既然常规写法太low,难以实现新需求,那么我们就来玩点高阶的,引出主题:函数选项模式

首先,需要先定义一个函数类型OptionFunc

type OptionFunc func(*Animal)

然后,根据新结构体字段,定义With开头的函数,返回函数类型为OptionFunc的闭包函数,内部逻辑只需要实现更新对应字段值即可

func WithName(name string) OptionFunc {return func(a *Animal) { a.Name = name }
}func WithAge(age int) OptionFunc {return func(a *Animal) { a.Age = age }
}func WithHeight(height int) OptionFunc {return func(a *Animal) { a.Height = height }
}func WithWeight(weight int) OptionFunc {return func(a *Animal) { a.Weight = weight }
}func WithCanRun(canRun bool) OptionFunc {return func(a *Animal) { a.CanRun = canRun }
}func WithLegNum(legNum int) OptionFunc {return func(a *Animal) { a.LegNum = legNum }
}

再然后,优化构造函数的定义和实现(name作为必传参数,其他可选,并且实现CanRunLegNum两个字段指定默认值)

func NewAnimal(name string, opts ...OptionFunc) *Animal {a := &Animal{Name: name, CanRun: true, LegNum: 4}for _, opt := range opts {opt(a)}return a
}

最后,调用优化后的构造函数,快速实现实例的初始化。想要指定哪个字段值,那就调用相应的With开头的函数,完全做到可配置化、可插拔;不指定还支持了默认值

a2 := NewAnimal("大黄狗", WithAge(10), WithHeight(120))
fmt.Println(a2)
a3 := NewAnimal("大灰狼", WithHeight(200))
fmt.Println(a3)输出结果:
&{大黄狗 10 120 0 true 4}
&{大灰狼 0 200 0 true 4}

带来的好处

  1. 高度的可配置化、可插拔,还支持默认值设定;
  2. 很容易维护和扩展;
  3. 容易上手,大幅降低新来的人试错成本;

开源项目中的实践案例

函数选项模式,不单单是我们业务代码中有使用,现在大量的标准库和第三库都在使用。

下面带着大家一块来看看,apollo配置中心客户端第三库shima-park/agollo,看看它是怎么玩的,怎么做配置初始化

核心代码

type Options struct {AppID                      string               // appidCluster                    string               // 默认的集群名称,默认:defaultDefaultNamespace           string               // Get时默认使用的命名空间,如果设置了该值,而不在PreloadNamespaces中,默认也会加入初始化逻辑中PreloadNamespaces          []string             // 预加载命名空间,默认:为空ApolloClient               ApolloClient         // apollo HTTP api实现Logger                     Logger               // 日志实现类,可以设置自定义实现或者通过NewLogger()创建并设置有效的io.Writer,默认: ioutil.DiscardAutoFetchOnCacheMiss       bool                 // 自动获取非预设以外的Namespace的配置,默认:falseLongPollerInterval         time.Duration        // 轮训间隔时间,默认:1sBackupFile                 string               // 备份文件存放地址,默认:.agolloFailTolerantOnBackupExists bool                 // 服务器连接失败时允许读取备份,默认:falseBalancer                   Balancer             // ConfigServer负载均衡EnableSLB                  bool                 // 启用ConfigServer负载均衡RefreshIntervalInSecond    time.Duration        // ConfigServer刷新间隔ClientOptions              []ApolloClientOption // 设置apollo HTTP api的配置项EnableHeartBeat            bool                 // 是否允许兜底检查,默认:falseHeartBeatInterval          time.Duration        // 兜底检查间隔时间,默认:300s
}func newOptions(configServerURL, appID string, opts ...Option) (Options, error) {var options = Options{AppID:                      appID,Cluster:                    defaultCluster,ApolloClient:               NewApolloClient(),Logger:                     NewLogger(),AutoFetchOnCacheMiss:       defaultAutoFetchOnCacheMiss,LongPollerInterval:         defaultLongPollInterval,BackupFile:                 defaultBackupFile,FailTolerantOnBackupExists: defaultFailTolerantOnBackupExists,EnableSLB:                  defaultEnableSLB,EnableHeartBeat:            defaultEnableHeartBeat,HeartBeatInterval:          defaultHeartBeatInterval,}for _, opt := range opts {opt(&options)}//...省略return options, nil
}type Option func(*Options)//一系列函数作为选项
func PreloadNamespaces(namespaces ...string) Option {return func(o *Options) {o.PreloadNamespaces = append(o.PreloadNamespaces, namespaces...)}
}
func AutoFetchOnCacheMiss() Option {return func(o *Options) {o.AutoFetchOnCacheMiss = true}
}
//...

玩法

  1. 使用Options结构体,定义出apollo需要使用到的所有配置字段
  2. 定义一系列函数作为选项,对配置字段做初始化设置(例如,设置容灾文件路径、预加载的namespace、轮训间隔时间等等);
  3. 构造函数里初始化一个Options的实例对象,并且根据传入的函数选项,进行配置字段的更新,最终返回这个实例对象;
  4. 获取到实例对象,调用相应的方法做相应的操作。

总结

由浅入深的讲解了下实例对象初始化一般写法和高阶写法。用好这个高阶写法(函数选项模式),让代码更高比格。还不会使用的Gopher,赶紧学起来,用起来。

文章首发

我的文章会首发在我的公众号:程序员升职加薪之旅,欢迎大家关注,第一时间收到最新内容。

一起学习

我的所有文章都会首发在我的 学习小圈子 ,欢迎加入我们,一起学习进步,一起升职加薪。

http://www.15wanjia.com/news/22690.html

相关文章:

  • 兰州企业 网站建设片多多可以免费看电视剧吗
  • 微网站建设价格百度关键词优化推广
  • 西昌手机网站设计天津百度网站排名优化
  • 免费自动交易软件app重庆seo职位
  • 做网站销售好不好360收录批量查询
  • 网站项目策划书方案合肥关键词排名
  • 网站域名怎么缴费中国网民博客 seo
  • 如何在网站做电子报标题seo是什么意思
  • 网站建设静态代码小说关键词提取软件
  • 嘉兴网站制作星讯网络科技域名注册查询
  • wordpress用户关注如何网站关键词优化
  • 广州网站建设o2o网站建设需要多少钱?
  • 设计之家室内设计抖音seo点击软件排名
  • 做婚纱网站的图片大全网络工程师是干什么的
  • 展厅布置摆放设计公司关键词优化排名查询
  • 中关村在线官方网站电脑南京seo网站优化
  • 印度软件外包百度快照优化
  • 哈尔滨网站建设王道下拉強郑州聚商网络科技有限公司
  • 卖一手房做哪个网站好seo规则
  • 地方门户信息网站建设方案百度数据中心
  • 怎么样给公司做网站seo培训网
  • 湘潭网站开发seo关键词排名在线查询
  • 有可以花钱让人做问券的网站吗百度的广告怎么免费发布
  • 北京加盟网站建设自媒体是如何赚钱的
  • node.js做网站好累杭州小程序建设公司
  • 客服平台有哪些seo手机关键词排行推广
  • 中英文网站建站网站建设全网营销
  • 国家建设部门三类人员官方网站seo的工作内容
  • 做棋牌网站违法嘛网络推广员有前途吗
  • 大气蓝色律师网站phpcms模板手机百度经验首页登录官网