编写一个好的Go包,从名字开始。把你的包名想象成一次电梯演说【elevator pitch,是一个小故事】,你必须只用一个词来描述它的作用。

utils和helper

导致不好的包名的一个原因是工具包。这类包是由各种helper代码和工具代码构成的,它们包含种种不相干的功能,所以很难用包提供的功能来为之命名。这通常就导致,包就叫做util之类的名字。

诸如 utils 或者 helper 之类的包名常见于有着深层次包结构,并希望在不引入循环的情况下共享辅助函数的项目中。将辅助函数提取到一个包中打破了循环,但由于这个包是起源于项目的设计问题,其名称并没有反应其目的,仅仅起到了打破循环引用的作用。

[a little] duplication is far cheaper than the wrong abstraction

— Sandy Metz

我的改进建议是,将utils包中的函数放到导入并调用它的包中,而不是集中到utils中。尽管这会导致一些代码重复,这也比在两个包中引入依赖要更可取。在辅助函数被用于很多地方的情况下,(我)更喜欢多个包,每个包都专注于它相应的描述性的名字的一个方面。

base和common

诸如 basecommon 这类的包通常出现在,有多个相关设施的通用功能(比如server和client之间的公共type以及其mock)被重构为单独的包时。而更好的解决方案是,server、client以及他们的公共代码组合到一个“以该包所提供的功能命名”的包中,来减少包的数量。

举个例子, net/http 包中并没有 client 或者 server 包,而是有 client.goserver.go 两个文件,分别持有各自的类型。 transport.go 保存着HTTP客户端和服务器使用的公共消息传输代码。

Conclusion

根据包所提供(provide)的内容来命名,而不是它所包含的(contain)。

Links

翻译自 Avoid package names like base, util, or common