VesselWheel

싱글톤 패턴과 델리게이트 패턴 적용에 대한 고찰(with 날씨, 위치 데이터) 본문

Xcode Study

싱글톤 패턴과 델리게이트 패턴 적용에 대한 고찰(with 날씨, 위치 데이터)

JasonYang 2024. 2. 9. 16:09

`WeatherManager`와 `LocationManager`를 싱글톤 패턴으로 사용할지, 델리게이트 패턴으로 사용할지는 애플리케이션의 요구 사항과 구조에 따라 달라집니다.

각 패턴의 특성을 이해하고 그에 따른 장단점을 고려하여 결정하시는 것이 좋습니다.

 

**싱글톤 패턴**은 클래스의 인스턴스가 하나만 생성되고, 어디서든지 그 인스턴스에 접근할 수 있도록 하는 디자인 패턴입니다.

장점:

- 공유 리소스에 대한 동기화된 접근을 제공합니다.

- 메모리 사용을 최적화할 수 있습니다.

- 전역 상태 관리에 효과적입니다.

 

단점:

- 전역 상태를 변경하면 애플리케이션 전체에 영향을 미치므로 사이드 이펙트를 일으킬 수 있습니다.

- 테스팅이 어려울 수 있습니다.

더보기

Xcode에서 싱글톤 패턴이 나온 이유는 다음과 같습니다:

1. 공유 인스턴스: 싱글톤 패턴은 애플리케이션 전역에서 단일 인스턴스를 공유하고 접근할 수 있도록 합니다. 이는 여러 컴포넌트나 객체 간에 데이터를 공유하고 동일한 리소스에 접근해야 할 때 유용합니다. 예를 들어, 로그인 정보, 애플리케이션 설정 등의 데이터를 여러 곳에서 사용해야 할 경우 싱글톤 패턴을 사용하여 하나의 인스턴스에 접근할 수 있습니다.

 

2. 전역 상태 관리: 애플리케이션의 전역 상태를 관리하기 위해 싱글톤 패턴을 사용할 수 있습니다. 전역 상태는 다양한 컴포넌트에서 필요한 정보이며, 싱글톤을 사용하여 중앙 집중식으로 상태를 관리하고 업데이트할 수 있습니다. 이는 상태의 일관성을 유지하고 응용 프로그램 전반에서 공유되는 데이터를 쉽게 관리할 수 있도록 도와줍니다.

 

3. 리소스 접근 제어: 싱글톤 패턴은 특정 리소스에 대한 접근을 제어하는 데 사용될 수 있습니다. 예를 들어, 파일 시스템 또는 네트워크 연결과 같은 리소스에 대한 중복된 접근이 발생하지 않도록 싱글톤을 사용하여 접근을 조절할 수 있습니다. 이는 리소스의 공유 및 동기화 문제를 해결하고, 애플리케이션에서 발생하는 충돌이나 부작용을 방지하는 데 도움이 됩니다.

 

4. 효율성과 성능: 싱글톤 패턴은 인스턴스를 한 번만 생성하고 재사용함으로써 메모리 및 자원 사용을 최적화할 수 있습니다. 여러 곳에서 동시에 같은 인스턴스에 접근할 필요가 없으므로, 인스턴스 생성 및 초기화에 소요되는 비용을 줄일 수 있습니다. 이러한 이유로 싱글톤 패턴은 Xcode 및 기타 개발 환경에서 널리 사용되며, 애플리케이션의 구조적인 설계와 데이터 관리를 개선하는 데 도움이 됩니다. 

**델리게이트 패턴**은 객체 간의 소통을 위한 디자인 패턴으로, 한 객체가 모든 일을 스스로 처리하는 것이 아니라 처리해야 할 일 중 일부를 위임하여 다른 객체가 처리하도록 합니다.

장점:

- 클래스 간의 결합도를 낮춥니다.

- 객체 간의 상호작용을 유연하게 만듭니다.

- 확장성이 좋습니다.

 

단점:

- 설계가 복잡해질 수 있습니다.

- 델리게이트 체인이 길어질수록 추적하기 어려워집니다.

 

따라서, `WeatherManager`와 `LocationManager`를 싱글톤으로 사용하는 것이 좋을지, 델리게이트 패턴을 사용하는 것이 좋을지는 애플리케이션의 전체적인 구조와 요구 사항을 고려하여 결정해야 합니다.

 


참고 빌더 패턴

- 내가 원하고자하는 매소드를 사전에 프로퍼티를 선언하고 조립식으로 빌더로 조합하는 것

class WeatherManagerBuilder {
    private var apiKey: String?
    private var location: (latitude: Double, longitude: Double)?
    private var city: String?
    private var threeHourForecast: Bool = false
    private var fiveDayForecast: Bool = false
    
    func setApiKey(_ apiKey: String) {
        self.apiKey = apiKey
    }
    
    func setLocation(latitude: Double, longitude: Double) {
        self.location = (latitude, longitude)
    }
    
    func setCity(_ city: String) {
        self.city = city
    }
    
    func enableThreeHourForecast() {
        self.threeHourForecast = true
    }
    
    func enableFiveDayForecast() {
        self.fiveDayForecast = true
    }
    
    func build() -> WeatherManager {
        guard let apiKey = apiKey else {
            fatalError("Incomplete builder: apiKey must be set.")
        }
        let manager = WeatherManager(apiKey: apiKey)
        if let location = location {
            manager.setLocation(latitude: location.latitude, longitude: location.longitude)
        }
        if let city = city {
            manager.setCity(city)
        }
        if threeHourForecast {
            manager.enableThreeHourForecast()
        }
        if fiveDayForecast {
            manager.enableFiveDayForecast()
        }
        return manager
    }
}

// 클라이언트 코드
let builder = WeatherManagerBuilder()
builder.setApiKey("your_api_key")
builder.setLocation(latitude: 37.7749, longitude: -122.4194)
builder.setCity("San Francisco")
builder.enableThreeHourForecast()
let weatherManager = builder.build()