2.4#4:过度使用getter和setter
在编程中,数据封装指的是隐藏对象的值或状态。getter和setter 是通过在不可导出的对象字段基础上提供可导出方法来启用封装的。
在Go 中,并不像我们在某些语言中看到的那样,自动支持 getter和setter。使用getter和 setter 来访问结构体字段也被认为既不是强制性的,也不是惯用的。例如,标准库实现了可以直接访问某些字段(例如time.Time)的结构体。time.Time结构体如下:
尽管不建议这样做,但我们甚至可以直接修改 C(但不再接收事件)。然而,这个例子说明了标准 Go 库并不强制使用getter和/或 setter,即使我们不应该修改一个字段。
另一方面,使用getter和setter 具有一些优点,包括:
■ 它们封装了与获取或设置字段相关的行为,允许稍后添加新功能(例如,验证字段、返回计算值或用互斥锁封装对字段的访问)。
■ 它们隐藏了内部实现,使我们在暴露内容时可更灵活地操作。
■ 当属性在运行时发生更改时,它们提供了一个调试拦截点,使调试变得更容易。
如果遇到这些情况,或者当我们保证向前兼容的时候预见到一个可能的情况,那么使用getter和 setter 可以带来一些好处。例如,如果将它们与一个名为 balance的字段一起使用,我们应该遵循以下命名约定:
■ getter 方法应该被命名为 Balance(而不是 GetBalance)。
■ setter 方法应该被命名为 SetBalance。
这里有一个例子:
总之,如果结构体上的getter和setter 没有任何价值,我们就不应该用它们淹没代码。我们应该实事求是,努力在效率和遵循在其他编程范例中有时被认为是无可争议的习惯用法之间找到正确的平衡。
记住,Go 是一种独特的语言,在设计上有许多特点,包括简单性。然而,如果我们发现需要 getter和setter,或者如前所述,在保证向前兼容的同时预见未来的需要,那么使用它们并没有什么问题。
接下来,我们将讨论过度使用接口的问题。