直接访问类变量(使用点表示法)还是通过函数?


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)

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

类成员temperature设计得不好。 它缺乏封装。

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

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

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

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

话虽如此,该类的设计可以改进:

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

编辑以避免歧义的措辞: 属性观察者(willSetdidSet(允许在直接更改公共变量时产生额外的效果。因此,直接更改并不能阻止其他影响。但这需要类设计者在脑海中做出如此直接的改变。而且变化的控制力不如函数。例如,您无法完全阻止非法更改的影响:您可以撤消 didSet 中的错误更改,但 willSet 将被调用两次;一次与非法价值,一个后逆转。

最新更新