组织
构造器参数和方法参数
- 类的核心属性 vs. 操作参数
核心属性:任何描述“类”核心状态的属性应当在构造器里初始化,并作为结构体的字段。例如,Reporter 结构体的 DateResult 和两个回调函数 GetSignupNameCallback、GetPlatformNickname 都是 Reporter 的核心依赖,在实例化时必须提供,因此可以在构造器中传入。
操作参数:任何仅在某个特定操作中使用的数据应作为方法的参数传入,而不是放在构造器里。比如 Do 方法中的 drivenList,它只是执行 Do 操作时的输入数据,和 Reporter 的核心状态无关,因此应放在方法里。 - 类的生命周期
持久状态:如果某些数据在“类”的生命周期内一直需要(或经常需要)访问和更新,且多次操作之间需要共享这些数据,就应放在构造器里。例如,如果 DateResult 代表生成报告的日期,那么它对 Reporter 的多次使用都有意义。
一次性状态:对于只在某个方法中短暂使用的数据,或者是临时状态数据,则不需要放在构造器中,而是放在相应方法的参数中。 - 构造器参数的清晰性和简洁性
构造器参数不宜过多,太多参数会使代码难以阅读和维护。应保持结构体的核心属性清晰,不包含与主体功能无关的细节参数。
对于初始化时不必要的数据,考虑使用“可选配置”模式,允许设置默认值,或提供额外的 setter 方法以延迟初始化。 - 使用者的直觉
想想使用者如何使用这个“类”:当一个参数在使用者实例化时需要提供,那就是核心属性;当它只是操作的一部分时,就应在方法参数中传入。
适用情境的关键判断
如果数据是对象的“必要属性”,需要贯穿多个方法的生命周期 —— 构造器参数。
如果数据是“局部需求”,仅在特定方法里有意义 —— 方法参数。
无状态
面向接口编程 单元测试 依赖注入 副作用
契约式设计
TODO
命名
名词和动词
- 名词化结构体名称
描述职责:结构体名称应表达它的职责或核心功能,通常以名词或动名词形式出现。
避免冗长:保持名称简洁明了,避免过度描述。 - 动词化方法名称
直观表达动作:方法名应直接表明方法的动作或操作,通常是动词。
符合接口惯例:Go 中常用 er 结尾的命名法定义接口,例如 Writer、Reader。实现这些接口的结构体应命名成相同结尾方式。
举例:
Processor Process Process 表示执行处理任务。
示例: DataProcessor.Process(inputData)
Exporter Export Export 表示数据导出。
示例: CSVExporter.Export(data)
Authenticator Authenticate 验证用户或资源身份(例如登录验证、令牌验证)。
场景: 用户登录、验证 API 密钥 UserAuthenticator.Authenticate (credentials)
Transformer Transform 转换数据或格式(例如文本转换、数据格式转换)。
场景: 转换数据格式、数据清洗 DataTransformer.Transform (inputData)
Aggregator Aggregate 汇总数据或结果(例如日志汇总、数据聚合)。
场景: 聚合用户行为、汇总统计数据 DataAggregator.Aggregate (logs)
EventDispatcher DispatchEvent, RegisterListener, RemoveListener 分发事件并管理事件监听者,适用于事件驱动系统或消息通知机制。
命名法则总结
结构体(类)名: 名词,表示职责(如 Writer、Calculator)。
方法名: 动词,表示操作(如 Write、Calculate)。
利用 GPT
这里是一个可以复用的 Prompt 模板,支持在新的 GPT 对话中快速获得单方法和多方法的抽象命名案例
Prompt:
我正在进行面向某业务场景的Go语言代码设计,请为该场景提供适合的结构体抽象命名案例,并包含单方法和多方法的结构体设计。请给出清晰的结构体和方法名称,方法名称要做到简洁、表达清晰,但避免过度冗长。单方法结构体应聚焦于单一功能,而多方法结构体应包含丰富的操作来实现业务场景的不同功能。结构体和方法命名应覆盖广泛业务需求,以确保设计的灵活性和实用性。
不用提供代码,只需要结构体和方法命名,简洁的使用场景描述
单方法和多方法的例子要不少于10个,并组织成表格
如果我没有提供具体的业务场景,请给出一些通用的结构体和方法命名示例,涵盖常见的系统设计和应用场景。
示例业务场景:数字人技术开发
编码规约
接口以 -er 后缀命名
Go 社区中,接口名称通常以 -er 结尾,表示该接口的核心行为。
减少缩写和自创词
除了业界常用缩写(如 ID, URL, API),尽量避免自创缩写。
经验总结:开源代码中应避免晦涩的自创缩写,使用清晰的全拼命名来保证可读性。
基于设计模式的命名
常见设计模式如 Factory、Builder、Adapter 等也有命名惯例。
常见示例:
LoggerFactory:表示生成 Logger 实例的工厂模式。
JSONAdapter:表示用于 JSON 处理的适配器。
经验总结:遵循设计模式命名,有助于开发者快速理解代码结构和意图。
结合业务领域术语
使用领域内通用的术语命名,可以使代码更贴近业务场景。
常见示例:
在金融领域,命名如 Transaction, BalanceManager, PaymentProcessor。
在电商领域,命名如 Cart, OrderProcessor, InventoryManager。
经验总结:结合领域术语命名使代码更具领域性和业务逻辑的表达力。