2

I have a question regarding object oriented design principles and Swift. I am pretty familiar with Java and I am currently taking a udacity course to get a first hands on in Swift.

In the Java community (basically in every community that follows OOP) it is very common to use information hiding techniques such as hiding or encapsulating data within classes to make sure it cannot be manipulated from outside. A common principle is to declare all attributes of a class as being private and use getters for retrieving an attribute's value and setters for manipulation.

I tried to follow this approach when writing a class that was part of the course and it looks like this:

//
//  RecordedAudio.swift
//  Pitch Perfect
//

import Foundation

class RecordedAudio: NSObject {
    private let filePathUrl: NSURL!
    private let title: String?

    init(filePathUrl: NSURL, title: String?)
    {
        self.filePathUrl = filePathUrl
        self.title = title
    }

    func getFilePathUrl() -> NSURL
    {
        return filePathUrl
    }

    func getTitle() -> String
    {
        if title != nil
        {
            return title!
        }
        else
        {
            return "none"
        }
    }
}

The code works and my private attributes cannot be accessed from outside my class, which is exactly the behavior I wanted to achieve. However, the following questions came to my mind:

1.) The course instructor decided to leave the attributes' access control level at the default "internal" and not use getters/setters but rather access the attributes directly from outside. Any thoughts on why developers might do that in swift? Is my approach not "swift" enough???

2.) In conclusion: Is there a "swifter" way to implement encapsulation when writing your own class? What are swift's native techniques to achieve the information hiding I am aiming for?

Marko Topolnik
  • 195,646
  • 29
  • 319
  • 436
Christian
  • 1,589
  • 1
  • 18
  • 36
  • See also http://stackoverflow.com/questions/24103242/data-encapsulation-in-swift and maybe http://stackoverflow.com/questions/24003918/does-swift-have-access-modifiers – gknicker Jan 05 '15 at 11:12
  • Thank you for linking me to those questions. However, they both assume that Swift lacks access modifiers, which it does not in it's current version. Swift does have access modifiers and they work, which is good news :-) However, I wonder how Apple wants us to use them in terms of OOP and information hiding! And that's what my question is about :-) – Christian Jan 05 '15 at 11:21
  • Early versions of swift lacked access modifiers, which is why there is still some confusion on the issue. In cases like this, where you're primarily interested in restricting access to the property setter, @akashivskyy's approach seems to be the generally accepted answer. – David Berry Jan 05 '15 at 20:28

2 Answers2

3

You can restrict external property manipulation, by marking the property public for reading and private for writing, as described in the documentation:

class RecordedAudio: NSObject {

    public private(set) let filePathUrl: NSURL!
    public private(set) let title: String?

    init(filePathUrl: NSURL, title: String?) {
        self.filePathUrl = filePathUrl
        self.title = title
    }

}

// in another file

let audio = RecordedAudio(filePathUrl: myUrl, title: myTitle)

let url = audio.filePathUrl // works, returns the url
audio.filePathUrl = newUrl // doesn't compile
akashivskyy
  • 44,342
  • 16
  • 106
  • 116
  • I like that. That looks "swift" :-) +1 Let's see if there are even other suggestions dropping in, otherwise I'll mark that as the answer! – Christian Jan 05 '15 at 13:38
2

I do it a bit like in Obj-C:

class MyClass
  private var _something:Int
  var something:Int {
    get {return _something}
// optional: set { _something = newValue }
  }
  init() { _something = 99 }
}

...
let c = MyClass()
let v = c.something

Above is a primitive example, but handled stringent it works as a good pattern.

qwerty_so
  • 35,448
  • 8
  • 62
  • 86