Gof의 디자인 패턴 - 중재자 패턴

Groot·2024년 7월 14일
0

TIL

목록 보기
148/153
post-thumbnail

중재자 패턴

  • 서로 다른 객체의 상호작용을 캡슐화 하는 객체를 정의한다
  • 객체들이 서로 의존하지 않고 소결합을 촉진시키는 방법

활용성

  • 여러 객체가 잘 정의된 형태이기는 하지만 복잡한 상호작용을 가질 때, 객체간의 의존성이 구조화되지 않으며, 이해가 어려울 때
  • 한 객체가 다른 객체를 너무 많이 의존하고, 책임이 너무 많아 그 객체를 사용하기 힘들 때
  • 여러 클래스에 분산된 행동들이 상속 없이 상황에 맞게 수정되어야 할 때

구조

요소

  • Mediator: Colleague 객체와 교류하는 데 필요한 인터페이스를 정의
  • ConcreteMediator: Colleague 객체와 조화를 이뤄 협력 행동을 구현, 자신이 맡을 Colleague를 파악하고 관리한다.
  • Colleague 객체들: 자신의 중재가 객체가 무엇인지 파악, 다른 객체와 통신이 필요하면 그 중재자를 통해 통신한다.

협력 방법

  • Colleague는 Mediator에서 요청을 송수신한다. Mediator는 필요한 Colleague사이에 요청을 전달할 의무가 있다.

장점

  • Colleague를 재사용할 수 있다.
  • 일 대 다의 관계로 이해가 쉽고 유지보수에 용이하다.
  • 객체 간의 협력 방법을 추상화할 수 있다.(Mediator)

단점

  • 중재자 객체가 모든 상호작용을 캡슐화하기 대문에 복잡해질 수 있다. Mediator의 유지보수가 어려울 수 있다.(적절한 추상화가 필요할 듯)

예시 코드

import Foundation

// 중재자 프로토콜 정의
protocol SmartHomeMediator {
    func notify(sender: DeviceProtocol, event: String)
}

// 장치 프로토콜 정의
protocol DeviceProtocol {
    var mediator: SmartHomeMediator { get }
    func send(event: String)
}

// 조명 장치 클래스 정의 -> SmartHomeMediator에 의존
class Light: DeviceProtocol {
    var mediator: SmartHomeMediator
    
    init(mediator: SmartHomeMediator) {
        self.mediator = mediator
    }
    
    func send(event: String) {
        mediator.notify(sender: self, event: event)
    }
    
    func turnOn() {
        print("조명이 켜졌습니다.")
        send(event: "조명 켜짐")
    }
    
    func turnOff() {
        print("조명이 꺼졌습니다.")
        send(event: "조명 꺼짐")
    }
}

// 온도 조절기 장치 클래스 정의 -> SmartHomeMediator에 의존
class Thermostat: DeviceProtocol {
    var mediator: SmartHomeMediator
    
    init(mediator: SmartHomeMediator) {
        self.mediator = mediator
    }
    
    func send(event: String) {
        mediator.notify(sender: self, event: event)
    }
    
    func setTemperature(_ temperature: Double) {
        print("온도 조절기가 \(temperature)도로 설정되었습니다.")
        if temperature > 25 {
            send(event: "온도 높음")
        } else {
            send(event: "온도 정상")
        }
    }
    
    func turnOff() {
        print("온도 조절기가 꺼졌습니다.")
        send(event: "온도 조절기 꺼짐")
    }
}

// 중재자 클래스 구현
class HomeMediator: SmartHomeMediator {
    private var light: Light?
    private var thermostat: Thermostat?
    
    func setLight(_ light: Light) {
        self.light = light
    }
    
    func setThermostat(_ thermostat: Thermostat) {
        self.thermostat = thermostat
    }
    
    func notify(sender: DeviceProtocol, event: String) {
        if sender is Light {
            if event == "조명 켜짐" {
                print("중재자가 조명 켜짐 이벤트에 반응하여 다음 작업을 수행합니다:")
                thermostat?.setTemperature(22) // 조명이 켜지면, 편안한 온도로 설정
            } else if event == "조명 꺼짐" {
                print("중재자가 조명 꺼짐 이벤트에 반응하여 다음 작업을 수행합니다:")
                thermostat?.turnOff() // 조명이 꺼지면, 온도 조절기 끄기
            }
        } else if sender is Thermostat {
            if event == "온도 높음" {
                print("중재자가 온도 높음 이벤트에 반응하여 다음 작업을 수행합니다:")
                light?.turnOff() // 온도가 높으면, 조명 끄기
            } else if event == "온도 정상" {
                print("중재자가 온도 정상 이벤트에 반응하여 다음 작업을 수행합니다:")
                light?.turnOn() // 온도가 정상일 때, 조명 켜기
            }
        }
    }
}

// 사용 예제
let mediator = HomeMediator()

let light = Light(mediator: mediator)
let thermostat = Thermostat(mediator: mediator)

mediator.setLight(light)
mediator.setThermostat(thermostat)

light.turnOn() // 조명이 켜지면, 중재자가 온도 조절기를 조정
thermostat.setTemperature(28) // 온도가 높으면, 중재자가 조명을 끔
  • SmartHomeMediator에 의존하는 Light와 Thermostat 객체
  • HomeMediator를 통해서 turnOn 동작과 setTemperature 동작이 이뤄진다.

참고

profile
I Am Groot

0개의 댓글