1. 델리게이트 패턴(Delegate Pattern)의 목적
델리게이트 패턴은 어떤 객체의 행동을 다른 객체에 위임하기 위해 사용되는 패턴이에요. iOS에서 자주 사용되며, 특정 객체가 해야 할 일을 다른 객체가 대신 처리하도록 할 수 있어요. 이를 통해 코드의 재사용성을 높이고, 객체 간의 결합도를 낮출 수 있죠.
예시:
예를 들어, Car라는 클래스가 있다고 해볼게요. 이 클래스는 엔진을 켤 수 있어요. 그런데 엔진이 켜질 때마다 누군가에게 이 사실을 알리고 싶다면, 그 알림 로직을 Car 클래스 안에 다 넣지 않고, 다른 객체에게 그 일을 맡길 수 있어요. 여기서 델리게이트 패턴을 사용하면 이런 식으로 구현할 수 있어요
protocol CarDelegate {
func engineDidStart()
}
class Car {
var delegate: CarDelegate?
func startEngine() {
print("엔진이 켜졌습니다")
delegate?.engineDidStart()
}
}
class Driver: CarDelegate {
func engineDidStart() {
print("운전자가 알림을 받았습니다: 자동차 엔진이 켜졌어요!")
}
}
let myCar = Car()
let driver = Driver()
myCar.delegate = driver
myCar.startEngine()
이 예시에서는, 자동차의 엔진이 켜지면 Driver가 델리게이트로서 그 사실을 알림받아요.
2. 델리게이트 패턴과 콜백 함수의 차이점
콜백 함수와 델리게이트 패턴은 둘 다 비슷한 역할을 해요. 어떤 작업이 끝났을 때 알림을 받는 방법이에요. 하지만 두 가지 주요 차이점이 있어요.
- 콜백 함수는 특정 작업이 끝났을 때 함수 자체가 호출되는 방식이에요. 간단하고, 작은 작업을 처리할 때 유용해요.
- 델리게이트 패턴은 객체 전체가 특정 작업을 대신 처리할 수 있게 해주는 패턴이에요. 더 복잡한 작업이나 여러 종류의 작업을 할 때 유용해요.
// 콜백 함수 사용 예시
func fetchData(completion: () -> Void) {
// 데이터를 가져오는 작업
print("데이터를 가져오는 중...")
completion()
}
fetchData {
print("데이터를 가져왔어요! 이제 사용할 수 있어요.")
}
// 델리게이트 패턴 사용 예시
protocol DataDelegate {
func didFetchData()
}
class DataFetcher {
var delegate: DataDelegate?
func fetchData() {
print("데이터를 가져오는 중...")
delegate?.didFetchData()
}
}
class DataManager: DataDelegate {
func didFetchData() {
print("데이터를 가져왔어요! 이제 사용할 수 있어요.")
}
}
let dataFetcher = DataFetcher()
let dataManager = DataManager()
dataFetcher.delegate = dataManager
dataFetcher.fetchData()
3. 델리게이트 패턴과 옵저버 패턴의 차이점 및 사용 시기
- 델리게이트 패턴은 한 객체가 다른 객체에게 특정 작업을 위임하는 경우에 사용돼요. 즉, 델리게이트는 하나의 객체와 하나의 델리게이트가 존재해요.
- 옵저버 패턴은 여러 객체가 특정 이벤트에 대해 관찰하고 있다가, 그 이벤트가 발생하면 모두에게 알리는 방식이에요. 여러 객체가 동시에 변화나 상태를 관찰할 때 유용해요.
예시:
WeatherStation이라는 객체가 온도 변화를 보고한다고 가정해볼게요.
- 델리게이트 패턴을 사용하면, 온도 업데이트를 처리하는 하나의 특정 객체만 존재하게 돼요
protocol TemperatureDelegate {
func didUpdateTemperature(_ temperature: Int)
}
class WeatherStation {
var delegate: TemperatureDelegate?
func updateTemperature() {
let newTemperature = 30
delegate?.didUpdateTemperature(newTemperature)
}
}
class Display: TemperatureDelegate {
func didUpdateTemperature(_ temperature: Int) {
print("현재 온도는 \(temperature)°C입니다")
}
}
let station = WeatherStation()
let display = Display()
station.delegate = display
station.updateTemperature()
- 옵저버 패턴을 사용하면, 여러 객체가 온도 변화를 관찰하고, 업데이트 시 동시에 알림을 받을 수 있어요
class WeatherStation {
var observers = [Observer]()
func addObserver(_ observer: Observer) {
observers.append(observer)
}
func updateTemperature() {
let newTemperature = 30
for observer in observers {
observer.didUpdateTemperature(newTemperature)
}
}
}
protocol Observer {
func didUpdateTemperature(_ temperature: Int)
}
class Display: Observer {
func didUpdateTemperature(_ temperature: Int) {
print("Display: 현재 온도는 \(temperature)°C입니다")
}
}
class Logger: Observer {
func didUpdateTemperature(_ temperature: Int) {
print("Logger: 온도를 \(temperature)°C로 기록했습니다")
}
}
let station = WeatherStation()
let display = Display()
let logger = Logger()
station.addObserver(display)
station.addObserver(logger)
station.updateTemperature()
이 예시에서는 Display와 Logger 두 객체가 모두 온도 변화를 알림받고, 각각 자신의 방식으로 그 정보를 처리해요.
4. 델리게이트 메서드에서 반환값을 사용하는 경우
때로는 델리게이트 메서드에서 반환값을 사용해, 호출자에게 결과를 돌려줘야 할 때가 있어요. 이 방법을 통해 델리게이트는 단순히 알리는 역할뿐 아니라, 호출자에게 결과나 데이터를 돌려줄 수 있어요.
예시:
예를 들어, Restaurant 클래스가 있고, 이 클래스가 Customer에게 무얼 주문할지 물어보는 상황을 생각해볼게요
protocol RestaurantDelegate {
func orderFood() -> String
}
class Restaurant {
var delegate: RestaurantDelegate?
func takeOrder() {
if let order = delegate?.orderFood() {
print("주문이 접수되었습니다: \(order)")
} else {
print("주문이 접수되지 않았습니다.")
}
}
}
class Customer: RestaurantDelegate {
func orderFood() -> String {
return "파스타"
}
}
let restaurant = Restaurant()
let customer = Customer()
restaurant.delegate = customer
restaurant.takeOrder()
이 예시에서, Customer는 어떤 음식을 주문할지 Restaurant에게 알려주고, 식당은 그 주문을 처리해요.
정리
- 델리게이트 패턴: 객체의 책임을 다른 객체에게 위임하고, 주로 하나의 객체가 델리게이트로 설정돼요.
- 콜백 함수: 특정 작업이 끝났을 때 호출되는 함수로, 단순한 작업에 적합해요.
- 옵저버 패턴: 여러 객체가 이벤트를 관찰하고, 모두에게 알리는 방식이에요.
- 반환값을 사용하는 델리게이트 메서드: 호출자에게 결과나 데이터를 돌려줄 때 유용해요.
'정보 > 레벨 1' 카테고리의 다른 글
Swift에서 프로토콜(Protocol)이란 무엇이며, 어떻게 활용하나요? (0) | 2024.11.11 |
---|---|
iOS 앱에서 데이터를 저장하는 방법에는 어떤 것들이 있나요? (1) | 2024.11.10 |
Swift의 기본 데이터 타입과 컬렉션(Collection) 타입에는 어떤 것들이 있나요? (0) | 2024.11.10 |
Auto Layout을 사용하는 이유와 장점은 무엇인가요? (1) | 2024.10.31 |
Swift에서 클로저(Closure)란 무엇이며, 어떻게 사용하나요? (0) | 2024.08.21 |