디자인 패턴, 싱글톤 in Swift

디자인 패턴을 처음 공부하는 시작점은 싱글톤 패턴이라고 할 수 있을 만큼 대중인적인 패턴이 싱글톤 패턴이다. 나 역시 이 패턴을 사용하지만 정확히 어떤 문제점이 있는지 설명할 수 있는지 설명할 수 있을까라고 혼자 질문했을 때 정확히 대답할 수 없어서 공부해야겠다고 느꼈다.

싱글톤 패턴이란?

클래스에 대한 인스턴스를 하나만 있도록 하면서 이 하나의 *인스턴스에 대한 접근하도록 하는 패턴을 의미한다.
예를 들어 한 화면에 API 통신을 하고자 할 때 urlSession 객체를 여러 개 만드는 것보다 싱글톤 패턴으로 띄워놓고 그것을 사용하면 이미 사용하고 있는 인스턴스를 또 생성할 필요가 없어지게 된다.

*인스턴스란? – 객체 지향 프로그래밍(OOP)에서 class or Struct을 기반으로 생성된 실제 데이터, 즉 실제로 메모리에 할당된 데이터를 의미한다.

왜 사용할까?

한 번에 같은 글래스의 기능을 사용하고자 할 때마다 인스턴스를 생성하며 그 기능을 가져오는 것은 비효율적일 것이다. 만약 싱글턴 패턴을 사용하게 된다면 불필요한 인스턴스를 여러 개 만드는 일을 줄일 수 있다.
예를 들어 한 화면에 API 통신을 하고자 할 때 urlSession 객체를 여러 개 만드는 것 보다 싱글톤 패턴으로 띄워놓고 그것을 사용하면 이미 사용하고 있는 인스턴스를 또 생성할 필요가 없어지게 된다.

실제로 URLSession에도 shared로 싱글턴 패턴을 사용한다.

혹은 개발을 하다보면 클래스에 있는 기능을 동시에 여러 곳에서 사용해야 할 필요가 있다. 그런 경우 클래스에 데ㅣ터를 전달하는 방법이 있을 수 있지만 싱글턴 패턴으로 접근해 사용할 수도 있다.

어떻게 사용할까?

*static 프로퍼티로 인스턴스를 생성하고 *private을 활용하여 init 메서드의 접근을 막는다.

static 프로퍼티란? – 타입 프로퍼티라고도 부른다. 클래스, 구조체, 열거형에서 사용되며 인스턴스를 생성하지 않고 타입 이름을 통해서 접근이 가능하다.

private 접근자란? – 접근 제어자 중 하나로, 정의하 블록 {} 내부에서만 접근이 가능하다.

final class Singleton {
    
    static let shared = Singleton()
    
    private init() {}
    
    func methodA() {}
    
    func methodB() {}
}
  • 싱글톤 패턴으로 인스턴스를 하나만 생성하기 위해 그리고 전역으로 생성하기 위해 static 프로퍼티를 사용한다.
  • shared로 접근하지 않고 새롭게 init으로 싱글톤 클래스의 인스턴스를 만드는 것을 막기 위해 init 메서드를 private 접근자로 막는다.

주의점은?

하나의 인스턴스를 생성하고 여러 곳에서 접그내서 사용하다보니 예기치 못한 상황에서 상태 관리와 디버깅의 어려움을 겪을 수 있다.

final class Singleton {
    
    static let shared = Singleton()
    
    var count = 0
    
    private init() {}
    
}

예를 들어 count를 수정해야 할 때 count로 직접 접근해 수정하다보면 추후에 어디서 수정을 했는지 디버깅의 어려움을 겪을 수 있다.

final class Singleton {
    
    static let shared = Singleton()
    
    private var count = 0
    
    private init() {}
    
    
    func chnageCount(to: Int) {
        count = to
    }
}

이를 어느정도 해결하기 위해 상태를 private 접근자로 막고 메서드를 만들어 상태를 변경하면 해당 부분이 어디에서 수정되었는지 좀 더 디버깅하기 수월하다.

물론 싱글톤 패턴 자체가 여러 곳에서 의존해서 사용하기 때문에 테스트가 번거로울 수 있다. 하지만 싱글톤 내부의 값이 변함으로써 어떤 값을 테스트한다면 그렇게 어렵지 않다고 생각이 든다.

Leave a Comment