直接(使用点符号)或通过函数访问 class 变量?

Accessing a class variable directly (using dot notation) or via a function?

class ThermometerClass {
    var temperature: Double = 0.0

    func registerTemperature(_ temperature: Double) {
        self.temperature = temperature
    }
}

let thermometerClass = ThermometerClass()

thermometerClass.temperature = 56.0

thermometerClass.registerTemperature(56.0)

我可以使用点符号直接访问温度,也可以使用函数这两者有什么区别。

class 成员 temperature 设计不佳。它缺乏封装。

  • 直接访问更改变量几乎没有控制。您必须了解 class 的内部结构,以确保更改不会导致不一致的状态。您不能完全阻止非常容易地设置非法值的尝试。

  • 无论内部细节如何,通过函数进行的访问旨在提供一些承诺。通过函数的访问受到更多控制:如果温度的变化需要额外的信息(例如湿度测量,因为您希望及时关联两个测量值,或来自外部原子钟的时间戳)函数可能需要它,而变量总是可以单独更改。

  • 此外,如果有一天温度计会出现一些特殊行为(例如,以用户首选的测量单位更新显示,或在某些情况下发出警报),该功能可以确保它已经完成了。

因此,通过函数进行访问是更安全的方法,因为它可以保护您免受该 class 未来演变的影响。

也就是说,class 的设计可以改进:

  • 应该强制执行封装,使变量成为私有的。 class 用户将被迫正确使用 registerTemperature()
  • 为方便起见,您可以在包装器 属性 上创建一个 setter:这似乎可以直接 public 访问变量,但是当它的值改变时 setter 被执行,以确保此类更改的承诺得到遵守。

编辑以避免模棱两可的措辞: 属性 观察者(willSetdidSet)允许产生额外的效果当直接更改 public 变量时。所以直接改变不会阻止额外的效果。但这需要 class 设计者考虑到这种直接的变化。而且这种变化比在函数中更难控制。例如,你不能完全阻止非法更改的影响:你可以撤销 didSet 中的错误更改,但是 willSet 会被调用两次;一次取非法值,取反后一次