不好的包名的常见情况是 utility
包。这些包通常是随着时间的推移一些帮助程序和工具类的包。由于这些包包含各种不相关的功能,因此很难根据包提供的内容来描述它们。这通常会导致包的名称来自包含的内容 - utilities
。
像 utils
或 helper
这样的包名称通常出现在较大的项目中,这些项目已经开发了深层次包的结构,并且希望在不遇到导入循环的情况下共享 helper
函数。通过将 utility
程序函数提取到新的包中,导入循环会被破坏,但由于该包源于项目中的设计问题,因此其包名称不反映其目的,仅反映其为了打破导入循环。
我建议改进 utils
或 helpers
包的名称是分析它们的调用位置,如果可能的话,将相关的函数移动到调用者的包中。即使这涉及复制一些 helper
程序代码,这也比在两个程序包之间引入导入依赖项更好。
[A little] duplication is far cheaper than the wrong abstraction.
([一点点]重复比错误的抽象的性价比高很多。)
— Sandy Metz
在使用 utility
程序的情况下,最好选多个包,每个包专注于单个方面,而不是选单一的整体包。
贴士:
使用复数形式命名utility
包。例如strings
来处理字符串。
当两个或多个实现共有的功能或客户端和服务器的常见类型被重构为单独的包时,通常会找到名称类似于 base
或 common
的包。我相信解决方案是减少包的数量,将客户端,服务器和公共代码组合到一个以包的功能命名的包中。
例如,net/http
包没有 client
和 server
的分包,而是有一个 client.go
和 server.go
文件,每个文件都有各自的类型,还有一个 transport.go
文件,用于公共消息传输代码。
贴士:
标识符的名称包括其包名称。
重要的是标识符的名称包括其包的名称。
- 当由另一个包引用时,
net/http
包中的 Get 函数变为http.Get
。- 当导入到其他包中时,
strings
包中的Reader
类型变为strings.Reader
。net
包中的Error
接口显然与网络错误有关。