중재자 패턴
- 서로 다른 객체의 상호작용을 캡슐화 하는 객체를 정의한다
- 객체들이 서로 의존하지 않고 소결합을 촉진시키는 방법
활용성
- 여러 객체가 잘 정의된 형태이기는 하지만 복잡한 상호작용을 가질 때, 객체간의 의존성이 구조화되지 않으며, 이해가 어려울 때
- 한 객체가 다른 객체를 너무 많이 의존하고, 책임이 너무 많아 그 객체를 사용하기 힘들 때
- 여러 클래스에 분산된 행동들이 상속 없이 상황에 맞게 수정되어야 할 때
구조
요소
- 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)
}
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: "조명 꺼짐")
}
}
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 동작이 이뤄진다.
참고