싱글톤 패턴❓
- 특정 용도로 객체를 하나만 생성하여 공용으로 사용하고 싶을 때 싱글톤(Singleton) 디자인 패턴을 활용합니다.
- 싱글톤(Singleton)으로 구현된 클래스는 생성자가 여러 차례 호출되더라도 실제로 생성되는 객체는 하나이며, 최초 생성 이후에 호출된 생성자는 최초의 생성가 생성한 객체를 리턴합니다.
- 객체는 하나만 생성하여, 생성된 객체를 어디서든 참조할 수 있도록 하는 패턴입니다.
예시 ▾
class UserInfo {
var id: String?
var password: String?
var name: String?
}
// A 뷰 컨트롤러
let userInfo = UserInfo()
userInfo.id = "Sodeul"
// B 뷰 컨트롤러
let userInfo = UserInfo()
userInfo.password = "1234"
// C 뷰 컨트롤러
let userInfo = UserInfo()
userInfo.name = "Sodeul"
- 위의 코드와 같이 각 뷰컨에서 따로 따로 정보를 받게 되면, 각각의 인스턴스에서 정보가 따로 놀게 됩니다.
- 이를 해결하기 위해 해당 인스턴스는 최초 생성될 때 전역으로 저장해두고, 그 이후에는 이 전역 인스턴에만 접근하게 하는 방법을 사용하게 됩니다.
class UserInfo {
static let shared = UserInfo()
var id: String?
var password: String?
var name: String?
private init() { }
}
// A 뷰 컨트롤러
let userInfo = UserInfo.shared
userInfo.id = "myId"
// B 뷰 컨트롤러
let userInfo = UserInfo.shared
userInfo.password = "myPwd123"
// C 뷰 컨트롤러
let userInfo = UserInfo.shared
userInfo.name = "myName"
혹시라도 init 함수를 호출해 Instance를 또 생생하는 것을 막기 위해, init() 함수 접근 제어자를 private로 지정해줍니다.
- 어느 클래스에서든 shared 라는 static 프로퍼티로 접근하면, 하나의 Instance 를 공유할 수 있습니다.
- 위에 예시 코드에서 UserInfo 클래스가 싱클톤 객체라고 불리며, 위와 같은 방식을 싱글톤 패턴이라고 합니다.
- 클래스에 대한 Instance는 최초 생성될 때 딱 한번만 생성해서 전역에 두고, 그 이후로는 이 Instance만 접근 가능하게 한다.
예시 2 ▾
- 아래에 보시는 것처럼 가까운 곳에서 싱글톤 패턴(Singleton Pattern)을 볼 수 있습니다.
let screen = UIScreen.main
let useDefault = UserDefaults.standard
let application = UIApplication.shared
let fileManager = FileManager.default
let notification = NotificationCenter.default
싱글톤 패턴(Singleton Pattern) 장단점 ⭐️
장점 ▾
- 한 번의 Instance만 생성하므로 메모리 낭비를 방지할 수 있습니다.
- Singleton Instance는 전역 Instance로 다른 클래스들과의 자원 공유가 쉽고 접근이 쉽습니다.
- DBCP(DataBase Connection Pool)처럼 공통된 객체를 여러 개 생성해서 사용해야하는 상황에서 많이 사용합니다. (쓰레드풀, 캐시, 대화상자, 사용자 설정, 레지스트리 설정, 로그 기록 객체 등)
단점 ▾
- Singleton Instance가 너무 많은 일을 하거나, 많은 데이터를 공유시킬 경우 다른 클래스의 Instance들 간 결합도가 높아져 "개방=폐쇄" 원칙을 위배합니다.
- 수정과 테스트가 어려워집니다.
추가 실습 예제 👨🏻💻
- 싱글톤 패턴(Singleton Pattern)을 이용하여 이름과 나이를 인스턴스(Instance)로 가지고 있는 클래스 생성합니다.
class CurrentUser {
static let shared = CurrentUser()
var name: String?
var age: Int?
private init() {}
}
2. ViewController에서 이름과 나이 값을 바인딩 해줍니다.
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let currentUser = CurrentUser.shared
currentUser.name = "Seok"
currentUser.age = 26
}
}
3. 다른 ViewController(FirstViewController)에서 이름을 사용해봅니다.
class FirstViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let currentUser = CurrentUser.shared
print(currentUser.name ?? "이름이 없습니다.") // Seok
}
}
4. 또 다른 ViewController(SecondViewController)에서 나이를 사용해봅니다.
class SecondViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let currentUser = CurrentUser.shared
print(currentUser.age ?? 0) // 26
}
}
- 여러 ViewController에서 데이터를 다루어야 할 때 쓰기 좋은 패턴이라고 생각합니다.
- 물론 많은 데이터가 공유되거나 많은 일을 하지 않는 선에서 사용해야 되는 패턴이라고 생각합니다.
- 실제로 개발하면서 위와 같은 경우가 있었는데 앞으로 싱글톤 패턴을 사용해야겠다는 생각이 들었습니다. 😄
'iOS_Swift.zip' 카테고리의 다른 글
[iOS]SOLID 원칙 (0) | 2022.01.07 |
---|---|
[iOS]옵저버 패턴(Observer Pattern) (0) | 2022.01.05 |
[iOS]FSCalendar 사용 후기 & 사용법 (5) | 2022.01.02 |
[iOS]dequeueReusableCellWithIdentifier-셀 재사용 (0) | 2022.01.01 |
[Xcode]Info plist (0) | 2021.12.25 |