273. 중재자 (Mediator) - 객체 간의 복잡한 상호작용을 캡슐화하여 결합도 저하

핵심 인사이트 (3줄 요약)

  1. 본질: 중재자(Mediator) 패턴은 수많은 객체들이 서로서로 직접 얽혀서 통신(M:N 구조)하는 혼돈의 스파게티 네트워크를, 모든 객체가 오직 한 명의 통제자(중재자)와만 통신하는 별 모양(Star, 1:N 구조)의 허브 앤 스포크(Hub-and-Spoke) 아키텍처로 단순화시키는 행동 패턴이다.
  2. 가치: 객체들 사이의 강한 결합(Tight Coupling)을 완전히 끊어내어 어느 한 객체를 수정해도 다른 객체에 미치는 파급효과(Ripple Effect)를 차단하고, 객체의 재사용성과 유지보수성을 극적으로 끌어올린다.
  3. 융합: 복잡한 GUI 컴포넌트 간의 상호작용(버튼과 체크박스의 연쇄 반응) 통제뿐만 아니라, 엔터프라이즈 환경에서의 엔터프라이즈 서비스 버스(ESB), 메시지 브로커, 항공 관제 시스템(ATC) 등 네트워크 통신 융합 아키텍처의 철학적 기반이다.

Ⅰ. 개요 및 필요성 (Context & Necessity)

  • 개념: 중재자 패턴은 객체 간의 상호작용(Interaction) 행위를 캡슐화하여 별도의 Mediator 객체에 집중시킨다. 동료 객체(Colleagues)들은 다른 동료를 직접 부르지 않고, 오로지 중재자에게만 메시지를 던지며 중재자가 그 통신을 라우팅한다.

  • 필요성: 비행기 10대가 공항 근처에 있다. 조종사들이 서로 충돌하지 않기 위해 10대가 각자 나머지 9대와 무전기로 계속 통신(총 45개의 통신 라인)한다면, 통신망은 마비되고 반드시 사고가 난다. 복잡한 UI 폼(Form)도 마찬가지다. '약관 동의' 체크박스를 누르면 '가입' 버튼이 활성화되고, '취소' 버튼을 누르면 모든 폼이 지워지는 식으로 10개의 UI 부품이 서로 얽히면(Spaghetti), 나중에 체크박스 하나 뺄 때 프로그램 전체가 뻗는다.

  • 💡 비유: 항공 관제탑(ATC, Air Traffic Control)과 완벽히 동일합니다. 수십 대의 비행기(객체)는 서로 대화하지 않습니다. 비행기는 오직 중앙의 관제탑(중재자)에게만 자신의 위치와 착륙 요청을 보고하고, 관제탑이 전체 상황을 판단해 다른 비행기들에게 지시를 내립니다.

  • 등장 배경 및 발전 과정:

    1. Spaghetti Dependencies의 비극: 초기 객체 지향 프로그래밍에서 '객체 간의 협력'을 강조하다 보니, 객체들이 서로의 참조를 너무 많이 가지는 M:N 메시지 지옥이 발생했다.
    2. 허브 앤 스포크 (Hub and Spoke) 패러다임 도입: 거미줄 구조 대신 바퀴살(Spoke)처럼 중앙(Hub)에 중재자를 두어 결합도를 O(N^2)에서 O(N)으로 낮추는 설계가 탄생했다.
    3. 이벤트 버스(Event Bus)로의 진화: 현대 웹과 분산 시스템에 이르러서는 단순한 중재자 객체를 넘어, 완전 비동기 방식의 Pub/Sub을 지원하는 Message Broker(Kafka 등)나 프론트엔드의 상태 관리소(Redux Store) 형태로 진화했다.
  • 📢 섹션 요약 비유: 교실에서 30명의 학생이 서로 직접 떠들며 회의하면 아수라장이 되지만, 학생들은 무조건 반장(중재자)에게만 손을 들고 말하고 반장이 이를 칠판에 정리하면 평화로운 회의가 되는 것과 같습니다.


Ⅱ. 아키텍처 및 핵심 원리 (Deep Dive)

구성 요소 (클래스 다이어그램)

요소명역할비유
Mediator (중재자 인터페이스)동료(Colleague) 객체들과 통신하기 위한 공통 인터페이스. 주로 이벤트나 메시지를 수신하는 notify() 메서드를 갖는다.관제탑의 통신 주파수 규격
ConcreteMediator동료 객체들의 모든 참조(목록)를 들고 있으며, A 동료가 메시지를 보내면 그 의미를 파악해 B와 C 동료에게 적절한 명령을 내리는 비즈니스 제어 로직을 캡슐화한 허브.실제 공항의 중앙 관제탑 통제실
Colleague (동료 추상 클래스)중재자(Mediator)의 참조를 들고 있는 부품 객체들. 동료들끼리는 서로 절대 모른다.통신기기를 탑재한 비행기 (대한항공, 아시아나 등)
ConcreteColleague버튼, 체크박스, 텍스트 필드 등 실제 이벤트를 발생시키는 구체적 부품. 무언가 변하면 중재자에게만 알린다."동의합니다" 체크박스, "제출" 버튼

동작 메커니즘 (코드 뼈대 구조)

중재자 패턴의 핵심은 모든 Colleague는 서로를 import 하거나 변수로 가지지 않는다는 점이다. 오직 Mediator 1개만 참조한다.

  ┌─────────────────────────────────────────────────────────────┐
  │                 M:N 스파게티 vs 1:N 허브 구조                  │
  ├─────────────────────────────────────────────────────────────┤
  │                                                             │
  │  [AS-IS: 강결합 스파게티]          [TO-BE: 중재자 패턴]        │
  │                                                             │
  │   A ◀────▶ B                 A               B          │
  │   ▲ ↘    ↙ ▲                   \         /             │
  │   │   ╳      │                     ▼   ▼               │
  │   ▼ ↙    ↘ ▼                   [ Mediator ]             │
  │   C ◀────▶ D                     ▲   ▲               │
  │                                  /         \             │
  │   (각자 서로를 알아야 함)       C               D          │
  │   (하나 삭제 시 연쇄 오류)       (A,B,C,D는 오직 M만 안다)     │
  │                                                             │
  │                                                             │
  │  ───(동작 흐름)─────────────────────────────────────────────  │
  │  1. CheckBox(A) 클릭 발생!                                   │
  │  2. CheckBox는 Mediator.notify(this, "checked") 호출.       │
  │  3. Mediator가 "A가 체크되었으니, B(버튼)를 활성화시켜야지" 판단.   │
  │  4. Mediator가 Button(B).enable() 호출.                     │
  └─────────────────────────────────────────────────────────────┘

[다이어그램 해설] 과거(AS-IS)에는 체크박스 A의 클릭 이벤트 로직 안에 ButtonB.enable()TextC.clear()가 하드코딩되어 있었다. 체크박스를 다른 화면에 재사용하고 싶어도 B와 C가 없으면 에러가 났다. 중재자 패턴(TO-BE)을 적용하면 체크박스 A는 그저 "나 눌러졌소!"라고 허공(Mediator)에 외칠 뿐이다. 재사용성이 100% 보장된다. 중앙의 Mediator만이 얽히고설킨 룰("A가 눌러지면 B를 켜고 C를 끈다")을 독점적으로 통제(Routing)한다.


옵저버(Observer) 패턴과의 차이점 (매우 중요)

중재자와 옵저버는 '객체 간 통신 결합도를 낮춘다'는 목적은 같으나 통신의 방향성이 다르다.

비교 항목중재자 (Mediator)옵저버 (Observer)
통신의 중심1개의 중앙 집중형 라우터 (양방향 통신, Star 구조)발행자(Subject)를 향한 1:N 구독 단방향 구조
로직의 집중A의 변화로 B와 C가 어떻게 바뀌어야 하는지(비즈니스 룰)를 중재자 1명이 독재함.Subject는 "나 변했어"만 알릴 뿐, 이후 어떻게 할지(룰)는 각 Observer가 알아서 각자 처리함.
적용 사례복잡한 UI 폼의 연쇄 상호작용 제어, 채팅방 로직상태 변화에 따른 단순 디스플레이 업데이트 (MVC의 Model 갱신)
  • 📢 섹션 요약 비유: 옵저버가 유튜버(Subject)의 새 영상 알림을 수백만 구독자(Observer)가 일방적으로 받는 것이라면, 중재자는 여러 명의 토론자(Colleague)가 진행자(Mediator)를 쳐다보며 의견을 주고받는 양방향 컨트롤 타워입니다.

Ⅲ. 융합 비교 및 다각도 분석

1. 파사드(Facade) 패턴 vs 중재자(Mediator) 패턴

두 패턴 모두 "복잡한 구조 앞에 하나의 창구(허브)를 둔다"는 공통점이 있다. 하지만 단방향이냐 양방향이냐가 핵심 차이다.

패턴파사드 (Facade)중재자 (Mediator)
구조외부 클라이언트 → 파사드 → 내부 서브시스템동료(내부) ↔ 중재자 ↔ 동료(내부)
방향성단방향 (파사드가 내부에 명령을 내림. 내부가 파사드를 역호출하지 않음)양방향 (동료들이 중재자에게 요청하고, 중재자가 다른 동료에게 명령함)
존재의 이유"복잡한 서브시스템을 쉽게 사용할 수 있도록 인터페이스를 단순화하자""동료 객체들 간의 얽힌 거미줄 종속성을 하나로 중앙 통제하자"

과목 융합 관점

  • 소프트웨어 공학 (SE): 마이크로서비스 아키텍처(MSA)에서의 API GatewayESB(Enterprise Service Bus) 패턴이 바로 이 중재자 패턴의 분산/엔터프라이즈 버전이다. 서비스 A와 B가 직접 REST API를 호출(강결합)하지 않고 중앙 버스를 거치게 함으로써 장애 격리와 라우팅 통제를 꾀한다.

  • 네트워크 (NW): 무선 랜(WLAN) 구조에서 단말기들이 서로 직접 통신하는 Ad-hoc 모드(스파게티 구조) 대신, 모든 단말이 하나의 AP(Access Point, 중재자)를 거쳐 통신하는 인프라스트럭처 모드를 채택한 것이 정확히 중재자 아키텍처다.

  • 📢 섹션 요약 비유: 파사드는 손님이 복잡한 주방 시스템을 알 필요 없이 '계산원'에게 1회성 명령을 내리는 것이고, 중재자는 주방 안에서 '주방장'이 고기 담당과 야채 담당 사이의 얽힌 순서를 땀 뻘뻘 흘리며 양방향으로 조율하는 것입니다.


Ⅳ. 실무 적용 및 기술사적 판단

실무 시나리오

  1. 시나리오 — 항공권 예매 UI 폼의 연쇄 폭발: '국내선/국제선' 라디오 버튼에 따라 달력의 활성화 여부가 다르고, '편도/왕복' 체크박스에 따라 '도착일' 입력 칸이 숨겨지거나 보이며, 이 모든 조건이 충족되어야만 '예매' 버튼이 켜진다. 컴포넌트 이벤트 리스너끼리 서로의 메서드를 호출하다가 런타임 콜스택 제한 초과 에러(Infinite Loop)가 터졌다.

    • 아키텍트의 해결책: UI 컴포넌트끼리 직접 호출하는 로직을 모두 잘라낸다. 모든 UI 요소(Colleague)는 상태 변경 시 오직 ReservationMediator.notify(this)만 호출한다. 중재자 안에 유일한 통제 로직(if 국내선 && 편도면 도착일 숨김)을 한데 모아 캡슐화한다. 버그가 터지면 중재자 클래스 딱 1개만 뒤져보면 된다.
  2. 시나리오 — 멀티플레이 채팅방 동기화 문제: 게임 내에서 유저 1명이 전체에게 메시지를 뿌리거나 귓속말을 보내야 한다. 유저 객체 100명이 서로의 소켓(Socket) 리스트를 각자 보유(List users)하면, 1명만 퇴장해도 나머지 99명의 리스트를 지우느라 서버 메모리에 락(Lock)이 걸린다.

    • 아키텍트의 해결책: 유저들은 서로를 전혀 모르게 하고, 중앙에 ChatRoom (Mediator) 객체 하나만 둔다. 유저는 chatRoom.send(message, toUser)만 호출하고, 누가 들어오고 나가는지(Session 관리)와 브로드캐스팅 라우팅 처리는 오로지 ChatRoom 하나가 독점한다. 완벽한 디커플링이다.

도입 체크리스트

  • 기술적: 동료 컴포넌트들이 정말로 서로 '직접' 많이 얽혀 있는가? 2~3개 컴포넌트 사이의 단순한 참조라면 굳이 중재자 패턴을 도입할 필요가 없다. (과도한 캡슐화 방지)
  • 설계적: 프론트엔드 환경인가? Vuex, Redux, Context API 등 이미 현대 상태 관리 라이브러리들은 중재자(Mediator) 패턴의 거대한 진화형(Store)을 내장하고 있다. 수동으로 Mediator 클래스를 짤 필요 없이 이 생태계들을 활용하라.

안티패턴

  • 중재자의 신(God) 클래스화: 동료들의 결합도를 낮추는 데는 성공했지만, 그 모든 복잡한 얽힘(비즈니스 룰)을 중재자 혼자서 다 짊어지게 되므로, 잘못하면 중재자 클래스가 5천 줄이 넘는, 수정 불가능한 끔찍한 괴물(God Object, 블랙홀)로 변해버린다.

    • 대안: 중재자 안에서도 로직을 기능별로 다시 쪼개어 서브 중재자(Sub-Mediator)로 분산시키거나, 상태(State) 패턴 등을 결합하여 if-else의 무게를 줄여야 한다.
  • 📢 섹션 요약 비유: 부하 직원들의 다툼을 막으려고 중앙 관리자(중재자)가 모든 결재와 조율을 혼자 다 하겠다고 나섰다가, 관리자 혼자 과로사로 쓰러져 회사 전체가 멈추는 부작용(신 클래스 화)을 경계해야 합니다.


Ⅴ. 기대효과 및 결론

정량/정성 기대효과

구분상호 직접 참조 (AS-IS)중재자 패턴 도입 (TO-BE)개선 효과
정량N개의 컴포넌트가 존재할 때 N(N-1)/2 개의 참조 경로 발생1개의 중재자와 N개의 참조로 통일결합도 지수 O(N²)에서 O(N)으로 기하급수적 축소
정량버튼 A의 로직 수정 시 B, C 폼 오류 발생률 (회귀 버그) 높음UI 폼 부품 독립적 재사용 가능부품 재사용성 100% 확보 및 버그 수정 시간 70% 절감
정성스파게티 의존성으로 인해 전체 시스템 흐름 파악 불가비즈니스 룰이 중재자 1곳에 모여 문서화됨아키텍처 가시성(Visibility) 및 통제력 극대화

미래 전망

  • 이벤트 주도 아키텍처(EDA)와의 결합 강화: 중재자가 단순한 클래스(오브젝트)를 넘어 카프카(Kafka)나 래빗MQ(RabbitMQ) 같은 미들웨어 메시지 브로커 인프라로 스케일업(Scale-up)하는 것이 대세다. 코드 레벨의 Mediator는 프론트엔드의 상태 관리소(Store)로, 인프라 레벨의 Mediator는 이벤트 버스(Event Bus)로 영속화되고 있다.
  • 마이크로 프론트엔드(Micro-Frontend)의 허브: 복수의 분리된 프론트엔드 앱들이 한 화면에서 구동될 때, 서로 직접 상태를 공유하지 않고 브라우저 내장 Custom Event를 활용한 보이지 않는 중재자를 두어 무결결성 렌더링을 시도한다.

참고 표준

  • GoF (Gang of Four): Behavioral Patterns - Mediator
  • Java Platform: java.util.Timer (모든 백그라운드 태스크 스케줄링의 중재), java.util.concurrent.ExecutorService
  • React / Vue 생태계: Redux(Store), Vuex 아키텍처 사상

중재자 패턴은 분산된 복잡성을 중앙의 통제로 묶어내는 철학적 결정이다. 기술사는 시스템의 복잡도를 완전히 없애는 것은 불가능(보존의 법칙)함을 안다. 따라서 N개의 객체에 흩어진 더러운 스파게티 복잡성을 '중재자'라는 하나의 쓰레기통(혹은 지휘소)에 의도적으로 몰아넣음으로써, 나머지 N개의 부품들을 완벽히 순수하고 재사용 가능한 블랙박스로 구원해 내는 아키텍처의 트레이드오프(Trade-off) 묘수를 발휘해야 한다.

  • 📢 섹션 요약 비유: 각자 악기를 마음대로 치며 불협화음을 내던 연주자(Colleague)들 앞에, 지휘자(Mediator)라는 통제자를 세워 모든 시선과 복잡성을 지휘자 한 명에게 집중시킴으로써 거대한 오케스트라의 하모니를 이끌어내는 마법입니다.

📌 관련 개념 맵 (Knowledge Graph)

개념 명칭관계 및 시너지 설명
파사드 패턴 (Facade)복잡한 내부를 단순한 외부 인터페이스로 가린다는 점이 같으나, 파사드는 단방향 외부 제공용이고 중재자는 내부 객체들의 양방향 조율용이다.
옵저버 패턴 (Observer)중재자 패턴의 내부 통신 로직을 구현할 때 흔히 결합(융합)된다. Colleague가 상태를 알릴 때 옵저버 패턴(이벤트 구독) 방식을 자주 쓴다.
ESB (Enterprise Service Bus)분산 컴퓨팅 환경에서 수많은 이기종 시스템이 서로 통신할 때 스파게티 연결을 막는, 엔터프라이즈 아키텍처 수준의 중재자(Mediator).
Redux (상태 관리)프론트엔드 컴포넌트(Colleague)들이 직접 데이터를 주고받지 않고 중앙의 Store(Mediator)에 Action을 보내 렌더링을 통제하는 현대적 구현체.
God Object (신 객체 안티패턴)중재자 패턴 남용 시 모든 비즈니스 로직이 중재자 하나에 집중되어 팽창해버리는 최악의 부작용.

👶 어린이를 위한 3줄 비유 설명

  1. 공항에 비행기가 수십 대 떠 있는데, 자기들끼리 "비켜! 내가 먼저 내릴 거야!" 하고 무전기로 마구 싸우면 꽈당 부딪히겠죠?
  2. 그래서 공항 한가운데에 **'관제탑'**을 높이 세우고, 비행기들은 오직 관제탑 아저씨하고만 조용히 이야기를 나눕니다.
  3. 이렇게 서로 얽히고설켜서 싸우는 친구들 사이에 단 한 명의 심판(중재자)을 두어, 모든 신호를 정리하고 평화를 유지하는 방법을 **'중재자 패턴'**이라고 부른답니다!