반응형

중재자 패턴(Mediator Pattern)

 

모든 클래스간의 복잡한 로직(상호작용)을 캡슐화하여 하나의 클래스에 위임하여 처리하는 패턴이다.

즉, M:N의 관계에서 M:1의 관계로 복잡도를 떨어뜨려 유지 보수 및 재사용의 확장성에 유리한 패턴이다.

 

커뮤니케이션을 하고자 하는 객체가 있을 때 서로가 커뮤니케이션 하기 복잡한 경우 이를 해결해주고 서로 간 쉽게 해주며 커플링을 약화시켜주는 패턴이다.

 

객체들간 커뮤니케이션 정의가 잘 돼있으나 복잡할 때(종합이 필요할 때) 사용한다.

 

이와 비슷한 패턴은 파사드 패턴(Facade Pattern)과 옵저버 패턴(Observer Pattern)이 있다.

 

위의 그림에서 관제탑이 중재자가 되고 각 비행기가 서로 커뮤니케이션을 하기 위해서는

관제탑을 거쳐 M:N이 아닌 M:1의 관계로 커뮤니케이션을 진행하게 된다.

 

 

프로그램을 작성하다 보면 상호작용을 해야하는 경우 객체들 간의 결합도가 증가하고 유연성이 떨어지는 경우가 발생하게 된다.

이때 중재자 패턴에서는 서로 명령을 주고 받을 수 있는 형식이 있다고 했을 때 서로 명령을 주고 받는 부분을 중재하는 형식을 정의를 한다.

그리고, 원래 서로 명령을 주고 받았던 개체들은 중재자 개체를 알게 하고 중재자 개체는 이들 개체를 알게 한다.

 

이제 특정 개체가 명령을 내릴 필요가 있으면 중재자 개체에게 전달하기만 하면 되고, 

중재자는 해당 명령을 자신이 알고 있는 개체들 중에 적절한 개체에게 전달만 하면 된다.

 

이처럼 중재자 패턴을 사용하면 복잡한 상호작용을 하기 위한 복잡한 관계를 단순화시킬 수 있게 된다.

 

그리고 중재자가 notify한다는 의미로 옵저버 패턴과 매우 유사한데,

옵저버는 Subscriber이 받기만 하는데 Mediator은 서로 통신한다는 것에서 차이가 있다.

 

 

중재자 패턴 클래스 다이어그램

 

+Mediator은 Colleague가 Mediator에서 알려주는 것을 의미하고

ColleagueA도 마찬가지로 Mediator가 ColleagueA,B에게 알리는 것을 의미한다.

 

 

 

 

중재자 패턴 예제

 

 

 

Isource 인터페이스

package MediatorPattern;

interface ISource{
  public void setMediator(Mediator mediator);
  public void eventOccured(String event);
}

 

TcpComm 클래스

ISource를 구현하는 Concrete 부분.

mediator을 설정하고 mediator에게 onEvent로 메시지를 전달한다.

package MediatorPattern;

public class TcpComm implements ISource {
  Mediator mediator;

  @Override
  public void setMediator(Mediator mediator){ // 중재자 설정
      this.mediator = mediator;
  }

  @Override
  public void eventOccured(String event){ // 이벤트의 전달
      mediator.onEvent("TCP comm", event);
  }
}

 

SystemSignal 클래스

TcpComm 클래스와 같다.

package MediatorPattern;

class SystemSignal implements ISource{
  Mediator mediator;
  
  @Override
  public void setMediator(Mediator mediator){ // 중재자 설정
      this.mediator = mediator;
  }

  @Override
  public void eventOccured(String event){ // 이벤트의 전달
      mediator.onEvent("System", event);
  }
}

 

Mediator 클래스

onEvent를 받으면 해당하는 메시지를 receiveEvent를 통해 보낸다.

package MediatorPattern;

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

class Mediator{
  List<IDestination> list = new ArrayList<IDestination>();
  public void addDestination(IDestination destination){ list.add(destination); }

  public void onEvent(String from, String event){
      for(IDestination each : list){ // 이벤트의 전송
          each.receiveEvent(from, event);
      }
  }
}

 

IDestionation 인터페이스

package MediatorPattern;

interface IDestination{
  public void receiveEvent(String from, String event);
}

 

Display 클래스

Idestianation 인터페이스를 구현하고 있다.

package MediatorPattern;

class Display implements IDestination{
  @Override
  public void receiveEvent(String from, String event){
      System.out.println("Display : from " + from + " event : " + event);
  }
}

 

Log 클래스

Display 클래스와 같다.

package MediatorPattern;

class Log implements IDestination{
	@Override
  public void receiveEvent(String from, String event){
		System.out.println("Log : from " + from + " event : " + event);
  }
}

 

MediatorMain 클래스

각 생성자를 만들고 destination은 Display, Log로 해준후 이벤트를 전달하여 아래와 같은 결과값을 얻을 수 있다.

package MediatorPattern;

public class MediatorMain {
	public static void main(String[] args) {
	  Mediator mediator = new Mediator();
	
	  ISource tcp = new TcpComm();
	  tcp.setMediator(mediator);
	  ISource system = new SystemSignal();
	  system.setMediator(mediator);
	
	  mediator.addDestination(new Display());
	  mediator.addDestination(new Log());
	  tcp.eventOccured("connected");
	  tcp.eventOccured("disconnected");
	
	  system.eventOccured("key input");
	  system.eventOccured("mouse input");
	}
}
Display : from TCP comm event : connected
Log : from TCP comm event : connected
Display : from TCP comm event : disconnected
Log : from TCP comm event : disconnected
Display : from System event : key input
Log : from System event : key input
Display : from System event : mouse input
Log : from System event : mouse input

 

중재자 패턴 예제 출처

https://effectiveprogramming.tistory.com/entry/Mediator-%ED%8C%A8%ED%84%B4

 

 

 

 

 

 

반응형