golang: 从 Uber Go 风格指南,摄取 API 设计营养

2019-10-16 09:29:51 +08:00
 guonaihong

昨天晚上快速看了 uber go 风格指南,发现最后一条技巧,对 API 设计有帮助,拿出来大家一起讨论下。

回顾

bad code

// package db

func Connect(
  addr string,
  timeout time.Duration,
  caching bool,
) (*Connection, error) {
  // ...
}

// Timeout and caching must always be provided,
// even if the user wants to use the default.

db.Connect(addr, db.DefaultTimeout, db.DefaultCaching)
db.Connect(addr, newTimeout, db.DefaultCaching)
db.Connect(addr, db.DefaultTimeout, false /* caching */)
db.Connect(addr, newTimeout, false /* caching */)

good code

type options struct {
  timeout time.Duration
  caching bool
}

// Option overrides behavior of Connect.
type Option interface {
  apply(*options)
}

type optionFunc func(*options)

func (f optionFunc) apply(o *options) {
  f(o)
}

func WithTimeout(t time.Duration) Option {
  return optionFunc(func(o *options) {
    o.timeout = t
  })
}

func WithCaching(cache bool) Option {
  return optionFunc(func(o *options) {
    o.caching = cache
  })
}

// Connect creates a connection.
func Connect(
  addr string,
  opts ...Option,
) (*Connection, error) {
  options := options{
    timeout: defaultTimeout,
    caching: defaultCaching,
  }

  for _, o := range opts {
    o.apply(&options)
  }

  // ...
}

// Options must be provided only if needed.

db.Connect(addr)
db.Connect(addr, db.WithTimeout(newTimeout))
db.Connect(addr, db.WithCaching(false))
db.Connect(
  addr,
  db.WithCaching(false),
  db.WithTimeout(newTimeout),
)

技巧肢解

里面主要用了两种技巧

可变长参数的好处

gout https://github.com/guonaihong/gout

gout(流式 http client) 可以使用 SetCookies 可以设置一个或者多个 cookie。在大多数开源库里面用了两个函数实现类似功能。gout 这里用上可变长参数可以减少 API 个数。

gin 里面

在 gin(API 框架) Run 函数就是可变长参数经典用法,你可以用 router.Run()起个默认服务,也可以用 router.Run(":1234") 指定端口起服务。这里也可以减少 API 个数,写起来很爽。

上面举的例子可以归纳出,可变长参数用在,函数参数个数 >=0 的地方,很爽。

函数(接口)当配置

//TODO,中午再补上。

4896 次点击
所在节点    程序员
30 条回复
useben
2019-10-16 18:29:22 +08:00
函数选项模式呗,go-micro 的插件化就是基于此模式的。
婉转的实现了可变参数和默认参数的目的
zjsxwc
2019-10-16 21:22:57 +08:00
这种需求还不如用 builder 模式来得简单易懂
zjh6
2019-10-16 21:25:35 +08:00
golang 是谷哥搞的,就要晓得其没前途了.
人对了,什么都是对的.
人错了,怎么走都是错!
guonaihong
2019-10-16 21:37:57 +08:00
@Mark3K 是吗?有时间玩下。
yixinlove
2019-10-16 22:46:03 +08:00
我觉得还是看什么时候吧,如果配置项太多,可以考虑第二种,如果配置项只有那么几个,就没必要了。
一切还是以人为本写代码,太复杂会看的头晕。
guonaihong
2019-10-17 12:35:49 +08:00
@zjh6 go 代码是开源的。问题不大,真的发生 google 不维护,也会有社区维护的,现在可以修改编译器源码的童鞋已经不少了。
guonaihong
2019-10-17 20:54:46 +08:00
@love 可否推荐个开发普通业务不错的语言,以后玩下。
love
2019-10-17 21:32:05 +08:00
@guonaihong 我用的是 js,当然 V2 有大把莫名奇妙的 java 码农疯狂 diss nodejs,你看着办
guonaihong
2019-10-19 19:05:56 +08:00
@love js 是挺不错的语言。我后面也打算玩下。
zhixuanziben
2019-11-10 00:32:15 +08:00
@love nodejs 出活挺快的,加上 ts 也有类型系统了,做做 CRUD 还是很方便的

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/609761

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX