Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[레벨 0] 7주차 14. 싱글톤 패턴(Singleton Pattern)이란 무엇이며, 어떤 경우에 사용하나요? #14

Open
longlivedrgn opened this issue May 23, 2024 · 3 comments
Assignees
Labels

Comments

@longlivedrgn
Copy link
Contributor

  • 싱글톤 패턴의 장단점은 무엇인가요?
  • 싱글톤 객체의 초기화 방법과 접근 방법을 설명해주세요.
  • 싱글톤 패턴을 구현할 때 주의할 점은 무엇인가요?
  • Swift에서 싱글톤 패턴을 구현할때 멀티스레드에 대해서 어떻게 고려해야하나요?
@longlivedrgn longlivedrgn self-assigned this May 23, 2024
@ueunli
Copy link

ueunli commented May 25, 2024

개요

  • 싱글턴은 Single Instance의 약자로, 싱글턴 패턴이란 한 타입에 대하여 단 하나의 객체만 생성 및 접근 가능하도록 만드는 패턴이다.
  • (클래스에서) 초기화자(들)를 private레벨로 선언하여 직접 생성을 막고, 보통 'shared'라는 네이밍으로 통용되는 타입속성 객체를 하나 제공하는 식으로 구현한다.
  • 단 한 번 초기화되며 계속 같은 객체에 접근함이 보장되므로 멀티스레드 환경에서 유리한 측면도 있으나, 반대로 그렇기에 주의해야 하는 부분도 있다. 동시에 너무 많은 읽기/쓰기가 중첩되면 오히려 thread-safe 하지 못할 수도 있으며, 남용하면 전체적인 의존성 구조를 복잡하게 만드는 주범, 안티패턴이 될 수 있다.

상세

(lazy) static let

(작성 ing)

@SunnnySong
Copy link

1️⃣ 싱글톤 객체의 초기화 방법과 접근 방법을 설명해주세요.

싱글톤

  • Single + Instance
    • 단일의 인스턴스 생성
    • 최초 생성할 때 메모리에 할당하고, 그 이후에는 최초 생성했던 인스턴스의 참조값을 전달한다.

초기화 방법

class SingletonSample {
	static let shared = SingletonSample()
	private init() {}
	
	// ...
}

접근 방법

let singletonSample = SingletonSample.shared

2️⃣ 싱글톤 패턴의 장단점은 무엇인가요?

장점

  • 고정된 메모리 영역을 사용하기 때문에 메모리 낭비를 방지할 수 있다.
  • 전역변수로 선언하기 때문에 다른 인스턴스들과 데이터 공유가 쉽다.

단점

  • 싱글톤 인스턴스에 너무 많은 객체들이 접근할 때, 인스턴스 간 결합도가 높아져 “개방-폐쇠 원칙”을 위배하게 된다.
    • 객체지향 설계 위반
  • 싱글톤 인스턴스는 메모리에 항상 올라와있으며 메모리가 해제되지 않는다는 점에서 단점이 존재한다.

3️⃣ 싱글톤 패턴을 구현할 때 주의할 점은 무엇인가요?

  • 클래스를 사용한다.
  • 만약 열거형, 구조체로 싱글톤을 구현한다면?
    • 싱글톤 인스턴스를 생성할 때마다 매번 다른 메모리 주소를 갖게 된다.
    • == 값타입이기 때문에 싱글톤 구조체 주소를 복사해서 새로운 주소를 갖게 된다.

4️⃣ Swift에서 싱글톤 패턴을 구현할때 멀티스레드에 대해서 어떻게 고려해야하나요?

  • iOS에서는 싱글톤 패턴을 구현할 때, static type property로 선언한다.
  • static let 으로 선언한다면, Dispatch_once와 Thread-safe함을 모두 만족한다.
    • Thread-safe하기 때문에 멀티스레드 환경에서도 안전하게 사용 가능하다.

@soo941226
Copy link

싱글톤 패턴의 장단점은 무엇인가요?

장점으로는 역할에 매칭되는 인스턴스가 메모리에 단 하나만 존재하게 하여 그만큼 메모리를 절약할 수 있는 장점이 있습니다. 또 한번 생성을 해놓으면 계속해서 그 인스턴스를 사용하게 되기 때문에, 복잡한 절차를 통해 생성이 되는 값의 경우, 그 절차가 반복되지 않을 수 있습니다. 그만큼 접근성이 높아져 필요한 기능을 쉽게 끌어다 쓸 수 있게 됩니다.

단점으로는 해당 인스턴스가 동시에 사용이 되는 경우 데이터레이스에 쉽게 노출된다는 것입니다. 또 접근성이 높아지는 만큼 이러한 상황에 더 쉽게 노출됩니다. 그래서 되도록이면 정말 싱글톤이 될 역할인지를 고민하고 사용하는 게 좋습니다.

싱글톤 객체의 초기화 방법과 접근 방법을 설명해주세요.

일반적으로 아래와 같습니다

final class King {
   static let instance: Self = .init()

   private init() { ... }
}

이니셜라이저를 외부에서 접근할 수 없도록 하고, 오로지 타입 프로퍼티로 접근하도록 만듭니다. shared, default등 맥락에 따라 다르게 명명되곤 합니다.

싱글톤 패턴을 구현할 때 주의할 점은 무엇인가요?

OOP의 관점에서 잘 정의하는 게 중요할 것 같은데요. 해당 타입이 정말 싱글톤이 맞는지가 고민되어야할 것 같고, mutating 함수 여부가 또 중요할 것 같습니다. 저라면 없다면 struct로 하고 아니면 class로 할 것 같네요. 쓰고 보니 mutating이 없다면 struct가 아니라 enum으로 하는 것도 또 괜찮겠다는 생각이 갑자기 드네요.

Swift에서 싱글톤 패턴을 구현할때 멀티스레드에 대해서 어떻게 고려해야하나요?

mutating이 발생하지 않는다면 크게 상관이 없는데, 만약 발생한다면, 트랜잭션을 빗대어 표현하면 원자성과 고립성을 지키는 게 굉장히 어려워집니다. 레이스 컨디션이 발생할 수 있다는 건데요. 이런 일을 하지 않는 타입을 만들 필요가 있는데, 하다 보면 점점 코드가 비대해지기 때문에 싱글톤 바깥에서 일을 처리하려고 하면 또 굉장히 까다로운 일이 됩니다. 결국 내부적으로 각 절차들의 동기화가 필요한데, 세마포어를 집어넣거나 async-await을 사용하거나 하는 방법이 필요할 것 같네요.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants