[Swift] 디자인 패턴 (Design Patterns) - 생성 패턴 (싱글턴 패턴, Singleton pattern)

이번 포스트는 디자인 패턴의 생성 패턴(Creational Patterns) 중 싱글턴 패턴(Singleton pattern)입니다 😗

생성 패턴 (Creational patters)

생성 패턴은 객체를 어떻게 생성하는지 다루는 디자인 패턴이다.

생성 패턴에는 두 가지 기본 개념이 있다.

  • 어떤 구체적인 타입이 생성돼야 하는지에 대한 정보를 캡슐화하기
  • 이러한 타입의 인스턴스가 어떻게 생성되는지를 숨기기

생성 패턴 범주의 한 부분으로 널리 알려진 패턴으로는 다섯 가지가 있으며, 이는 다음과 같다.

  • 싱글턴 패턴 (Singleton pattern)
    애플리케이션 주기 동안 하나의 클래스 인스턴스를 허용한다.

  • 빌더 패턴 (Builder pattern)
    복잡한 객체의 생성과 표현을 서로 분리해 유사한 타입을 생성하기 위해 동일한 프로세스가 사용될 수 있게 한다.

  • 팩토리 메소드 패턴 (Factory method pattern)
    객체(또는 객체의 타입)를 어떻게 생성하는지에 대한 근본적인 로직을 노출하지 않으면서 객체를 생성한다.

  • 추상 팩토리 패턴 (Abstract factory pattern)
    구체적인 타입을 명시하지 않으면서 관련된 객체를 생성하기 위한 인터페이스를 제공한다.

  • 프로토타입 패턴 (Prototype pattern)
    이미 존재하는 객체를 복사하는 방식으로 객체를 생성한다


싱글턴 패턴 (Singleton pattern)

아마도 싱글턴 패턴은 사람들 사이에서 말도 많고 탈도 많은 패턴일 것 이다.

이러한 논란에 주된 원인 중 하나는 싱글턴 패턴이 가장 많이 남용되고 오용하는 패턴이기 때문일 것이며,
그 이유는 싱글톤 패턴이 애플리케이션에 정적 상태를 제공하기 때문이다.

정적인 상태는 애플리케이션 내에 어느 지점에서나 객체를 변경시키는 능력을 가지고 있어서
숨겨진 의존성과 강한 결합을 가져온다.

싱글턴 패턴은 언제 사용할까?

싱글턴 패턴은 애플리케이션 라이프 사이클 동안 클래스를 단일 인스턴스로 제한하게 되는데,
이 패턴은 애플리케이션에서 행위를 조직화하기 위해 하나의 인스턴스만 필요로 하는 경우에 매우 유용하다.

예를 들어 이미지 캐싱을 한다고 했을 때, 모든 이미지에 대해서 캐싱을 진행하려면 각각의 페이지마다 해줘야 하지만,
하나의 싱클턴 패턴의 이미지 캐싱 클래스로 관리를 할 수 있다.

이와 같이 싱글턴 패턴은 애플리케이션 생애 동안 어떠한 타입에 대한 유일한 인스턴스가 있어야 하는 문제를 해결하기 위해 설계되었다.
싱글턴 패턴은 대개 내부나 외부 리소스의 집중적 관리가 필요한 경우나 접근할 수 있는 단일 정적 포인트가 필요한 경우에 사용된다.
또한, 싱글턴 패턴을 자주 사용하는 다른 경우는 애플리케이션이 동작하는 내내 필요한 상태를 갖지 않는 연관된 행동들을 통합하고 싶은 경우가 있다.
즉, 전체의 라이프 사이클에서 존재는 오직 하나의 인스턴스(싱글턴 인스턴스)로 각각에 페이지에 존재하는 설정 및 행동을 가지고 관리할 수 있다는 장점이 있다.


싱글턴 패턴 구현하기

class Person {
    static let shared = Person()
    var age = 0
    
    private init() { }
}

코드를 살펴보면 Person 클래스에서 Person 클래스의 인스턴스를 가진 shared 정적 상수를 생성했다.
이 상수를 통해 클래스를 인스터스화 하지 않아도 호출할 수 있으며,
생성자를 private로 생성하므로써 다른 인스턴스를 생성을 막아 애플리케이션 사이프 사이클 내내 오직 하나의 인스턴스만 존재하게 된다.

이제 싱글턴 패턴을 사용해보자.

var person1 = Person.shared
var person2 = Person.shared
var person3 = Person.shared

person1.age = 24 // person1 : 24, person2 : 24, person3 : 24
person2.age = 18 // person1 : 18, person2 : 18, person3 : 18
person3.age = 31 // person1 : 31, person2 : 31, person3 : 31

Person 타입의 세 인스턴스는 모두 동일한 인스턴스를 가리키고 있는 것을 확일 할 수 있다.

주의 사항

애플리케이션에서 해당 타입의 인스턴스가 오직 하나만 존재하게 하는 것을 보장하기 위해
참조(클래스) 타입을 사용해 싱글턴 패턴을 구현했다.

구조체나 열거형과 같은 값 타입으로 이 패턴을 구현했다면 해당 타입이 인스턴스가
여러개 생성되는 상황에 도달했을 것이다.

코드를 다시 호출하면 매번 값 타입의 인스턴스가 전달되는데, 코드에서는 인스턴스의 복사본을 전달하게 된다.
이는 싱글턴 패턴을 값 타입으로 구현하면 타입의 인스턴스가 코드의 다른 곳으로 전달될 때마다
인스턴스의 새로운 복사본을 전달받게 되고, 그로 인해 이 패턴에 의미가 상실되게 된다.


좋은 웹페이지 즐겨찾기