중재자(Mediator) 패턴
중재자(Mediator) 패턴은 여러 객체들 간의 직접적인 상호작용을 중재자 객체에 위임하여 객체 간의 결합도를 줄이는 행동 디자인 패턴입니다. 이 패턴에서는 중재자 객체가 각 객체들의 상호작용을 관리하며, 객체들은 직접 통신하지 않고 중재자를 통해서만 통신합니다.
문제점: 객체 간의 직접적인 의존성으로 인한 복잡성 증가
여러 객체가 서로 직접 참조하며 통신하면 결합도가 높아지고 유지보수가 어렵습니다. 예를 들어, GUI 애플리케이션에서 버튼, 텍스트 필드, 체크박스 등이 서로 간섭하며 상호작용할 경우 코드가 복잡해지고 확장하기 어려워집니다.
class TextBox {
public void clear() {
System.out.println("TextBox cleared");
}
}
class Button {
private TextBox textBox;
public void setTextBox(TextBox textBox) {
this.textBox = textBox;
}
public void click() {
textBox.clear(); // 버튼이 텍스트 필드를 직접 조작
}
}
public class Main {
public static void main(String[] args) {
Button button = new Button();
TextBox textBox = new TextBox();
button.setTextBox(textBox);
button.click(); // TextBox cleared
}
}
문제점
- 결합도 증가: Button과 TextBox가 서로 직접 참조합니다.
- 유연성 부족: 새로운 UI 요소를 추가하거나 수정하려면 기존 코드를 변경해야 합니다.
- 확장성과 유지보수성 저하: 객체 간의 의존성이 많아지면 코드가 복잡해집니다.
해결 방법: 중재자 패턴 적용
중재자 패턴에서는 각 객체가 중재자 객체와만 통신하며, 중재자가 모든 상호작용을 관리합니다. 이를 통해 객체 간의 직접적인 의존성을 제거하고 유연성과 확장성을 높일 수 있습니다.
중재자 인터페이스 정의
interface Mediator {
void notify(Component sender, String event);
}
구체적인 중재자 클래스 구현
class Dialog implements Mediator {
private Button button;
private TextBox textBox;
public void setButton(Button button) {
this.button = button;
}
public void setTextBox(TextBox textBox) {
this.textBox = textBox;
}
@Override
public void notify(Component sender, String event) {
if (sender == button && event.equals("click")) {
System.out.println("Button clicked. Clearing the TextBox.");
textBox.clear();
}
}
}
컴포넌트 클래스 정의
abstract class Component {
protected Mediator mediator;
public Component(Mediator mediator) {
this.mediator = mediator;
}
}
구체적인 컴포넌트 구현
class Button extends Component {
public Button(Mediator mediator) {
super(mediator);
}
public void click() {
mediator.notify(this, "click");
}
}
class TextBox extends Component {
public TextBox(Mediator mediator) {
super(mediator);
}
public void clear() {
System.out.println("TextBox cleared");
}
}
클라이언트 코드
public class Main {
public static void main(String[] args) {
Dialog dialog = new Dialog();
Button button = new Button(dialog);
TextBox textBox = new TextBox(dialog);
dialog.setButton(button);
dialog.setTextBox(textBox);
button.click(); // Button clicked. Clearing the TextBox.
// TextBox cleared
}
}
중재자 패턴의 동작 원리
- 컴포넌트 객체는 중재자와만 통신하며, 다른 객체와는 직접적으로 상호작용하지 않습니다.
- 중재자 객체는 컴포넌트들의 상호작용을 조정하고 관리합니다.
- 컴포넌트가 이벤트를 발생시키면 중재자가 해당 이벤트를 처리합니다.
중재자 패턴의 장단점
장점
- 결합도 감소: 각 객체가 중재자와만 통신하므로 객체 간의 직접적인 의존성이 줄어듭니다.
- 유연성 증가: 새로운 컴포넌트를 추가하거나 수정할 때 기존 코드에 영향을 주지 않습니다.
- 유지보수 용이: 상호작용 로직이 중재자에 집중되므로 코드의 가독성과 유지보수성이 향상됩니다.
단점
- 복잡성 증가: 중재자에 많은 상호작용 로직이 집중되면 중재자 객체가 복잡해질 수 있습니다.
- 성능 저하 가능성: 모든 상호작용이 중재자를 거치기 때문에 오버헤드가 발생할 수 있습니다.
결론
중재자 패턴은 객체 간의 복잡한 상호작용을 단순화하고 결합도를 낮추기 위해 사용되는 패턴입니다. 이 패턴을 사용하면 객체가 독립적으로 동작하면서도 필요한 상호작용을 중재자를 통해 관리할 수 있습니다.
다만, 모든 상호작용 로직이 중재자에 집중되면 복잡도가 증가할 수 있으므로, 패턴을 적절히 사용해야 합니다. GUI 애플리케이션, 채팅 시스템, 교통 관제 시스템 등 여러 객체가 복잡하게 상호작용해야 하는 상황에서 특히 유용합니다.