💌 Design Pattern

[Design Pattern] Singleton Pattern (싱글톤패턴) with Swift

exception_log 2022. 2. 14. 22:52

안녕하세요 조이입니다~!

오늘은 게으름피우지 않고 디자인패턴 포스팅을 해보려고 해요!

오늘도 군말없이 바로 시작하겠습니다!

 

Singleton Pattern 개요

"하나의 인스턴스만 생성하여 사용하는 디자인 패턴"
즉, 인스턴스가 필요할 때 똑같은 인스턴스를 만들지 않고 기존의 인스턴스를 활용하는 것이다.

 

실제 상황에서 생각해보기

  • 하나의 나라를 생각해보자. 한 나라는 하나의 공식 정부를 가질 수 있다. 당연하게도!
  • 정부를 구성하는 개인의 신원과는 상관없이 "대한민국 정부" 라는 제목은 담당자의 그룹을 식별할 수 있는 글로벌 엑세스 포인트라고 볼 수 있다.

대충 무슨 말인지는 알겠음. 그러면 우리가 코드로 적용할 때에는 언제 사용하지?

  • 공통된 객체를 여러개 생성해서 사용해야하는 상황에서 사용한다.
  • 인스턴스가 절대적으로 한개만 존재하는 것을 보증하고 싶을 때 사용한다.

그럼 싱글톤의 장점은 뭐지?

  • 메모리 낭비를 방지할 수 있다. 
  • 다른 클래스와 자원 공유가 쉽다.

장점만 있나? 단점은 없나?

  • 만약 싱글톤 인스턴스가 너무 많은 일을 혼자 하거나 많은 데이터를 공유시키면 다른 클래스들간의 결합도가 높아지게 되는데, 이 때 OCP에 위배된다. (OCP가 뭔지 모른다면.. https://exception-log.tistory.com/197?category=1244126 요기 한번 읽어보시길..)
  • 결합도가 높아지게 되면 유지보수가 힘들어지고 테스트도 원활하게 진행할 수 없는 문제점이 발생한다.
  • 멀티 스레드 환경에서는 동기화 처리를 하지 않았을 때 인스턴스가 2개 생성되는 문제도 발생할 수 있음
  • 때문에 싱글톤이 반드시 필요한 상황이 아니라면 지양하는게 좋다.
  • 해결책은 없을까?
    • Singleton 클래스의 기본 생성자를 private으로 설정한다.
    • 생성자 역할을 하는 static method를 만들어준다. 내부적으로 이 method는 private 생성자를 호출하여 개체를 만들고 정적 필드에 저장한다. 이 method에 대한 다음 호출은 캐시된 개체를 반환할 것이다.

 

코드로 확인해보기

  • Swift에서는 static을 사용해 타입 프로퍼티로 인스턴스를 생성하면 사용 시점에 초기화 된다.
class UserInfo {
    static let shared = UserInfo() // Instance를 저장할 프로퍼티!

    var id: String?
    var password: String?
    var name: String?
  
  	private init() { } // init 함수 접근제어자를 private으로! -> 혹시라도 init 함수를 호출해서 instance를 또 생성하는 것을 막기 위해
}

// A Viewcontroller
let userInfo = UserInfo.shared
userInfo.id = "joy"

// B ViewController
let userInfo = UserInfo.shared
userInfo.password = "hey"

// C ViewController
let userInfo = UserInfo.shared
userInfo.name = "suebin"

// 어느 클래스에서든 shared 란 static 프로퍼티로 접근하면, 하나의 인스턴스를 공유하는 것
반응형