patterns
PatternsAbout

Mediator/Middleware 패턴

중재자 역할을 하는 객체 통해 컴포넌트들이 서로 통신하도록 한다

📮 피드백 보내기

컴포넌트들이 서로 직접 통신하는 대신 중재자 역할을 하는 객체를 통하도록 한다. 중재가 객체가 요청을 받아 이를 필요로 하는 객체들에게 전달하는 것이다. 중재자는 보통 객체나 함수로 구현된다.

이 패턴은 공항에서 비행기의 동선을 관리하는 관제소에 비교할 수 있다. 비행기끼리 직접 통신하면 사고로 이어질 수 있겠지만 관제소에서 상황을 전달받아 통제를 하게 되면 서로 충돌 없이 안전하게 활주로를 이용할 수 있게 된다.

자바스크립트로 비행기를 조종할 일은 없겠지만. 종종 여러 객체들이 서로 데이터를 주고 받는 상황이 생기곤 한다. 컴포넌트가 많아질수록 통신의 횟수는 많아지며 점점 흐름을 파악하기 어려워 질 것이다.

mediator middleware01

객체끼리 서로 통신하게 하여 다대다의 관계를 이루게 하는 대신 객체의 요청들을 모두 중재자 객체에게 보낸다. 중재자는 이런 요청들을 처리하여 이를 필요로 하는 객체에게 전달한다.

mediator middleware02

실무에서 이 중재재 패턴이 적합한 곳은 채팅을 구현할 때 이다. 채팅 앱에서 사용자는 메시지를 직접 서로 주고 받지 않는다. 그 대신 채팅 서버에 메시지를 전송하고 서버가 각 사용자에게 메시지를 전달하는 형태이다.

class ChatRoom {
  logMessage(user, message) {
    const time = new Date()
    const sender = user.getName()

    console.log(`${time} [${sender}]: ${message}`)
  }
}

class User {
  constructor(name, chatroom) {
    this.name = name
    this.chatroom = chatroom
  }

  getName() {
    return this.name
  }

  send(message) {
    this.chatroom.logMessage(this, message)
  }
}

위의 예제에서 사용자는 ChatRoom과 연결되는 User를 만들어낼 수 있고. 각 인스턴스는 send메서드를 통해 다른 사용자에게 메시지를 전송할 수 있다.


사례 분석

Express.js는 많이 사용하는 웹 서버 프레임웍이다. 특정 라우팅 경로에 대해 콜백을 추가함으로써 요청을 처리할 수 있다.

'/' 경로를 요청했을 때 요청에 헤더를 추가해야 한다고 가정해 보자. 아래 예시와 같이 미들웨어를 추가하여 처리할 수 있다.

const app = require('express')()

app.use('/', (req, res, next) => {
  req.headers['test-header'] = 1234
  next()
})

next 함수는 요청-응답 사이클에 걸려있는 다음 콜백을 호출한다. 아래 그림과 같이 요청-응답 사이에 콜백 체인을 추가할 수 있다.

mediator middleware03

아래 에제에서는 위의 예시에서 헤더가 잘 추가되었는지 검사하는 미들웨어를 추가했다. 이전 콜백의 변경 사항을 다음 콜백에서 확인할 수 있는 것이다.

const app = require('express')()

app.use(
  '/',
  (req, res, next) => {
    req.headers['test-header'] = 1234
    next()
  },
  (req, res, next) => {
    console.log(`Request has test header: ${!!req.headers['test-header']}`)
    next()
  }
)

아래 예시에서는 하나 이상의 함수를 추가하여 요청 객체를 추적하거나 수정하고 있다.

엔드포인트 '/'가 호출될 때 마다 두 개의 미들웨어 콜백이 실행된다.


이 미들웨어 패턴은 여러 객체 간 다대 다의 통신을 하나의 관리 포인트를 통하도록 만들어 관계를 단순하게 만들어준다.

참조

  • Patterns
  • About
  • Submit Feedback
© 2020-2022 Patterns.dev. All rights reserved.