iOS/Design Pattern
Design Pattern - Singleton Pattern
HaningYa
2020. 8. 9. 00:33
728x90
Singleton Pattern - 싱글톤 패턴
- class 가 하나의 instance 만 가지도록 제한한다.
- 모든 class 에 대한 reference 는 하나의 같은 class 에 대한 instance를 참조한다. (Single)
- iOS 앱 개발에서 겁나 자주 쓰이고 Apple 이 광범위하게 쓴다.
- 다른 instance 를 생성하는 shared singleton instance를 제공하는 Singleton Plus 패턴도 자주 쓰인다.
Singleton Pattern 언제 사용해야 할까?
- 하나 이상의 동일 class 의 instance 를 가지게 되면 문제가 생길때
- 로직상으로 하나 이상의 동일 class 에 대한 instance 를 가지면 안될때
Singleton Plus Pattern 언제 사용해야 할까?
- shared instance 가 거의 대부분 유용하게 쓰일때
- 그러면서 custom instance 를 만드는 걸 허용하고 싶을때
- 예시) FileManager: 파일 시스템의 접근을 관리함. default 라 싱글톤 인스턴스가 있음. 대부분의 경우 default 대신 커스텀한 FileManager 인스턴스를 만들어서 background 쓰레드에서 사용할 것임
Singleton Pattern - Creational Pattern
- 앞서 다룬 Delegation Pattern 이나 Strategy 패턴은 Bahavior 패턴으로써 하나의 객체가 다른 객체에 대해 명령을 내리는 행위를 하였다.
- Singleton Pattern 은 Class에 대해 shared 된 instance 를 만드는 패턴이기 때문에 Creational Pattern 에 속한다.
예제) UIApplication
import UIKit
let app = UIApplication.shared
//let app2 = UIApplication() - 주석처리 안하면 에러난다
//왜냐면 싱글톤이라 인스턴스 하나만 만들 수 있다.
커스텀 싱글톤 클래스 예제
- 먼저 'shared' 라는 public static 프로퍼티를 선언한다. (싱글톤 인스턴스)
- init 을 private 하게 선언해 추가적인 인스턴스의 생성을 방지한다.
- 싱글톤 인스턴스를 MySingleton.shared를 통해 call 할 수 있다.
- 추가적인 MySingleton 인스턴스를 만들면 컴파일 에러가 난다.
public class MySingleton {
static let shared = MySingleton()
private init() { }
}
let mySingleton = MySingleton.shared
//let mySingleton2 = MySingleton() - 역시 주석을 해제하면 에러가 난다.
Singleton Plus Pattern 예제 - FileManager
let defaultFileManager = FileManager.default
let customFileManager = FileManager()
- FileManager 는 Singleton property 인 default instance 를 제공한다.
- 근데 또 새로운 FileManager 인스턴스들을 만들 수 있다.
- 이게 singleton plus 패턴이라는 증거이다.
Custom Singleton Plus 예제
- 싱글톤에서 했던 것 처럼 shared static property 를 선언한다. 싱글톤 플러스 패턴에서는 이 프로퍼티가 주로 default 라고 정의된다. (근데 원하는데로 이름 정해도 된다.)
- 그냥 싱글톤과 달리 init 을 public 으로 선언하여 추가적인 class 인스턴스화를 허용한다.
- MySingletonPlus.shared 를 통해 싱글톤 인스턴스에 접근할 수 있다.
- 또한 새로운 인스턴스도 만들 수 있다.
public class MySingletonPlus {
static let shared = MySingletonPlus()
public init() { }
}
let singletonPlus = MySingletonPlus.shared
let singletonPlus2 = MySingletonPlus()
Singleton Pattern 을 사용할 때 주의할 점
- 싱글톤 패턴은 과도하게 사용하기 쉽다.
- 싱글톤 패턴을 사용하고 싶은 상황일때 먼저 다른 방법으로 상황을 해결할 수 있는지 생각해라
- 예를들어 싱글톤 패턴은 단순히 정보를 view controller 사이에 전달할때는 적합하지 않다.
--> 그럴땐 싱글톤 대신 initializer 나 property 를 통해 model 을 넘기는 것으로 해결하라 - 진짜 실제로 진심으로 싱글톤 패턴이 필요하다면 싱글톤 플러스 패턴이 더 적합한지 생각하라
- 정말 동일 class 에 대해 하나 이상의 instance 를 가지는게 문제를 일으킬지 생각하고 true singleton 을 쓸지 singleton plus 를 쓸지 판단해라
- code smell 을 주의하라. 쉽게 말하자면 택도 없는 곳에서 싱글톤 패턴 쓰지말고 그냥 보통의 객체를 사용해라
싱글톤 패턴 사용시 단점
- 싱글톤 패턴의 사용이 문제가 되는 이유 중 하나는 테스팅이다.
- 만약 state 가 싱글톤과 같은 전역객체에 저장되어 있다면 테스트의 순서가 중요해 진다.
- mock 하기도 힘들어 진다.
728x90