[디자인 패턴] Singleton Pattern
class
를 오직 하나의 인스턴스로 제한하는 패턴을 싱글톤 패턴이라고 합니다. 해당 클래스에 대한 모든 참조는 모두 같은 인스턴스를 바라봅니다. iOS 개발에서 매~우 흔하게 쓰이는 패턴입니다.
“Singleton plus” 패턴 역시 흔하게 사용 됩니다. 이 패턴은 위의 싱글톤처럼 shared
프로퍼티를 제공하지만 initializer
도 접근 할 수 있어서 여러 custom
인스턴스를 생성할 수 있습니다.
언제 쓰이는가?
- 싱글톤 패턴: 하나의
class
에 대해서 2개 이상의 인스턴스를 사용하면 문제가 되거나 논리적이지 못한 경우 - 싱글톤 플러스 패턴:
shared
인스턴스 외에도 custom 인스턴스가 생성될 필요가 있는 경우
e.g. 파일 시스템 접근권한과 관련된 모든 것을 다루는 FileManager
. 싱글톤인 default
인스턴스를 사용해도 되지만 본인 만의 인스턴스를 만들 수도 있습니다(보통 백그라운드 스레드에서 사용할 때 생성합니다)
코드 예시
싱글톤 사용 예시
import UIKit// MARK: - Singletonlet app = UIApplication.shared
싱글톤 생성 예시
class MySingleton {
// 1: 싱글톤 인스턴스인 static 프로퍼티 선언
static let shared = MySingleton() // 2: 추가적인 인스턴스 생성을 막기 위해 init을 private으로 표시
private init() { }}// 3: shared 를 통해서 싱글톤 인스턴스를 얻을 수 있음
let mySingleton = MySingleton.shared// 4: 컴파일 에러
let newSingleton = mySingleton()
싱글톤 플러스 사용 예시
let defaultFileManager = FileManager.default
let customFileManager = FileManager()
싱글톤 플러스 생성 예시
class MySingletonPlus { // 1: 위의 싱글톤 생성예시 처럼 static 프로퍼티인 shared 선언
static let shared = MySingletonPlus() // 2: 위의 싱글톤과는 다르게 init이 외부에서도 접근 할 수 있도록 허용
init() { }
}// 3: shared 를 통해서 싱글톤 인스턴스를 얻을 수 있음
let singletonPlus = MySingletonPlus.shared// 4: init 을 통해서 custom 인스턴스를 생성할 수 있음
let singletonPlus2 = MySingletonPlus()
주의해야할 점
1. 싱글톤 패턴은 과하게 사용하기 쉽습니다. 때문에 싱글톤을 사용하기 이전에 다른 방법도 고려해 보길 추천합니다.
예시로, 단순히 하나의 뷰 컨트롤러에서 다른 곳으로 정보를 전달하려는 거라면 싱글톤은 적합하지 않습니다. 또한 만약 custom 인스턴스가 많이 필요하다면 싱글톤 No No! 부적합!
만약 싱글톤이 필요하다고 판단 되면 Singleton Plus 가 더 적합하지 않을지 고려해봐야합니다. (이쯤되면 싱글톤을 안쓰기 위해 발악을 해보라는 의미인 듯 합니다)
두개 이상의 인스턴스가 있으면 문제가 되는지, custom 인스턴스가 유용하지 않은지 고려하여 singleton Plus 와 singleton 중에서 가장 알맞는 것을 선택하도록 합니다.
2. 테스트를 할 때 문제가 있을 수 있습니다. 만약 싱글톤 같은 global 객체에 저장되는 state
를 갖고 있다면 (1)테스트의 순서에 문제가 발생할 수 있습니다. 또한 (2)mocking 하기도 까다롭습니다.