MVC Pattern, DI, Singleton Pattern, IoC, NestJS

이재홍·2022년 2월 2일
0
post-custom-banner

MVC 패턴

모델-뷰-컨트롤러(model–view–controller, MVC)는 소프트웨어 공학에서 사용되는 소프트웨어 디자인 패턴이다. 이 패턴을 성공적으로 사용하면, 사용자 인터페이스로부터 비즈니스 로직을 분리하여 애플리케이션의 시각적 요소나 그 이면에서 실행되는 비즈니스 로직을 서로 영향 없이 쉽게 고칠 수 있는 애플리케이션을 만들 수 있다.

익스프레스 서버에서 요청을 받아 요청에 맞는 컨트롤러를 생성하고
컨트롤러에서 필요한 서비스들은 import한 후 인스턴스를 생성하여 MVC패턴의 컨트롤러부분을 구현해보았습니다. 퍼사드패턴으로 전체흐름을 보기 좋고 깔끔하게 만들었으나, 무언가 부족해보입니다.

index.js

import express from 'express';
import { ProductController } from './mvc/controllers/product.controller.js';
import { CouponController } from './mvc/controllers/coupon.controller.js';

const app = express();

// 상품 API
const productController = new ProductController();
app.post('/products/buy', productController.buyProduct);
app.post('/products/refund', productController.refundProduct);

// 쿠폰 API
const couponController = new CouponController();
app.post('./coupons/buy', couponController.buyCoupon);

app.listen(3000);

product.controller.js

import { ProductService } from './services/product.service.js';
import { CashService } from './services/cash.service.js';

export class ProductController {
  buyProduct = (req, res) => {
    const cashService = new CashService();
    const hasMoney = cashService.checkValue();

    const productService = new ProductService();
    const isSoldout = productService.checkSoldout();
    // 3. 상품 구매하는 코드
    if (hasMoney && !isSoldout) {
      res.send('상품을 구매합니다.');
    }
  };

  refundProduct = (req, res) => {
    const productService = new ProductService();
    const isSoldout = productService.checkSoldout();
    // 2. 상품 환불하는 코드
    if (isSoldout) {
      res.send('상품을 환불합니다.');
    }
  };
}

컨트롤러의 메소드에서 서비스가 필요할 때마다 서비스 객체를 계속해서 생성하고있습니다.
컨트롤러가 동작하기 위해서는 서비스가 필요하기에 컨트롤러는 서비스에 의존하고있으며 강하게 결합되어있습니다.

index.js

import express from 'express';
import { ProductController } from './mvc/controllers/product.controller.js';
import { CouponController } from './mvc/controllers/coupon.controller.js';
import { ProductService } from './mvc/controllers/services/product.service.js';
import { CashService } from './mvc/controllers/services/cash.service.js';
import { PointService } from './mvc/controllers/services/point.service.js';

const app = express();
const productService = new ProductService();
const moneyService1 = new CashService(); // new 한번으로 모든 곳에서 사용가능 (싱글톤 패턴)
const moneyService2 = new PointService(); // 포인트 결제 추가

// 상품 API
const productController = new ProductController(productService, moneyService1);
app.post('/products/buy', productController.buyProduct);
app.post('/products/refund', productController.refundProduct);

// 쿠폰 API
const couponController = new CouponController(moneyService2);
app.post('/coupons/buy', couponController.buyCoupon);

app.listen(3000);

보다 효율적이고 유지보수에 용이할 수 있도록 서비스의 객체(인스턴스)는 한번만 생성한 뒤에 컨트롤러를 생성할 때 생성자함수에 매개변수로 전달해주도록 코드를 바꾸었습니다.
이를 Constructor Inject(생성자 주입)을 사용해서 DI(Dependency Injection) 의존성 주입을 해주었다고 표현합니다. 이렇게 함으로써 강하게 결합되어있던 클래스들이 느슨한 결합으로 바뀌어 메모리 효율과 유지보수도 용이해졌습니다.

product.controller.js

export class ProductController {
  constructor(productService, moneyService) {
    this.productService = productService;
    this.moneyService = moneyService;
  }

  buyProduct = (req, res) => {
    const hasMoney = this.moneyService.checkValue();
    const isSoldout = this.productService.checkSoldout();
    // 3. 상품 구매하는 코드
    if (hasMoney && !isSoldout) {
      res.send('상품을 구매합니다.');
    }
  };

  refundProduct = (req, res) => {
    const isSoldout = this.productService.checkSoldout();
    // 2. 상품 환불하는 코드
    if (isSoldout) {
      res.send('상품을 환불합니다.');
    }
  };
}

싱글톤 패턴

객체의 인스턴스가 오직 한번만 생성되고 재사용될 경우 싱글톤패턴이라고 부릅니다.
앞서말한 의존성 주입과 비슷하지만 싱글톤 패턴은 객체를 한번만 생성한다는 점에서 다릅니다.

IoC (Inversion of Control )

이러한 패턴 흐름을 NestJS라는 프레임워크는 자동으로 해주는데 이를 제어가 역전되었다고 합니다.

제어의 역전(Inversion of Control)은 일반적인 디자인 패턴 중 하나입니다.
일반적으로 개발자가 프로그램의 흐름을 제어하는 주체였다면, IoC의 개념이 나오게 되며 프레임워크가 dependency를 container화 시켜 생명주기를 관리하게 되었습니다.
즉, dependency의 제어권이 개발자에서 프레임워크로 넘어가게 되었으며 이를 제어권의 흐름이변경되었다고 하여 IoC(Inversion of Control)이라고 하게됩니다.

NestJS

NestJS는 TypeScript(타입스크립트)를 지원하는 효율적이고 확장 가능한 Node.js의 서버 애플리케이션 프레임워크이며, OOP (Object Oriented Programming), FP (Functional Programming) 및 FRP (Functional Reactive Programming) 요소를 결합하는 특징을 가지고 있습니다.

NestJS를 사용함으로써 생산성이 증대되고 개발자들간의 서로가 작성한 코드의 구조를 알아보기 쉬워지고 유지보수도 용이해지는 장점을 얻을 수 있습니다.
nest를 사용하기 위해선 다음과 같이 전역으로 nest를 설치하여 nest 명령어를 사용할 수 있게 해주어야 합니다.

npm i -g @nestjs/cli

nest new 명령어를 사용하여 새 nest 프로젝트를 생성할수 있습니다.

nest new aaa

Nest는 기본적으로 타입스크립트를 지원하며, 개발하는데 필요한 부가적인 기능들도 포함되어있습니다.
eslintrc.js 파일은 여러명이 개발할 때 문법의 규칙을 통일하기 위해 사용되며
prettier는 코드가 보기좋고 깔끔하게 통일되게 만들어줍니다.
nest-cli.json 파일은 nest 설정파일입니다.

post-custom-banner

0개의 댓글