본문 바로가기

Develop/Design Pattern

[Design Pattern] 중재자 (Mediator) 패턴

728x90

1. 개요

  • 중재자 디자인 패턴 (Mediator Design Pattern)은 객체 간 복잡한 상호작용 부분을 따로 함축한 객체를 만드는 패턴이다.

2. 조건

  • 여러 객체 간의 상호작용이 매우 복잡할 때

3. 다이어그램

mediator-default

3.1. 설명

  • Mediator
    • 객체들 사이의 상호작용을 중재, 조정하는 인터페이스를 정의한다.
    • 다른 객체들과 통신하기 위한 인터페이스를 제공한다.
    • 객체들 간의 결합도를 낮추고, 객체들이 직접적으로 통신하지 않도록 한다.

 

  • ConcreteMediator
    • Mediator 인터페이스를 구현하여 객체들의 상호작용을 조정한다.
    • 객체들 간의 통신을 관리하고 중재한다.
    • 다른 객체들과의 통신을 위해 객체들 간의 관계를 알고 있어야 한다.

 

  • Colleague
    • Mediator와 통신하는 객체를 나타낸다.
    • 다른 동료 객체들과 직접적으로 통신하지 않고, Mediator를 통해 상호작용한다.
    • 상호작용을 위한 메시지를 보내고 받는다.

 

  • ConcreteColleague (ColleagueA, ColleagueB)
    • Colleague 인터페이스를 구현하여 Mediator와 통신한다.
    • 다른 동료 객체들과의 간접적인 통신을 위해 Mediator를 사용한다.

4. 구현

interface Mediator { void update(Colleague c); }

public class ConcreteMediator implements Mediator {
  protected Colleague c1 = new ColleagueA(this);
  protected Colleague c2 = new ColleagueB(this);

  Colleague getC1() { return c1; }
  Colleague getC2() { return c2; }

  @Override
  public void update(Colleague c) {
    if (c instanceof ColleagueA) {
      System.out.println("Colleague A has been updated.");
    } 
    else if (c instanceof ColleagueB) {
      System.out.println("Colleague B has been updated.");
    }
  }
}
public abstract class Colleague {
  protected Mediator mediator;
  public Colleague(Mediator mediator) { this.mediator = mediator; }
  public abstract void operation();
}

public class ColleagueA extends Colleague {
  public ColleagueA(Mediator mediator) { super(mediator); }
  @Override
  public void operation() { mediator.update(this); }
}

public class ColleagueB extends Colleague {
  public ColleagueB(Mediator mediator) { super(mediator); }
  @Override
  public void operation() { mediator.update(this); }
}
public class Client {
  public static void main(String[] args) {
    ConcreteMediator mediator = new ConcreteMediator();
    mediator.getC1().operation();
    mediator.getC2().operation();
  }
}

출력결과

Colleague A: Hello from Colleague A
Colleague B: Hello from Colleague B

5. 예시

public interface Mediator {
  public void update(Colleague c);
}

public class SmartHouse implements Mediator {
  private Window window = new Window(this);
  private AirConditioner aircon = new AirConditioner(this);

  public Window getWindow() { return window; }
  public AirConditioner getAircon() { return aircon; }

  @Override
  public void update(Colleague c) {
    if (c == window && window.isOpened()) aircon.off();
    if (c == aircon && aircon.isOn()) window.close();
  }

  public void visualize() {
    System.out.println("\033[H\033[2J[현재 상태]");
    window.visualize();
    aircon.visualize();
    System.out.println();
  }
}
public abstract class Colleague {
  protected Mediator mediator;
  public Colleague(Mediator mediator) { this.mediator = mediator; }
}

class Window extends Colleague {
  private boolean state = false;
  public Window(Mediator mediator) { super(mediator); }

  public boolean isOpened() { return state; }

  public void open() {
    if (state) return; state = true;
    mediator.update(this);
  }

  public void close() {
    if (!state) return; state = false;
    mediator.update(this);
  }

  public void visualize() {
    System.out.println("창문: " + (state ? "열림" : "닫힘"));
  }
}

public class AirConditioner extends Colleague {
  private boolean state = false;
  public AirConditioner(Mediator mediator) { super(mediator); }

  public boolean isOn() { return state; }

  public void on() {
    if (state) return; state = true;
    mediator.update(this);
  }
  public void off() {
    if (!state) return; state = false;
    mediator.update(this);
  }

  public void visualize() {
    System.out.println("에어컨: " + (state ? "켜짐" : "꺼짐"));
  }
}
public class Client {
  public static void main(String[] args) {
    SmartHouse home = new SmartHouse();

    while (true) {
      home.visualize();
      System.out.println("0: 창문 열기");
      System.out.println("1: 창문 닫기");
      System.out.println("2: 에어컨 켜기");
      System.out.println("3: 에어컨 끄기");

      System.out.print(" > ");
      Scanner sc = new Scanner(System.in);
      int i = sc.nextInt();

      if (i == 0) home.getWindow().open();
      if (i == 1) home.getWindow().close();
      if (i == 2) home.getAircon().on();
      if (i == 3) home.getAircon().off();

      else if (i == -1) return;
    }
  }
}

출력결과

[현재 상태]
창문: 닫힘
에어컨: 꺼짐

0: 창문 열기
1: 창문 닫기
2: 에어컨 켜기
3: 에어컨 끄기
 > 0
[현재 상태]
창문: 열림
에어컨: 꺼짐

0: 창문 열기
1: 창문 닫기
2: 에어컨 켜기
3: 에어컨 끄기
 > 2
[현재 상태]
창문: 닫힘
에어컨: 켜짐

0: 창문 열기
1: 창문 닫기
2: 에어컨 켜기
3: 에어컨 끄기
 > 0
[현재 상태]
창문: 열림
에어컨: 꺼짐

0: 창문 열기
1: 창문 닫기
2: 에어컨 켜기
3: 에어컨 끄기
 > -1

6. 장단점

6.1. 장점

  • 객체 간 상호 의존성이 감소한다.
  • 코드의 확장성유연성을 제공한다.
  • 중앙 집중적인 제어를 할 수 있다.

6.2. 단점

  • 코드의 복잡성이 증가한다.
  • 중재자 객체에 단일 지점 의존성이 발생할 수 있다.

관련 포스팅

참고 자료

728x90