델리게이트 패턴 (Delegate Pattern)

썹스·2023년 1월 1일
0

델리게이트 패턴 (Delegate Pattern)

델리게이트 패턴(위임 패턴)은 서로 다른 객체 간의 원활한 작업 및 원하는 결과를 얻기 위해 만들어진 디자인 패턴입니다.

델리게이트 패턴의 원리를 설명하자면 이래와 같습니다.

위 그림은 A객체만이 할 수 있는 작업(메서드 등)을 B객체가 할 수 있도록 위임해주는 델리게이트 패턴을 간단하게 시각화한 것입니다.

A객체의 작업을 B객체에서도 할 수 있도록 도와주는(연결해주는) 연결고리가 필요한데, 이러한 연결고리 역할을 A객체의 delegate 속성이 하고 있습니다.


📌 델리게이트 패턴 구현

서로 다른 작업을 하는 에어컨 객체리모컨 객체가 있다고 가정한 뒤 코드를 구현해보겠습니다.

  • 에어컨 객체가 하는 일
    • 원하는 온도의 바람 출력
    • 에어컨 필터 청소

  • 리모컨 객체가 하는 일
    • 원하는 온도의 바람 설정
    • 에어컨 필터 청소 설정

✅ 위임 프로토콜 구현

위임 프로토콜을 채택한 타입의 객체만이 프로토콜의 기능(작업)을 수행할 수 있습니다.

@objc protocol AirconRemoteControlDelegate{
    @objc optional func windTemperatureUp()     // 에어컨 바람 온도 조절 기능
    @objc optional func windTemperatureDown()   // 에어컨 바람 온도 조절 기능
    @objc optional func autoFilterCleaning()    // 에어컨 자동 청소 기능
}

✅ 리모컨 타입 구현

리모컨 타입을 정의할 때는 다른 객체에서 리모컨 타입의 작업을 수행할 수 있도록 delegate속성을 정의했습니다.

delegate속성의 타입은 프로토콜 타입(AirconRemoteControlDelegate)으로 정의하여 해당 프로토콜을 채택한 타입의 객체가 작업을 위임받을 수 있도록 해야 합니다.

class AirconRemoteControl{
    // ⭐️ 리모컨 객체의 작업을 에어컨 객체에서도 할 수 있도록 delegate 속성 정의
    var delegate: AirconRemoteControlDelegate? 

    func windTemperatureUp(){    // 바람 온도 올리기
        delegate?.windTemperatureUp!()
    }
    func windTemperatureDown(){  // 바람 온도 내리기
        delegate?.windTemperatureDown!()
    }
    func autoFilterCleaning(){  // 바람 온도 내리기
        delegate?.autoFilterCleaning!()
    }
}

✅ 에어컨 타입 구현

에어컨 타입은 위임 프로토콜(AirconRemoteControlDelegate)을 채택하여 리모컨의 작업을 위임받도록 해야 합니다.

@objc, optional 키워드를 사용하여 프로토콜을 정의했기 때문에 기능을 선택적으로 구현할 수 있습니다.

class Aircon: AirconRemoteControlDelegate{
    func windTemperatureUp() {
        print("삐빅 (에어컨 바람의 온도가 올라갔습니다.)")
    }
    func windTemperatureDown() {
        print("삐빅 (에어컨 바람의 온도가 내려갔습니다.)")
    }
//    func autoFilterCleaning() {  // 생략 가능
//        print("삐빅 (에어컨 필터를 청소합니다.)")
//    }
}

✅ 리모컨의 작업 위임받아 실행

각각의 타입으로부터 생성된 LG에어컨 객체와 LG리모컨 객체는 하는 작업이 서로 다릅니다.

하지만 LG리모컨의 작업을 LG에어컨에게 위임하는 코드(LG_RemoteControl.delegate = LG_Aircon)를 작성하면 에어컨 객체에서도 LG리모컨의 작업을 수행할 수 있습니다.

let LG_RemoteControl = AirconRemoteControl()
let LG_Aircon = Aircon()

//⭐️ 리모컨의 작업을 에어컨에게 위임!! ⭐️  즉, LG_Aircon에서 LG_RemoteControl 작업 실행 가능
LG_RemoteControl.delegate = LG_Aircon    

LG_RemoteControl.windTemperatureUp()    // 삐빅 (에어컨 바람의 온도가 올라갔습니다.)
LG_RemoteControl.windTemperatureDown()  // 삐빅 (에어컨 바람의 온도가 내려갔습니다.)

✅ 종합적인 코드

@objc protocol AirconRemoteControlDelegate{
    @objc optional func windTemperatureUp()     // 에어컨 바람 온도 조절 기능
    @objc optional func windTemperatureDown()
    @objc optional func autoFilterCleaning()    // 에어컨 자동 청소 기능
}

class AirconRemoteControl{
    // 리모컨 객체의 작업을 에어컨 객체에서도 할 수 있도록 delegate 속성 정의
    var delegate: AirconRemoteControlDelegate?

    func doSomething(){
        print("리모컨에 특정 이벤트가 발생했습니다.")
    }

    func windTemperatureUp(){    // 바람 온도 올리기
        delegate?.windTemperatureUp!()
    }
    func windTemperatureDown(){  // 바람 온도 내리기
        delegate?.windTemperatureDown!()
    }
    func autoFilterCleaning(){  // 바람 온도 내리기
        delegate?.autoFilterCleaning!()
    }
}

class Aircon: AirconRemoteControlDelegate{
    func windTemperatureUp() {
        print("삐빅 (에어컨 바람의 온도가 올라갔습니다.)")
    }
    func windTemperatureDown() {
        print("삐빅 (에어컨 바람의 온도가 내려갔습니다.)")
    }
//    func autoFilterCleaning() {  // 생략 가능
//        print("삐빅 (에어컨 필터를 청소합니다.)")
//    }
}

let LG_RemoteControl = AirconRemoteControl()
let LG_Aircon = Aircon()

LG_RemoteControl.delegate = LG_Aircon    //⭐️ 리모컨의 작업을 에어컨에게 위임!! ⭐️  -> LG_Aircon에서 LG_RemoteControl 작업 실행 가능

LG_RemoteControl.windTemperatureUp()    // 삐빅 (에어컨 바람의 온도가 올라갔습니다.)
LG_RemoteControl.windTemperatureDown()  // 삐빅 (에어컨 바람의 온도가 내려갔습니다.)

📢 요약 설명

각각의 타입으로부터 생성된 LG에어컨 객체와 LG리모컨 객체는 하는 작업이 서로 다릅니다.

리모컨의 주된 작업은 에어컨의 온도 설정이고, 에어컨의 주된 작업은 설정된 온도의 바람 출력입니다. (각 객체의 작업은 서로 밀접한 관계를 가지고 있지만 엄연히 다른 성격의 작업입니다)

이제 에어컨 사용자가 리모컨을 사용하여 바람의 온도를 높인다고 가정해보자

에어컨과 리모컨은 서로 다른 객체이기 때문에 에어컨 객체에서 리모컨 객체의 작업을 입력받을 수 없습니다. 즉, 에어컨은 리모컨의 동작(작업)을 알 수 없음

때문에 에어컨 객체에서 리모컨의 온도 설정 작업을 입력받아 사용할 수 있도록 리모컨 작업을 위임받아 사용해야 합니다.

profile
응애 나 코린이(비트코인X 코딩O)

0개의 댓글