Table of Contents

[GoF 디자인 패턴] 중재자 (Mediator) 패턴

행동(behavioral) 패턴 중 하나로, 객체 간의 복잡한 상호작용을 캡슐화하여 객체들 간의 결합도를 낮추는 디자인 패턴이다.

중재자 패턴은 객체 간의 직접적인 의존성을 없애고, 대신 중재자를 통해 상호작용을 수행한다.

image

중재자 패턴의 구성요소

  • 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 객체에게 메세지를 전달할 수 있게 된다.


중재자 패턴 고려사항

객체 간의 상호작용이 복잡하고 각각에게 강한 의존성이 있어 결합도를 낮춰야 하는 경우에 중재자 패턴을 사용한다. 하지만 객체 간의 강한 결합도가 필요하거나 객체 간의 상호작용이 한 두 개 뿐이며 변경이 적고 중재자가 병목 현상을 유발할 가능성이 있는 경우에는 적합하지 않다.


중재자 패턴 사용 시 장점

  1. 객체 간의 결합도를 줄일 수 있어 유지보수성이 높아진다.
  2. 객체 간의 의존성을 최소화하여, 객체의 재사용성을 높일 수 있다.
  3. 객체 간의 상호작용을 중앙에서 관리하므로, 복잡한 상호작용을 간소화 할 수 있다.

중재자 패턴 사용 시 단점

  1. 중재자가 많은 역할을 담당하게 되어, 중재자 클래스의 복잡도가 증가할 수 있다.
  2. 중재자에게 많은 역할이 부여될 경우, 단일 책임 원칙(SRP)을 위배하게 될 수 있다.
  3. 중재자 클래스가 추가될 경우, 전체적으로 변경사항이 발생할 가능성이 있다.