Reputation: 91
I'm trying to figure out the best pattern to work with objects in Swift.
i think i got it right with the initializers, both convenience and default... but what happen with the class factory methods?
I tried to create a simple class Person and a subclass Student, with few properties and methods. is it the most correct way to do it?
class Person{
var _name: String
var _surname: String
var _dateOfBirthday: String
var _phoneNumb: [String]
init(name:String, surname:String, dateOfBirthday:String, phone:[String]){
self._name = name
self._surname = surname
self._dateOfBirthday = dateOfBirthday
self._phoneNumb = phone
}
convenience init() {
self.init(name:"",surname:"",dateOfBirthday:"", phone:[])
}
convenience init(name:String){
self.init(name:name,surname:"",dateOfBirthday:"", phone:[])
}
}
class Student:Person{
var _studentId:Int
init(name: String, surname: String, dateOfBirthday: String, phone: [String], id:Int) {
self._studentId = id
super.init(name: "", surname: "", dateOfBirthday: "", phone: [])
}
convenience init(){
self.init(name: "", surname: "", dateOfBirthday: "", phone: [], id:0)
}
convenience init(name:String){
self.init(name:name,surname:"",dateOfBirthday:"", phone:[], id:0)
}
}
what if i want to add a class factory method? would it be something like this or i'm doing it wrong?
class func Person() -> Person {
var x = Person()
x._telephoneNumber = [String]() // is this needed? or i can initialize it later?
return x
}
class func PersonWithName(name:String) -> Person {
var x = Person(name:name, surname:"", dateOfBirthday:"", telephoneNumber:[])
return x
}
is this correct? why would it be better to use the init instead of the class factory?
Upvotes: 5
Views: 13651
Reputation: 4336
Prior to the recent Xcode 6.1 and Swift 1.1, it was necessary to use factory pattern if construction could fail because init()
could not return optionals. This was also why many cocoa/objective-c libraries imported had factory methods.
With the release of Xcode 6.1 and Swift 1.1 and the support for init()
that can return optionals, you should use the init()
pattern with convenience initializers. With this release, Apple also changed their cocoa/objective-c imports to use the init() -> T?
pattern over the factory method.
See https://developer.apple.com/library/ios/releasenotes/DeveloperTools/RN-Xcode/Chapters/xc6_release_notes.html for the release notes.
Upvotes: 0
Reputation: 6536
is this correct? why would it be better to use the init instead of the class factory?
Why would you create a "class factory" if you can use init? init
is idiomatic Swift way of creating new objects of a class.
Adding convenience initializers is the right choice in most cases when you want to add a shortcut to class's main (designated) initializer. However, in your case, they are completely unnecessary, because Swift supports default argument values.
Just define your initializer like so:
init(name:String = "", surname:String = "", dateOfBirthday:String = "", phone:[String] = []) { ... }
This way, you can invoke it as Person()
or Person(name: "Andrew")
or with any other combination of arguments.
EDIT:
As a side note, prefixing instance variables with an underscore generally doesn't seem to be idiomatic Swift. It's okay to omit the underscore and use self.
to disambiguate between local and instance variables:
self.name = name
self.surname = surname
self.dateOfBirthday = dateOfBirthday
self.phoneNumb = phone
Upvotes: 5