[디자인 패턴] Singleton Pattern

전성훈·2023년 10월 31일
1

DesignPattern

목록 보기
3/18
post-thumbnail

주제: 애플리케이션에서 단 하나만의 객체를 나타낼 때


Singleton

  • 싱글턴 패턴은 계속해서 다른 요청이 있더라도 무조건 같은 인스턴스를 방출한다. 즉, 싱글턴은 '특정 클래스의 인스턴스가 오직 하나임을 보장하는 객체'를 의미한다.
  • 싱글턴은 애플리케이션이 요청한 횟수와는 관계없이 이미 생성된 같은 인스턴스를 반환한다.
  • 애플리케이션 내에서 특정 클래스의 인스턴스가 딱 하나만 있기 때문에 다른 인스턴스를이 공유해서 사용할 수 있다.
    singleton

사용 용도

  • 전역적으로 공유된 리소스나 설정이 필요로 할 때
  • 클래스의 인스턴스가 한 개만 존재해야 할 때
  • 여러 번 생성될 경우 메모리 낭비, 성능 저하가 발생할 때

일반적인 구현 방법

  1. 생성자를 private로 선언하여 외부에서 인스턴스 생성을 제한한다.
  2. 클래스 내부에 인스턴스를 저장할 static 변수를 선언한다.
  3. 인스턴스에 접근할 수 있는 static 메서드를 제공한다. 이 메서드에서 인스턴스가 생성되지 않았다면 생성하고, 이미 생성되어 있다면 해당 인스턴스를 반환한다.

장단점

  • 싱글턴 패턴은 유일한 객체를 만들어서 다양한 객체들에게 공유되는 객체를 만들 수 있다는 장점이 있다. 또한 재사용이 가능하여 메모리 낭비를 방지할 수 있다는 장점도 있다.
  • 그러나 싱글턴 패턴은 객체지향 관점에서 본다면 인스턴스들 간에 결합도가 높아져서 OCP(개방-폐쇄 원칙, Open-Closed Principle)을 위배하게 된다는 단점이 있다.

구현 예시

Singleton 틀 만들기

class SingleTon { 
	static let shared = SingleTon()
	
	private init() { }
}
  • shared라는 static 변수가 SingleTon 인스턴스를 저장하며, 생성자는 private로 선언되어 외부에서 인스턴스 생성이 제한된다.
  • 이제 애플리케이션 내의 어디서든 Singleton.shared를 통해 해당 인스턴스에 접근할 수 있다.

예시 코드

import UIKit

enum Milk {
    case chocolate
    case strawberry
    case banana
}

// Singleton
class MilkStorage {
    static let shared = MilkStorage()
    
    private var chocoloateMilkCount = 100
    private var strawberryMilkCount = 100
    private var bananaMilkCount = 100
    
    private init() { }
    
    func release(_ milk: Milk, count: Int) {
        switch milk {
        case .chocolate:
            chocoloateMilkCount -= count
        case .strawberry:
            strawberryMilkCount -= count
        case .banana:
            bananaMilkCount -= count
        }
    }
    
    func checkMilkCount() {
        print("""
            - 남은 재고 -
             1. 초코 우유: \(chocoloateMilkCount)
             2. 딸기 우유: \(strawberryMilkCount)
             3. 바나나 우유: \(bananaMilkCount)
            """)
    }
}


class OnlineStore {
    func orderMilk(_ milk: Milk, count: Int) {
        MilkStorage.shared.release(milk, count: count)
    }
}

let naverSmartStore = OnlineStore()
let coupang = OnlineStore()
let weMakePrice = OnlineStore()

naverSmartStore.orderMilk(.banana, count: 15)

MilkStorage.shared.checkMilkCount()

Cocoa framework에서의 Singleton Design pattern

FileManager

  • 애플리케이션 파일 시스템을 관리하는 클래스이다.
  • 파일 시스템과 상호작용하기 위한 기능을 제공하는 클래스이다.
  • FileManager는 애플리케이션에서 파일 및 디렉토리를 생성, 복사, 이동, 삭제 등의 작업을 수행할 수 있다.
  • FileManager.default
let fileManager = FileManager.default 
let fileExists = fileManager.fileExists(atPath: "/path/to/file.txt")

URLSession

  • URL 세션을 관리하는 클래스이다.
  • 네트워크 작업을 수행하는 데 사용되는 클래스이다.
  • 애플리케이션 전반에서 공유되는 세션 인스턴스를 제공하여 네트워크 요청을 처리하고 응답을 받아온다. 이를 통해 여러 곳에서 동일한 세션을 사용하여 네트워크 작업을 수행할 수 있다.
  • URLSesssion.shared
let session URLSession.shared 
session.dataTask(with: url) { (data, response, error) in 
	// 네트워크 작업 수행
}.resume() 

NotificationCenter

  • 등록된 알림을 정보를 사용할 수 있게 해주는 클래스이다.
  • 애플리케이션 내에서 이벤트를 발송하고 수신하기 위한 중앙 집중식 통지 시스템이다.
  • Notification.default
NotificationCenter.default.addObserver(self, selector: #selector(tap), name: Notification.Name("Test"), object: nil )
NotificationCenter.default.post(name: Notifiaction.Name("Test"), object: nil)

UserDefaults

  • 간단한 데이터를 앱에 영구적으로 저장하는 데 사용되는 인터페이스이다.
  • UserDefaults는 애플리케이션의 설정, 사용자 기본값, 간단한 상태 등을 저장하기에 유용하다.
  • Key-Value 형태로 간단한 데이터를 저장하고 관리할 수 있는 인터페이스를 제공하는 데이터베이스 클래스이다.
  • UserDefaults.standard
UserDefaults.standard.set("Jeon", forKey: "User")
let user = UserDefaults.standard.string(forKey: "User")

UIApplication

  • ios에서 실행되는 중앙제어 애플리케이션 객체이다.
  • 애플리케이션의 실행과 상태 관리를 담당하는 클래스이다. UIApplication은 앱의 주요 이벤트와 상태 변화를 처리하고, 앱의 라이프사이클에 따른 동작을 수행한다.
  • UIApplication.shared
let application = UIApplication.shared
application.openURL(url)

출처(참고문헌)

제가 학습한 내용을 요약하여 정리한 것입니다. 내용에 오류가 있을 수 있으며, 어떠한 피드백도 감사히 받겠습니다.

감사합니다.

0개의 댓글