Table of Contents
[GoF 디자인 패턴] 중재자 (Mediator) 패턴
행동(behavioral) 패턴 중 하나로, 객체 간의 복잡한 상호작용을 캡슐화하여 객체들 간의 결합도를 낮추는 디자인 패턴이다.
중재자 패턴은 객체 간의 직접적인 의존성을 없애고, 대신 중재자를 통해 상호작용을 수행한다.
![image](/images/gof-design-pattern-mediator/1.png)
중재자 패턴의 구성요소
- Mediator : 객체 간의 상호작용을 조정하는 역할을 정의하는 인터페이스
- ConcreteMediator : Mediator 인터페이스의 구현체**.** Mediator 역할을 실제로 수행
- Colleague : 중재자 (Mediator)와 상호작용하는 객체로 인터페이스로 정의.
- Concrete Colleague : Colleague 인터페이스의 구현체. Mediator 객체와 통신할 수 있는 메서드를 구현
구현 예제
Mediator 인터페이스를 선언한다.
1public interface Mediator {
2 void notify(User user, String message);
3}
선언된 notify 메서드는 Mediator 객체에서 동료 객체들에게 메시지를 전달하기 위해 사용된다.
Mediator 인터페이스를 구현한 ConcreteMediator 클래스를 만든다.
1public class ChatMediator implements Mediator {
2
3 private final List<User> userList = new ArrayList<>();
4
5 public void addClient(User user) {
6 userList.add(user);
7 }
8
9 @Override
10 public void notify(User user, String message) {
11 if (userList.contains(user)) {
12 user.receive(message);
13 } else {
14 System.out.println("주의 : 해당 유저는 없습니다.");
15 }
16 }
17}
Mediator 인터페이스를 구현하여 객체 간의 상호작용을 조정하는 역할을 수행한다. 여기서 notify 메서드는 userList에 사용자 객체가 등록되어 있는 경우 해당 사용자 객체에게 메시지를 전달한다.
→ “객체 간의 결합도를 낮추고, 객체 간의 상호작용을 중앙 집중적으로 관리할 수 있다.”
Colleague 인터페이스를 만든다.
1public interface User {
2 void send(User user, String message);
3 void receive(String message);
4}
Colleague 객체들이 구현해야 하는 메서드를 정의한다. send 메서드는 Colleague 객체가 다른 Colleague 객체에게 메시지를 보낼 때 사용되고, receive 메서드는 Colleague 객체가 다른 Colleague 객체로부터 메시지를 받았을 때 호출되는 메서드이다.
Colleague 인터페이스를 구현한 Concrete Colleague 클래스를 만든다.
1public class Client implements User {
2
3 private final String name;
4 private final Mediator chatMediator;
5
6 public Client(String name, Mediator chatMediator) {
7 this.name = name;
8 this.chatMediator = chatMediator;
9 }
10
11 @Override
12 public void send(User user, String message) {
13 System.out.println(name + " 유저가 메시지를 보냅니다....");
14 chatMediator.notify(user, message);
15 }
16
17 @Override
18 public void receive(String message) {
19 System.out.println(name + " 유저가 메시지를 받았습니다 : " + message);
20 }
21}
생성자에서는 Mediator 객체를 인자로 받아 다른 Colleague 객체들과 소통할 수 있다. 또한 send 메서드와 receive 메서드를 구현하여 객체 간의 메시지 송수신 기능을 구현한다.
→ “Colleague 객체가 Mediator 객체와 직접 통신하지 않고, 중간에 Mediator 객체를 거쳐서 다른 객체와 상호작용하기 때문에 객체 간의 결합도를 낮출 수 있다.”
중재자 패턴을 사용하는 클라이언트 코드이다.
1
2ChatMediator mediator = new ChatMediator();
3
4User user1 = new Client("user1", mediator);
5User user2 = new Client("user2", mediator);
6User user3 = new Client("user3", mediator);
7User user4 = new Client("user4", mediator);
8
9mediator.addClient(user1);
10mediator.addClient(user2);
11mediator.addClient(user3);
12
13user1.send(user3, "안녕하세요. user3");
14user3.send(user1, "안녕하세요.");
15user2.send(user4, "안녕하세요. user4");
채팅방의 역할을 수행하는 ChatMediator 객체와 4개의 Client 객체를 생성한다. Client 객체가 send 메서드를 호출할 경우 ChatMediator 객체를 통해 다른 Client 객체에게 메세지를 전달할 수 있게 된다.
중재자 패턴 고려사항
객체 간의 상호작용이 복잡하고 각각에게 강한 의존성이 있어 결합도를 낮춰야 하는 경우에 중재자 패턴을 사용한다. 하지만 객체 간의 강한 결합도가 필요하거나 객체 간의 상호작용이 한 두 개 뿐이며 변경이 적고 중재자가 병목 현상을 유발할 가능성이 있는 경우에는 적합하지 않다.
중재자 패턴 사용 시 장점
- 객체 간의 결합도를 줄일 수 있어 유지보수성이 높아진다.
- 객체 간의 의존성을 최소화하여, 객체의 재사용성을 높일 수 있다.
- 객체 간의 상호작용을 중앙에서 관리하므로, 복잡한 상호작용을 간소화 할 수 있다.
중재자 패턴 사용 시 단점
- 중재자가 많은 역할을 담당하게 되어, 중재자 클래스의 복잡도가 증가할 수 있다.
- 중재자에게 많은 역할이 부여될 경우, 단일 책임 원칙(SRP)을 위배하게 될 수 있다.
- 중재자 클래스가 추가될 경우, 전체적으로 변경사항이 발생할 가능성이 있다.