Delegate 패턴과 Notification 의 차이 및 특징

Delegate 패턴과 Notification 의 차이 및 특징

Delegate패턴

  • 객체 간의 일대일 통신을 가능하게 한다.
  • 한 객체가 다른 객체로 작업을 위임할 수 있도록 대리자를 설정한다.
  • 주로 프로토콜을 사용하여 델리게이트 메서드를 정의하고, 델리게이트 객체는 이를 채택하여 실제 작업을 구현한다.
// 프로토콜 정의
protocol DataProviderDelegate: AnyObject {
    func didReceiveData(_ data: String)
}

// 데이터를 제공하는 객체
class DataProvider {
    weak var delegate: DataProviderDelegate?
    
    func fetchData() {
        let data = "Some data fetched from server"
        delegate?.didReceiveData(data)
    }
}

// 델리게이트를 채택하는 객체
class ViewController: UIViewController, DataProviderDelegate {
    let dataProvider = DataProvider()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        dataProvider.delegate = self
        dataProvider.fetchData()
    }
    
    func didReceiveData(_ data: String) {
        print("Received data: \\(data)")
    }
}
  • Delegate 패턴은 객체간의 일대일 통신을 가능하게 한다.
  • 델리게이트 객체는 다른 객체의 동작을 커스터마이징하고 확장할 수 있다.
  • 델리게이트 패턴은 프로토콜을 통해 타입 안정성을 보장한다.

객체 간의 일대일 통신이 필요한 경우, 객체간의 결합도를 낮추고 유연성을 높이고 싶은 경우 사용한다.

Notification

애플 공식 문서에는 이렇게 적혀있다.

A notification dispatch mechanism that enables the broadcast of information to registered observers. (등록된 Observer들에게 정보를 BroadCast할 수 있는 알림 발송 메커니즘)

  • 한 객체가 다른 객체에게 메시지를 보낼 때 사용 한다.
  • 다수의 객체가 메시지를 라디오 방송 하듯 브로드 캐스트하여 통신한다.
  • NotificationCenter 를 통해 메세지를 보내고 받는다.
extension Notification.Name {
    static let didReceiveData = Notification.Name("DidReceiveData")
}

class DataProvider {
    func fetchData() {
        let data = "Some data fetched from server"
        NotificationCenter.default.post(name: .didReceiveData, object: nil, userInfo: ["data": data])
    }
}

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        NotificationCenter.default.addObserver(self, selector: #selector(handleData(_:)), name: .didReceiveData, object: nil)
    }
    
    @objc func handleData(_ notification: Notification) {
        if let data = notification.userInfo?["data"] as? String {
            print("Received data: \\(data)")
        }
    }
}
  • Notification은 양방향 통신을 지원하여 한 이벤트에 여러 객체가 반응할 수 있도록 한다.
  • 느슨한 결합으로 객체간의 의존성을 줄이고 재사용성을 높일 수 있다는게 장점이다.
  • Notification은 비동기적으로 동작하므로, 비동기 처리가 필요한 경우에 적합하다.

한 이벤트에 여러 객체가 반응해야하는 경우에 사용되며 객체간의 결합도를 최소화하고 느슨한 결합을 유지하고 싶을 때 사용된다.


정리

먼저 두 방식 모두 객체간의 소통을 위해 만들어졌습니다. 특정 이벤트가 발생하면 원하는 객체에 해당 사항을 전달해서 특정처리를 수행하도록 구성됩니다.

 

delegate 방식은 주로 이벤트를 1:1로 전달할 때 많이 사용됩니다. 주로 protocol을 정의하고 이를 이벤트를 대신 처리할 객체가 채택하여 사용하게 됩니다. 이에 따라 제 3 객체를 필요로 하지 않으며 확실한 처리가 가능하지만, 많은 줄의 코드를 필요로 하며 많은 객체에게 이벤트를 알리고 싶을 경우 비효율적이라는 단점이 있습니다.

 

notification 방식은 이벤트를 1:N으로 전달할 때 용이합니다. NotificationCenter라는 싱글톤객체를 기반으로 이벤트 발생여부를 옵저버를 등록한 객체에게 전달하는 방식으로 구성됩니다.

 

따라서 다수의 객체에게 손쉽게 이벤트 전달이 가능합니다. 하지만 제 3 객체를 필수적으로 필요로 하며, key값으로 Notification의 이름을 사용하기 때문에 컴파일 중 구독이 제대로 이루어져있는지 확인할 수 없다는 단점이 존재합니다.