Mediator/Middleware 패턴

김상민·2022년 12월 2일
0

디자인패턴

목록 보기
3/3
post-thumbnail

Use a central mediator object to handle communication between components

Mediator

  • 애플리케이션은 독립된 object들로 만들어진다.
    object간의 통신은 유지보수가 쉽고 다른 object를 건드리지 않으면서, 애플리케이션의 일부분을 안전하게 수정할 수 있는 방식으로 이루어져야한다.
  • 애플리케이션의 크기가 커져가면서 더욱 더 많은 object들이 추가, 제거, 재배치된다. 이때 object들이 서로에 대해 너무 많은 정보를 아는 상태로 직접 통신하게 되면 서로간의 결합도가 높아져 바람직하지 않다. object들이 강하게 결합되면, 다른 object들에 영향을 주지 않고 하나의 object를 수정하기가 어렵다.

  • 우리는 object 간의 다방향 데이터를 처리해야 한다. 하지만 component가 많으면 component 간의 통신이 다소 혼란스러울 수 있다.

  • 이러한 이유로 component들이 서로 직접 통신하는 대신 mediator를 통하도록 한다.
    (mediator가 관제탑, component가 비행기라고 생각하면 된다.)

component vs object
컴포넌트가 사람이 눈으로 확인할 수 있는 결과물이라면 객체는 사람이 눈으로 확인할 수 없는 작은 단위의 사물과 같다. 객체도 독립적으로 작동할 수 있지만 보통 다른 객체와 관계를 맺어 결과물을 제출한다. 다른 객체와 관계를 맺어 하나의 모듈이 되었으면 이 모듈이 곧 컴포넌트가 되기도 한다. 객체는 컴포넌트보다는 작은 단위의 기능을 수행한다. 컴포넌트는 독립적으로 작동하는 큰 단위의 모듈이다. 객체가 모여 컴포넌트가 된다. 컴포넌트는 사람이 직접적, 물질적으로 인식할 수 있는 대상이다.

  • Mediator pattern에서는 독립된 object들은 다른 object와 직접 통신하지 않고, Mediator를 거친다.
    JS에서 Mediator는 보통 object literal이나 function으로 구현된다.

  • 활용

    채팅방 기능

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);
  }
}

CodeSandBox

Middleware

  • Middleware = middle software
    middleware는 request와 respond 사이에 있는 contoller다.

  • express가 middleware라는 용어를 대중화하여 구체적으로 디자인 패턴을 구현했다. 이를 통해 개발자가 프레임워크의 핵심에 손대지 않고도 새로운 기능을 쉽게 만들고 배포하여 기능을 추가할 수 있도록 했다.

  • 구조

  • middleware에 처리를 위한 새로운 데이터가 수신되면 등록된 middleware 들이 비동기 순차 실행 흐름으로 호출된다. next 함수가 req - res 사이클에 걸려있는 다음 callback을 호출한다.
    -각 middleware는 데이터의 추가적인 처리를 중단시킬 수 있다. callback을 호출하지 않거나 오류를 전파하여 동작한다.

  • 새로운 middleware는 use()함수를 통해 등록할 수 있다.

    const app = require('express')()
    
    app.use('/', (req, res, next) => {
      req.headers['test-header'] = 1234
      next()
    })
  • 활용

    이 미들웨어 패턴은 여러 객체 간 다대 다의 통신을 하나의 관리 포인트를 통하도록 만들어 관계를 단순하게 만들어준다.
    import express from "express";
    
    const app = express();
    
    const urlLogger = (req, res, next) => {
      console.log(`Path: ${req.path}`);
      next();
    };
    
    const timeLogger = (req, res, next) => {
      const today = new Date();
      const year = today.getFullYear();
      const month = today.getMonth() + 1;
      const day = today.getDate();
      const date = `${year}.${month}.${day}`;
      console.log(`Time: ${date}`);
      next();
    };
    
    const securityLogger = (req, res, next) => {
      req.protocol === "https" ? console.log("Secure") : console.log("Insecure");
      next();
    };
    
    const protector = (req, res) => {
      res.end();
    };
    
    app.use(urlLogger, timeLogger, securityLogger);
    app.get("/", (req, res) => res.send("<h1>Home</h1>"));
    app.get("/protected", protector, (req, res) => res.send("<h1>Protected</h1>"));
    
    app.listen(process.env.PORT, () => `Listening!✅`);

CodeSandBox

장단점

  • 장점
    • object들 간 수정을 하지 않고 관계를 수정할 수 있다.
    • object들 간의 관계의 복잡도, 의존성 및 결합도를 감소시킨다.
      다대 다의 복잡한 의존 관계를 풀어나감
  • 단점
    • 중재자에 권한이 집중되어 있으므로 잘못된 중재자의 설계는 더 복잡한 객체를 생성할 수 있다.

참고

Mediator/Middleware Pattern

  • JavaScript patterns - Stoyan Stefaonv
  • Node.js 디자인 패턴 바이블 - Mario Casciaro, Luciano Mammino
profile
성장하는 웹 프론트엔드 개발자 입니다.

0개의 댓글