[Swift] Mediator Pattern
Mediator Pattern
✅ Mediator Pattern
아래의 문서를 구입하여 영어 문서를 번역하고 이해한 것을 바탕으로 글을 작성하고 있습니다.
https://www.raywenderlich.com/books/design-patterns-by-tutorials/v3.0/chapters/19-mediator-pattern
중재자 패턴은 객체가 서로 통신하는 방법을 캡슐화하는 동작 설계 패턴이다. 여기에는 4가지 타입이 있다.
1. colleagues는 서로 소통하기 원하는 객체이다. colleague 프로토콜로 구현한다.
2. colleague protocol은 각 colleague가 구현해야하는 방법과 속성을 정의합니다.
3. mediator는 colleagues의 소통을 컨트롤하는 객체이다. 이것은 mediator 프로토콜로 구현한다.
4. mediator protocol은 mediator가 구현해야하는 메소드와 프로퍼티를 정의한다.
각각의 colleague는 mediator protocol을 통해서 mediator를 참조합니다. 다른 colleague와 직접 소통하는 대신 mediator를 통해서 소통합니다. mediator는 colleague간의 소통을 촉진합니다.
When should you use it?
mediator 패턴은 상호 작용을 객체 즉, mediator로 분리하는데 유용합니다.
이 패턴은 다른 colleague가 시작한 이벤트에 대해 한 명 이상의 동료가 작업해야 하고, 이 colleague가 다른 colleague에게 영향을 미치는 추가 이벤트를 생성하도록 하는 경우에 특히나 유용합니다.
Playground example
NOTE: - 기본적으로 Mediator를 사용하지 않아도 기술적으로 Mediator 패턴을 구현할 수 있지만, 그렇게 할 경우 훨씬 더 많은 보일러 플레이트 코드를 작성할 수 있습니다. 'Multicast Delegate Pattern'을 통해 작업한 경우, Mediator 클래스가 Multicast Delegate클래스와 유사하지만 이를 고유하게 만드는 몇 가지 주요 차이점이 있음을 알 수 있습니다.
✅ 해당 코드는 아래 참고에 있는 블로그의 코드를 참고하였습니다.
문서의 예시는 Mediator를 weak와 strong 프로퍼티로 나누어서 사용한다는 것을 제외하고는 아래 코드가 더 이해가 쉽습니다.
import UIKit
// Mediator
protocol Mediator {
func notify(sender: Colleague, event: EventType)
}
enum EventType {
case checkBoxSelect
case checkBoxUnselect
}
// Base Colleague
class Colleague {
var mediator: Mediator?
func setMediator(mediator: Mediator) {
self.mediator = mediator
}
}
// Collegue
class CheckBox: Colleague {
var isSelect: Bool = false {
didSet {
if isSelect {
print("CheckBox 선택")
} else {
print("CheckBox 선택 해제")
}
}
}
func checkBoxClick() {
self.isSelect = !self.isSelect
if self.isSelect {
self.mediator?.notify(sender: self, event: .checkBoxSelect)
} else {
self.mediator?.notify(sender: self, event: .checkBoxUnselect)
}
}
}
// Collegue
class TextField: Colleague {
var isHidden: Bool = true {
didSet {
if isHidden {
print("TextField 비활성화")
} else {
print("TextField 활성화")
}
}
}
}
// Concrete Mediator
class ProfileUI: Mediator {
var checkBox: CheckBox
var textField: TextField
init(checkBox: CheckBox, textField: TextField) {
self.checkBox = checkBox
self.textField = textField
self.checkBox.setMediator(mediator: self)
self.textField.setMediator(mediator: self)
}
func notify(sender: Colleague, event: EventType) {
switch event {
case .checkBoxSelect:
self.textField.isHidden = false
case .checkBoxUnselect:
self.textField.isHidden = true
}
}
}
let checkBox = CheckBox()
let textField = TextField()
let profileUI = ProfileUI(checkBox: checkBox, textField: textField)
profileUI.checkBox.checkBoxClick()
profileUI.checkBox.checkBoxClick()
What should you be careful about?
이 패턴은 colleague끼리 디커플링 하는데 유용합니다. 직접 상호작용 하는 대신 각 동료들은 중재자를 이용합니다. 그러나 이를 'god' obbject로 만드는 것에 주의해야 합니다. 그러니까 여기에 다 때려박으면 관리가 어려워집니다. mediator가 커지면 분할하거나 다른 패턴 혹은 중재자의 기능 일부를 delegate패턴을 적용하거나 위임하는 등의 기법을 고려하세요!
Key points
이 패턴은 객체들이 서로 소통하는 방법을 캡슐화 합니다. 네가지 유형이 포함됩니다. 글 위부분을 봐주세요.
colleague 프로토콜은 모든 colleague가 가져야할 프로퍼티와 메소드를 정의하고 mediator는 통신을 컨트롤하며, mediator 프로토콜은 mediator가 반드시 해야할 프로퍼티와 메소드를 정의합니다.
직접 소통하는 대신에 중재자를 통해서 소통하세요!! 이렇게 하면 객체 간의 긴밀한 결합을 끊는데 도움이 됩니다.
(참고)
https://icksw.tistory.com/254?category=944177