디자인 패턴(구)/행위 패턴

중재자(Mediator) 패턴이란?

공대키메라 2022. 4. 23. 17:56

1. 중재자 패턴이란?

의도

한 집합에 속해잇는 객체의 상호작용을 캡슐화하여 객체를 정의한다. 객체들이 직접 서로를 참조하지 않도록 하여 객체 사이의 소결합을 촉진시키며, 개발자가 객체의 상효작용을 독립적으로 다양화시킬 수 있게 만든다.

 

즉, 여러 객체들이 소통하는 방법을 캡슐화하는 패턴이다.

사용 시기

  • 여러 객체가 잘 정의된 형태이기는 하지만 복잡한 상호작용을 가질 때. 객체간의 의존성이 구조화되지 않으며 잘 이해하기 어려울 때
  • 한 객체가 다른 객체를 너무 많이 참조하고, 너무 많은 의사소통을 수행해서 그 객체를 재사용하기 힘들 때
  • 여러 클래스에 분산된 행동들이 상속 없이 상황에 맞게 수정되어야 할 때

위 상황에서 이 패턴을 사용하면 여러 컴포넌트간의 결합도를 중재자를 통해 낮출 수 있다

구조

  • Mediator : Colleague객체와 교류하는 데 필요한 인터페이스를 정의
  • ConcreteMediator : Colleague 객체와 조화를 이뤄서 협력 행동을 구현, 자신이 맡을 동료를 파악하고 관리
  • Colleague 클래스들 : 자신의 중재자 객체가 무엇인지 파악. 다른 객체와 통신이 필요하면 그 중재자를 통해 통신되도록 하는 동료 객체를 나타내는 클래스

이 중재자 패턴을 예시를 통해 더 이해하기 위해 정보를 더 찾았다.

 

다음 그림은 youtube에서 참고한 것인데 Mediator 패턴을 생각할 때 항공기 관제탑이라고 생각을 하면 편하다.

 

Mediator는 어떤 비행기가 교신을 하던지 서로에게 알맞게 정보를 전달하는 역할을 한다.

 

출처 영상 : https://www.youtube.com/watch?v=KOVc5o5kURE

 

 

 

 

 

 

또한,

 

채팅룸에서 문자 메시지를 주고받는다고 할 때, 각자 개개인이 주고받는 것이 아니라 중앙 제어소를 거쳐서 응답을 하게 되면 훨씬 효율적이다.

 

출처 영상 : https://www.youtube.com/watch?v=7imEWnkVFFg

장점

  • 컴포넌트 코드를 변경하지 않고 새로운 중재자를 만들어 사용할 수 있다.
  • 각각의 컴포넌트 코드를 보다 간결하게 유지할 수 있다.

단점

  • 중재자 역할을 하는 클래스의 복잡도와 결합도가 증가한다.

2. 구현

필자는 다음과 같은 class를 구현할 것이다.

 

이번 예제는 다음 영상에서 참고했다.

 

채팅방에 사람이 있고 그 모든 참여 인원들에게 메시지를 보낸다고 생각하자.

 

출처 : https://www.youtube.com/watch?v=7imEWnkVFFg 

Mediator.java

import java.util.ArrayList;
import java.util.List;

public interface Mediator {

    List<Colleague> colleagues = new ArrayList<>();

    default boolean addColleague(Colleague colleague) {
        if(colleague != null)
            return colleagues.add(colleague);
        else
            return false;
    }

    void mediate(String data);

}

Colleague.java

public abstract class Colleague {

    private Mediator mediator;

    public boolean join(Mediator mediator){
        if(mediator == null)
            return false;
        this.mediator = mediator;
        return mediator.addColleague(this);
    }

    public void sendData(String data) {
        if(data != null)
            mediator.mediate(data);
    }

    abstract public void handle(String data);
}

ChatColleague1.java

public class ChatColleague1 extends Colleague {
    @Override
    public void handle(String data) {
        System.out.printf("data : %s in ChatColleague1\n", data);
    }
}

Main.java

public class Main {
    public static void main(String[] args) {

        Mediator mediator = new ChatMediator();

        Colleague colleague1 = new ChatColleague1();
        Colleague colleague2 = new ChatColleague1();
        Colleague colleague3 = new ChatColleague1();

        colleague1.join(mediator);
        colleague2.join(mediator);
        colleague3.join(mediator);

        colleague1.sendData("AAA");
        colleague1.sendData("BBB");
        colleague1.sendData("CCC");
    }

}

출력 결과

더보기

data : AAA in ChatColleague1
data : AAA in ChatColleague1
data : AAA in ChatColleague1
data : BBB in ChatColleague1
data : BBB in ChatColleague1
data : BBB in ChatColleague1
data : CCC in ChatColleague1
data : CCC in ChatColleague1
data : CCC in ChatColleague1

 

총 3명의 인원이 현재 Mediator에서 colleague1 그룹으로 포함되어있으니, 메시지를 하나 보낼 때 마다 

 

3번 + 3번 + 3번 씩 총 9번의 메시지가 전송된다.

 

만약 새롭게 채팅방을 이용한다면 새롭게 만들어서 따로 추가를 해주면 된다. 

 

ChatColleague2.java

public class ChatColleague2 extends Colleague {
    @Override
    public void handle(String data) {
        System.out.printf("data : %s in ChatColleague2\n", data);
    }
}

Main.java - ChatColleague2 추가

public class Main {

    public static void main(String[] args) {
        Mediator mediator = new ChatMediator();

        Colleague colleague1 = new ChatColleague1();
        Colleague colleague2 = new ChatColleague1();
        Colleague colleague3 = new ChatColleague1();

        Colleague colleague4 = new ChatColleague2();
        Colleague colleague5 = new ChatColleague2();
        Colleague colleague6 = new ChatColleague2();

        colleague1.join(mediator);
        colleague2.join(mediator);
        colleague3.join(mediator);

        colleague4.join(mediator);
        colleague5.join(mediator);
        colleague6.join(mediator);

        colleague1.sendData("AAA");
        colleague1.sendData("BBB");
        colleague1.sendData("CCC");
        colleague4.sendData("1AAA");
        colleague5.sendData("1BBB");
        colleague6.sendData("1CCC");
    }

}

출력 결과

더보기

data : AAA in ChatColleague1
data : AAA in ChatColleague1
data : AAA in ChatColleague1
data : AAA in ChatColleague2
data : AAA in ChatColleague2
data : AAA in ChatColleague2
data : BBB in ChatColleague1
data : BBB in ChatColleague1
data : BBB in ChatColleague1
data : BBB in ChatColleague2
data : BBB in ChatColleague2
data : BBB in ChatColleague2
data : CCC in ChatColleague1
data : CCC in ChatColleague1
data : CCC in ChatColleague1
data : CCC in ChatColleague2
data : CCC in ChatColleague2
data : CCC in ChatColleague2
data : 1AAA in ChatColleague1
data : 1AAA in ChatColleague1
data : 1AAA in ChatColleague1
data : 1AAA in ChatColleague2
data : 1AAA in ChatColleague2
data : 1AAA in ChatColleague2
data : 1BBB in ChatColleague1
data : 1BBB in ChatColleague1
data : 1BBB in ChatColleague1
data : 1BBB in ChatColleague2
data : 1BBB in ChatColleague2
data : 1BBB in ChatColleague2
data : 1CCC in ChatColleague1
data : 1CCC in ChatColleague1
data : 1CCC in ChatColleague1
data : 1CCC in ChatColleague2
data : 1CCC in ChatColleague2
data : 1CCC in ChatColleague2

 

동일한 작업을 오직 한 곳을 거쳐서 작동하는 기능을 Mediator 패턴을 이용해서 구현할 수 있다.


이번에는 Mediator패턴에 대해 알아보았다. 

 

이것보다 더 나은 예제가 있다면 피드백 부탁한다.