贝利信息

Golang包设计如何提高代码复用率

日期:2026-01-24 00:00 / 作者:P粉602998670
可复用的Go代码需遵循接口窄、实现松原则:接口仅含1–3个必要方法,命名体现职责,配置通过构造函数传入,错误分层处理并避免过早抽象。

接口定义要窄,实现要松

Go 里复用的核心不是继承,而是组合 + 接口。如果 interface{} 太宽(比如塞了 10 个方法),调用方很难只用其中 2 个,又得实现全部——这直接劝退复用。真正可复用的接口往往只有 1–3 个方法,比如 io.Reader 就只有 Read([]byte) (int, error) 一个方法。

导出标识符命名要体现职责边界

Go 包里导出的类型、函数、变量,名字本身就在传递复用意图。比如叫 NewHTTPClient() 暗示它返回的是通用 HTTP 客户端;而叫 NewPaymentClient

() 就锁死了场景,别人不敢拿去复用。

配置通过结构体传入,不依赖全局变量或 init()

一旦包初始化时读环境变量、硬编码 endpoint、或者在 init() 里注册 handler,这个包就很难被不同项目安全复用——你改配置就得改源码,或者引入副作用。

type ServiceOption func(*service)

func WithTimeout(d time.Duration) ServiceOption { return func(s *service) { s.timeout = d } }

func NewService(opts ...ServiceOption) *service { s := &service{} for _, opt := range opts { opt(s) } return s }

错误处理要分层,别把底层错误直接透出

如果包里所有错误都直接返回 fmt.Errorf("failed to dial: %w", err),上层无法区分是网络问题、认证失败还是参数错误,也就没法针对性重试或降级——复用时只能全盘兜底,成本飙升。

真正难的不是写可复用的代码,是忍住不在第一个项目里就把“看起来以后会用到”的逻辑提前封装。多数复用发生在第二、第三个相似需求出现时,过早抽象只会增加维护负担。