Search code examples
swiftvariable-assignmentaccess-controlclass-designvariable-declaration

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)

I can access temperature directly by using dot notation and also with the function what is the difference in this two.


Solution

  • The class member temperature is not well designed. It lacks encapsulation.

    • The direct access changes the variable with little control. You have to know the internals of the class to be sure that the change doesn't lead to an inconsistent state. You cannot totally prevent the attempt to set an illegal value very easily.

    • The access via the function is designed deliver some promises, regardless of the internal details. Access via a function is more controlled: if the change of the temperature would require additional information (e.g. hygrometry because you expect to correlate in time both measurements, or timestamp from an external atomic clock) the function could required it, whereas variables can always be changed individually.

    • Moreover, if the thermometer will one day get some special behavior (e.g. update the display in the user's preferred unit of measure, or raise an alarm under some conditions), the function could make sure it is done.

    So the access via the function is the safer approach, since it will protect you against future evolution of that class.

    This being said, the design of the class could be improved:

    • The encapsulation should be enforced, making the variable private. The class users would then be forced to the proper use of registerTemperature() .
    • For convenience, you could make a setter on a wrapper property: this seems to give direct public access to a variable but when its value is changed the setter is executed, to ensure the promises of such changes are held.

    Edit to avoid ambiguous wording: property observers (willSet and didSet) allow to produce additional effects when a public variable is changed directly. So direct changes do not prevent additional effects. But this require the class designer to have such direct changes in mind. And the change is less controlled than in a function. For example, you cannot totally prevent the effects of an illegal change: you could reverse a wrong change in didSet, but willSet would then be called twice; once with the illegal value, one after the reversing.