左耳听风
陈皓
网名“左耳朵耗子”,资深技术专家,骨灰级程序员
60101 人已学习
立即订阅
登录后,你可以任选6讲全文学习
推荐试读
换一换
06 | 如何才能拥有技术领导力?
32 | 编程范式游记(3) - 类型系统和泛型的本质
28 | 推荐阅读:分布式系统架构经典资料
课程目录
已完结/共 118 讲
技术基础 (21讲)
开篇词 | 洞悉技术的本质,享受科技的乐趣
01 | 程序员如何用技术变现(上)
02 | 程序员如何用技术变现(下)
03 | Equifax信息泄露始末
04 | 从Equifax信息泄露看数据安全
05 | 何为技术领导力?
06 | 如何才能拥有技术领导力?
07 | 推荐阅读:每个程序员都该知道的知识
08 | Go语言,Docker和新技术
09 | 答疑解惑:渴望、热情和选择
10 | 如何成为一个大家愿意追随的Leader?
11 | 程序中的错误处理:错误返回码和异常捕捉
12 | 程序中的错误处理:异步编程以及我的最佳实践
13 | 魔数 0x5f3759df
14 | 推荐阅读:机器学习101
15 | 时间管理:同扭曲时间的事儿抗争
16 | 时间管理:如何利用好自己的时间?
17 | 故障处理最佳实践:应对故障
18 | 故障处理最佳实践:故障改进
19 | 答疑解惑:我们应该能够识别的表象和本质
20 | Git协同工作流,你该怎么选?
分布式架构 (9讲)
21 | 分布式系统架构的冰与火
22 | 从亚马逊的实践,谈分布式系统的难点
23 | 分布式系统的技术栈
24 | 分布式系统关键技术:全栈监控
25 | 分布式系统关键技术:服务调度
26 | 分布式系统关键技术:流量与数据调度
27 | 洞悉PaaS平台的本质
28 | 推荐阅读:分布式系统架构经典资料
29 | 推荐阅读:分布式数据调度相关论文
编程范式 (11讲)
30 | 编程范式游记(1)- 起源
31 | 编程范式游记(2)- 泛型编程
32 | 编程范式游记(3) - 类型系统和泛型的本质
33 | 编程范式游记(4)- 函数式编程
34 | 编程范式游记(5)- 修饰器模式
35 | 编程范式游记(6)- 面向对象编程
36 | 编程范式游记(7)- 基于原型的编程范式
37 | 编程范式游记(8)- Go 语言的委托模式
38 | 编程范式游记(9)- 编程的本质
39 | 编程范式游记(10)- 逻辑编程范式
40 | 编程范式游记(11)- 程序世界里的编程范式
弹力设计 (11讲)
41 | 弹力设计篇之“认识故障和弹力设计”
42 | 弹力设计篇之“隔离设计”
43 | 弹力设计篇之“异步通讯设计”
44 | 弹力设计篇之“幂等性设计”
45 | 弹力设计篇之“服务的状态”
46 | 弹力设计篇之“补偿事务”
47 | 弹力设计篇之“重试设计”
48 | 弹力设计篇之“熔断设计”
49 | 弹力设计篇之“限流设计”
50 | 弹力设计篇之“降级设计”
51 | 弹力设计篇之“弹力设计总结”
管理设计 (6讲)
52 | 管理设计篇之“分布式锁”
53 | 管理设计篇之“配置中心”
54 | 管理设计篇之“边车模式”
55 | 管理设计篇之“服务网格”
56 | 管理设计篇之“网关模式”
57 | 管理设计篇之“部署升级策略”
性能设计 (5讲)
58 | 性能设计篇之“缓存”
59 | 性能设计篇之“异步处理”
60 | 性能设计篇之“数据库扩展”
61 | 性能设计篇之“秒杀”
62 | 性能设计篇之“边缘计算”
区块链 (6讲)
63 | 区块链技术的本质
64 | 区块链技术细节:哈希算法
65 | 区块链技术细节:加密和挖矿
66 | 区块链技术细节:去中心化的共识机制
67 | 区块链技术细节:智能合约
68 | 区块链技术 - 传统金融和虚拟货币
程序员练级攻略 (23讲)
69 | 程序员练级攻略:开篇词
70 | 程序员练级攻略:零基础启蒙
71 | 程序员练级攻略:正式入门
72 | 程序员练级攻略:程序员修养
73 | 程序员练级攻略:编程语言
74 | 程序员练级攻略:理论学科
75 | 程序员练级攻略:系统知识
76 | 程序员练级攻略:软件设计
77 | 程序员练级攻略:Linux系统、内存和网络
78 | 程序员练级攻略:异步I/O模型和Lock-Free编程
79 | 程序员练级攻略:Java底层知识
80 | 程序员练级攻略:数据库
81 | 程序员练级攻略:分布式架构入门
82 | 程序员练级攻略:分布式架构经典图书和论文
83 | 程序员练级攻略:分布式架构工程设计
84 | 程序员练级攻略:微服务
85 | 程序员练级攻略:容器化和自动化运维
86 | 程序员练级攻略:机器学习和人工智能
87 | 程序员练级攻略:前端基础和底层原理
88 | 程序员练级攻略:前端性能优化和框架
89 | 程序员练级攻略:UI/UX设计
90 | 程序员练级攻略:技术资源集散地
91 | 程序员练级攻略的正确打开方式
程序员面试攻略 (4讲)
92 | 程序员面试攻略:面试前的准备
93 | 程序员面试攻略:面试中的技巧
94 | 程序员面试攻略:面试风格
95 | 程序员面试攻略:实力才是王中王
高效学习 (5讲)
96 | 高效学习:端正学习态度
97 | 高效学习:源头、原理和知识地图
98 | 高效学习:深度,归纳和坚持实践
99 | 高效学习:如何学习和阅读代码
100 | 高效学习:面对枯燥和量大的知识
高效沟通 (6讲)
101 | 高效沟通:Talk和Code同等重要
102 | 高效沟通:沟通阻碍和应对方法
103 | 高效沟通:沟通方式及技巧
104 | 高效沟通:沟通技术
105 | 高效沟通:好老板要善于提问
106 | 高效沟通:好好说话的艺术
Go语言编程模式 (9讲)
107 | Go编程模式:切片、接口、时间和性能
108 | Go 编程模式:错误处理
109 | Go 编程模式:Functional Options
110 | Go编程模式:委托和反转控制
111 | Go 编程模式:Map-Reduce
112 | Go 编程模式:Go Generation
113 | Go编程模式:修饰器
114 | Go编程模式:Pipeline
115 | Go 编程模式:Kubernetes Visitor模式
尾声 & 加餐 (2讲)
结束语 | 业精于勤,行成于思
加餐 | 谈谈我的“三观”
左耳听风
15
15
1.0x
00:00/00:00
登录|注册

109 | Go 编程模式:Functional Options

你好,我是陈皓,网名左耳朵耗子。
这节课,我们来讨论一下 Functional Options 这个编程模式。这是一个函数式编程的应用案例,编程技巧也很好,是目前 Go 语言中最流行的一种编程模式。
但是,在正式讨论这个模式之前,我们先来看看要解决什么样的问题。

配置选项问题

在编程中,我们经常需要对一个对象(或是业务实体)进行相关的配置。比如下面这个业务实体(注意,这只是一个示例):
type Server struct {
Addr string
Port int
Protocol string
Timeout time.Duration
MaxConns int
TLS *tls.Config
}
在这个 Server 对象中,我们可以看到:
要有侦听的 IP 地址 Addr 和端口号 Port ,这两个配置选项是必填的(当然,IP 地址和端口号都可以有默认值,不过这里我们用于举例,所以是没有默认值,而且不能为空,需要是必填的)。
然后,还有协议 ProtocolTimeoutMaxConns 字段,这几个字段是不能为空的,但是有默认值的,比如,协议是 TCP,超时30秒 和 最大链接数1024个。
还有一个 TLS ,这个是安全链接,需要配置相关的证书和私钥。这个是可以为空的。
所以,针对这样的配置,我们需要有多种不同的创建不同配置 Server 的函数签名,如下所示:
func NewDefaultServer(addr string, port int) (*Server, error) {
return &Server{addr, port, "tcp", 30 * time.Second, 100, nil}, nil
}
func NewTLSServer(addr string, port int, tls *tls.Config) (*Server, error) {
return &Server{addr, port, "tcp", 30 * time.Second, 100, tls}, nil
}
func NewServerWithTimeout(addr string, port int, timeout time.Duration) (*Server, error) {
return &Server{addr, port, "tcp", timeout, 100, nil}, nil
}
func NewTLSServerWithMaxConnAndTimeout(addr string, port int, maxconns int, timeout time.Duration, tls *tls.Config) (*Server, error) {
return &Server{addr, port, "tcp", 30 * time.Second, maxconns, tls}, nil
}
因为 Go 语言不支持重载函数,所以,你得用不同的函数名来应对不同的配置选项。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/1000字
划线
笔记
复制
06 | 如何才能拥有技术领导力?
32 | 编程范式游记(3) - 类型系统和泛型的本质
28 | 推荐阅读:分布式系统架构经典资料
64 | 区块链技术细节:哈希算法
83 | 程序员练级攻略:分布式架构工程设计
96 | 高效学习:端正学习态度
该试读文章来自付费专栏《左耳听风》,如需阅读全部文章,
请购买文章所属专栏
立即购买
登录 后留言

精选留言(13)

  • 汪辉
    之前看到mq的初始化可选配置的时候有用到Functional Options这个模式,没想到在这里找到源头了。
    2021-01-19
    5
  • Geek_a754be
    之前在公司自研的微服务框架里面看到大规模使用,原来有个学名叫Functional Options
    2021-02-09
    1
    4
  • 太强了,受益匪浅
    2021-02-18
    2
  • 方勇(gopher)
    确实很多中间件的传参都这么设计,有时候可能要考虑,函数放在client端,还是server端
    2021-12-17
  • 青阳
    和函数科里化是一回事吗
    2021-11-12
  • 图个啥呢
    厉害了!
    2021-06-25
  • 👻 小二
    这种接口也很友好, 就是苦了作者

    ```go
    package main

    import (
    "crypto/tls"
    "time"
    )

    type Option struct {
    Timeout *time.Duration
    TLS *tls.Config
    }

    func (option *Option) SetTimeOut(timeout time.Duration) *Option {
    option.Timeout = &timeout
    return option
    }

    func (option *Option) SetTLS(tls *tls.Config) *Option {
    option.TLS = tls
    return option
    }

    func MergeOptions(options ...*Option) *Option {

    //把option合并起来
    return nil
    }

    type Server struct {
    Addr string
    Port int
    Timeout time.Duration
    TLS *tls.Config
    }

    func NewOptions() *Option {
    return new(Option)
    }
    func NewServer(addr string, port int, options ...*Option) (*Server, error) {

    srv := Server{
    Addr: addr,
    Port: port,
    Timeout: 30 * time.Second,
    TLS: nil,
    }

    op := MergeOptions(options...)

    if op.Timeout != nil {
    srv.Timeout = *op.Timeout
    }

    if op.TLS != nil {
    srv.TLS = op.TLS
    }

    //...
    return &srv, nil
    }
    func main() {
    _, _ = NewServer("127.0.0.1", 80)
    _, _ = NewServer("127.0.0.1", 80, NewOptions().SetTimeOut(100))
    _, _ = NewServer("127.0.0.1", 80, NewOptions().SetTimeOut(100).SetTLS(nil))
    }

    ```
    2021-06-10
  • 轻飘飘过
    对比js的...解构和函数式编程的compose?
    2021-05-20
  • astrosta
    用了很久,才知道叫Functional Options
    2021-04-24
  • Geek_450b7e
    优秀,学到了
    2021-04-23
  • Eirture
    在 Kubernetes 源代码中学过这一招,原来是叫 Functional Options,有了名字更容易记住和传播 👍
    2021-04-18
  • 小丢👣
    豁然开朗,respect
    2021-03-19
  • 侯鹏₁₈₆₁₄₀₉₂₄₁₉
    非常棒👍🏻
    2021-02-08
收起评论
13
返回
顶部