의존성주입(Dependency Injection)




의존성 주입



진짜로

ㅡㅡ????????????? 이러고 들었던 수업….

이 와중에 졸릴까봐 서서들었는데 서서듣다가 졸아서 쓰러질뻔

큰웃음 드릴뻔했다 진짜….ㅋ….. 중간에 따라가다가 이해 1도 안가서 못따라 갈까봐 정신집중하다보니까 잠이 깸;;;;;

참으로 신박한 정신깨는 방법이네



진짜 단어가 너무 낯설고 익숙하지 않아서 어렵게 느껴진다.

한번도 들어보지 못한 단어들…. 계속해서 쏟아지는 개념들…..

진짜 절규 수준… 😱😱😱😱😱😱😱😱😱😱😱



한 프로젝트에서 연동되어있는 파일, 그러니까 MVC패턴을 사용하려다보니까 파일들을 여러개를 띄워놓고 코드를 작성해야하는데

이때 구조별로 층이 나눠서 나누어주는것을 레이어드 아키텍쳐라고 한다.


레이어드 아키텍쳐

인덱스1개, 컨트롤러2개(상하), 서비스2개(상하) 이렇게 5개의 파일을 이런식으로 구조별로 나누어주는것.

가장 기본적인 구조. 층이 나누어져있음. -단으로 읽음. ex)서비스단, 구매단

// product.controller.js

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

export class ProductController {
  buyProduct = (req, res) => {
    // 1. 가진돈 검증하는 코드 (10줄 => 2줄)
    const cashService = new CashService();
    const hasMoney = cashService.checkValue(); // true 또는 false 리턴

    // 2. 판매여부 검증하는 코드 (10줄 => 2줄)
    const productService = new ProductService();
    const isSoldout = productService.checkSoldout(); // true 또는 false 리턴

    // 3. 상품 구매하는 코드
    if (hasMoney && !isSoldout) {
      res.send("상품 구매 완료!!");
    }
  };

  refundProduct = (req, res) => {
    // 1. 판매여부 검증하는 코드 (대략 10줄 정도)
    const productService = new ProductService();
    const isSoldout = productService.checkSoldout(); // true 또는 false 리턴

    // 2. 상품 환불하는 코드
    if (isSoldout) {
      res.send("상품 환불 완료!!");
    }
  };
}

Tight Coupling

CouponController 클래스는 CashService에 의존하고 있다.

예를들어 17개의 파일이 잇는데 거기서 모두 하나의 CashService를 이용한다고 치면

CashService 하나를 변경하게 되면 17개의 파일도 자동으로 변경되는 것.

그래서 예외처리 없이 모두 변경되니까 유지보수에서 편하다고 생각했는데 아니었다.

하나의 파일을 바꾸면 다른 것들도 다 바뀔거라고 생각했는데,

어짜피 코어가 되는 애들은 변경이 되면 안되니까

그 파일은 수정하지 않기때문에 어짜피 코어를 가지고 있는 파일(=코어에 의존하는 파일)은 변경될 일이 적다.

그래서 매번 새로운 인스턴스로 가져와서 사용하기 때문에 변경점들을 놓칠 수 있다고 한다.


그리고 이걸 ‘강하게 결합되어있다’ 라고 표현하기도 한다. (=Tight Coupling)


강한결합의 특징

  • 하나의 객체를 변경하게 되면 다른 객체들을 변경을 요구되어 변경점들을 확인하고 쉽게 놓칠 수 있다.
  • 결합이 강하게 되어있어 결합이 되어있지 않으면 사용을 할 수 없게된다.
  • new를 선언할 때마다 컴퓨터 메모리를 사용하게 되는데 비교적으로 강한 결합에서 new를 더 많이 사용해 메모리를 많이 잡아먹게 된다.

RAM : 저장해놓는곳. 메모리. 끄면 삭제됨(대신 빠름. 임시저장)

new Controller();

이런식으로 인스턴스를 만들게되면 램에 공간이 생기면서 저장된다. 그런데 new를 사용하게 되면 메모리를 더 많이 잡아먹음

DISK : 영구저장. 조금 느림

CPU : 계산, 더하기, 나누기 등등 .그냥 일하는애. 컴퓨터 속도가 빠르다




Loose coupling



Loose coupling 특징

  • 클래스/클래스를 느슨하게 결합되어 새로운 기능을 개발하거나 기존 기능을 수정하고 확장하는게 쉽다.
  • 코드의 유지 보수가 쉽다.
  • 테스트 대역으로 치환하기가 쉬워 유닛 테스트가 용이.


그래서 강한결합일때는 느슨한결합으로 바꿔줄 필요가 있는데,

이러한 변경을 하는걸 DI(=의존성 주입)라고 함.

dependency injection (DI)

ex) ProductController가 CashService에 의존하고 있음(그래서 캐시서비스를 밖으로 꺼내줌) (cashService => 의존성)




Dependency Injection 의존성 주입

Tight Coupling(강한 결합)을 Loose Coupling(느슨한 결합)으로 전환 시키는 방법.

제어의 역전(Inversion of Control)의 기술 중 하나

  • 제어의 역전 : “내가 대신 제어해 줄게”
  • 의존성주입 : “니가 정의한 코드(클래스, 변수 등등)를”


그래서

DI(Dependency Injection) 의존성주입에 총 3가지의 방법이 존재하는데,

이 중 Constructor Inject(생성자 주입)이 많은 Design pattern에서 권장됨.

그래서 보면 비지니스로직인 ProductService에서 constructor을 주입함.

//product.controller.js


export class ProductController {
  constructor(cashService) {	//constructor주입
    this.cashService = cashService;
  }

  buyProduct = (req, res) => {
    // 1. 가진돈 검증하는 코드(10줄 => 2줄)
    const hasMoney = this.cashService.checkValue();

    // 판매여부 검증하는 코드(10줄 => 2줄)
    const isSoldout = this.productService.checkSoldout();

    // 3. 상품 구매하는 코드
    if (hasMoney && !isSoldout) {
      res.send("상품을 구매합니다.");
    }
  };
}


DI 프레임워크(대규모 프로젝트에 사용) : 대표적인게 스프링 프레임워크

(node.js에서도 있어야한다! 라고 해서 나온게 nest.js)

파이썬에서는 DI제공해주지 않아서 라이브러리에서 가져와서 써야함.

DI를 제공해주는 프레임워크가 많지 않다.

이 DI를 제공해주는 역할을 대신 해주는 nest.js 도구를 IoC 컨테이너(Inversion(되돌리다) of Control(통제): 관리를 바꾸다)라고 한다.

IoC : 우리가 원래는 하나하나씩 주입했었는데 이제는 자기네들이 알아서 해준다 (=DI해주는 애라고 생각하면 됨)


의존성주입으로 new를 2번 이상 할 필요가 없어짐. 또한 하나의 의존성을 여러곳에서 재사용(=싱글톤패턴)

=> 대상 class의 소스코드를 직접 수정하지 않고 변경 가능(cash service를 point service로 바꿔치기 했다 :⭐️핵심!!!!)





Singleton Pattern(싱글톤패턴)

싱글톤 패턴 : 객체의 인스턴스가 오직 1개만 생성되는 패턴

장점

  • 메모리 절약
  • 데이터 공유 쉬움

단점

  • 싱글톤 인스턴스가 너무 많은 일을 하거나 많은 데이터를 공유시킬경우에 다른 클래스 인스턴스들 간 결합도가 높아짐
  • 객체지향설계원칙에 벗어남 (근데 이건 DI를 지원해주는 프레임워크를 사용하면 보완 가능하다고 함)

출처 : https://devmoony.tistory.com/43

출처 : https://tecoble.techcourse.co.kr/post/2020-11-07-singleton/



의존성주입으로 얻을 수 있는 싱글톤패턴의 장점

  • new 한번으로 모든곳에서 사용 가능하게 됨
  • 강한결합이 느슨한 결합으로 풀리게 됨



그렇다면 ‘의존성 주입’이면 ‘싱글턴 패턴’인가요? => 🙅🏻‍♀️❌아님.

의존성 주입이어도 싱글톤 패턴이 아닐 수 있다. (디폴트가 싱글톤이었을뿐 반드시 그런것은 아님)







© 2018. by sora

Powered by sora