개발을 하다 보면 특정 객체가 앱 전역에서 하나만 존재해야 하는 경우가 있습니다. 그럴 때 사용하는 디자인 패턴이 바로 '싱글톤(Singleton)'입니다. 싱글톤 패턴은 객체의 인스턴스가 하나만 생성되도록 보장하고 이를 전역적으로 접근할 수 있게 합니다. 이 글에서는 싱글톤 패턴이 무엇인지, 왜 사용하는지, 그리고 실제로 어디에 적용할 수 있는지 알아보도록 하겠습니다.
목차
5.
싱글톤 패턴이란?
싱글톤 패턴은 특정 클래스의 인스턴스가 오직 하나만 생성되도록 보장하는 디자인 패턴입니다. 이 패턴은 주로 전역 상태를 관리하거나 자원의 중복을 방지하고 싶을 때 사용됩니다. 예를 들어 네트워크 매니저, 데이터베이스 연결 객체 등은 애플리케이션 전체에서 하나의 인스턴스로만 존재해야 합니다. 여러 인스턴스가 생성된다면 리소스를 낭비하거나, 데이터를 일관성 있게 유지하는 것이 어려울 수 있습니다.
싱글톤 패턴의 주요 특징은 다음과 같습니다.
인스턴스의 유일성 보장
클래스 인스턴스가 하나만 존재합니다.
전역 접근
프로그램 어디서나 동일한 인스턴스를 접근할 수 있습니다.
지연 초기화
필요할 때까지 인스턴스를 생성하지 않아 메모리 사용을 최적화할 수 있습니다.
언제 싱글톤 패턴을 사용해야 할까?
싱글톤 패턴은 다음과 같은 상황에서 유용합니다.
전역 상태를 관리할 때
사용자의 로그인 상태나 애플리케이션 설정 등 앱 전체에서 일관된 상태를 관리해야 할 때
공유 자원을 관리할 때
네트워크 연결, 파일 입출력, 데이터베이스 접근 등 여러 클래스에서 동시에 접근하는 자원을 중앙에서 관리하고 싶을 때
비용이 큰 객체의 중복 생성을 방지할 때
초기화 비용이 크거나 메모리 사용량이 큰 객체를 여러 번 생성하는 것을 방지하고 싶을 때
싱글톤 패턴 구현하기
class NetworkManager {
// 인스턴스를 정적 프로퍼티로 선언하여 유일성을 보장
static let shared = NetworkManager()
// 외부에서 이 클래스를 초기화하지 못하도록 private initializer 사용
private init() { }
// 네트워크 요청 메서드 예시
func fetchData(from url: String) {
// 네트워크 요청 코드
print("\(url)에서 데이터를 가져옴")
}
}
Swift
복사
위 코드에서 NetworkManager.shared를 통해 네트워크 매니저 인스턴스에 접근할 수 있습니다. private init()은 외부에서 클래스의 인스턴스를 새로 생성하는 것을 막아 하나의 인스턴스만 존재하도록 합니다.
싱글톤을 활용한 사용자 세션 관리
간단한 예시로 사용자 세션을 관리하는 UserSessionManager를 만들어 보겠습니다. 이 클래스는 사용자 로그인 상태를 관리하며 앱 전역에서 언제든지 접근할 수 있어야 합니다.
class UserSessionManager {
static let shared = UserSessionManager()
private init() { }
var isLoggedIn: Bool = false
var userName: String?
func logIn(userName: String) {
self.userName = userName
self.isLoggedIn = true
print("\(userName)님이 로그인하셨습니다.")
}
func logOut() {
self.userName = nil
self.isLoggedIn = false
print("로그아웃 되었습니다.")
}
}
Swift
복사
이제 앱의 어디서든 UserSessionManager.shared를 통해 로그인 상태를 관리할 수 있습니다.
// 로그인 처리
UserSessionManager.shared.logIn(userName: "심범수")
// 현재 로그인 상태 확인
if UserSessionManager.shared.isLoggedIn {
print("\(UserSessionManager.shared.userName!)님이 로그인 중입니다.")
} else {
print("로그인된 사용자가 없습니다.")
}
// 로그아웃 처리
UserSessionManager.shared.logOut()
Swift
복사
이렇게 싱글톤 패턴을 사용하면 사용자 로그인 상태를 전역적으로 관리할 수 있고 여러 클래스에서 동일한 인스턴스를 공유할 수 있기 때문에 데이터의 일관성을 유지할 수 있습니다.
싱글톤 패턴의 주의사항
싱글톤 패턴은 편리하지만 잘못 사용하면 유지보수와 테스트에서 어려움을 초래할 수 있습니다.
의존성 주입의 어려움
싱글톤 객체는 전역적으로 사용되기 때문에 테스트 시에 모킹(Mock)을 사용하기 어렵습니다.
과도한 전역 상태 사용
전역적으로 접근 가능한 객체가 많아지면 코드의 의존성이 높아지고 버그 발생 가능성이 증가합니다.
멀티스레드 환경에서의 안전성
스레드 안전한 싱글톤 구현이 필요할 수 있습니다. static let은 기본적으로 스레드 안전성을 제공하므로 대부분의 경우 안전하지만 추가적인 고려가 필요할 수 있습니다.
마무리
싱글톤 패턴은 객체의 유일성을 보장하며 전역적으로 접근 가능한 인스턴스를 생성해야 할 때 매우 유용한 패턴입니다. 네트워크 매니저나 사용자 세션 관리와 같은 경우에 잘 활용할 수 있습니다. 하지만 잘못된 사용은 유지보수를 어렵게 만들 수 있기 때문에 적절한 상황에서 신중히 적용하는 것이 중요합니다. 클린 코드와 유지보수성을 위해 싱글톤이 정말 필요한지 고민하고 필요한 경우에만 사용하는 습관을 가지는 것이 중요합니다.