강한 결합과 느슨한 결합의 특징!

JBoB·2023년 1월 29일
0

🐧강한 결합(Tight Coupling)이란?

클래스와 객체가 서로 의존(Dependency) 하고 있는 것!

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

🐤강한 결합의 예시

//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줄 => class로 인해 2줄)
        const cashService = new CashService() //강한 결합
        const hasMoney = cashService.checkValue()
        
      
        //  2. 판매여부 검증하는 코드 (대략 10줄 => class로 인해 2줄)
        const productService = new ProductService() // 강한 결합
        const isSoldout = productService.checkSoldOut()
        //  3. 상품 구매하는 코드
        if(hasMoney && !isSoldout ){
          res.send("상품 구매 완료!!")
        }
      } 

    refundProduct =  (req,res) => {
        //  1. 판매여부 검증하는 코드 (대략 10줄 => class로 인해 2줄)
        const productService = new ProductService() //강한 결합 
        const isSoldout = productService.checkSoldOut()
      
      
        //  2. 상품 환불하는 코드
        if(isSoldout){
          res.send("상품 환불 완료!!")
        }
      }
}

ProductController 클래스에 선언한 메서드에서 CashService,ProductService 의 객체를 직접 생성해 메서드를 호출하는 형태 코드이다.

ProductController 클래스가 CashServiceProductService 클래스를 직접 사용해 생성한 객체에 의존하고 있는 강한 결합 상태이다.

⇒new 를 세번 사용해 메모리를 더 잡아먹는 단점이 생긴다.

⇒ ex) 여기서 CashServiceCouponService 로 바뀌게 되면 다른 객체들의 변경이 요구되며 하나하나 바꿔줘야하는 단점이 생긴다.

ProductControllerCashServiceProductService**의존성이 존재한다고 하는 것**이며,

다른 말로는 **강하게 결합되어 있다(Tight Coupling)**라고도 부른다.

🐧느슨한 결합(Loose-coupling)

  • 클래스/클래스를 느슨하게 결합되어 새로운 기능을 개발하거나 기존 기능을 수정하고 확장하는게 쉽다.
  • 유지 보수가 쉽다.
  • 메모리 사용을 줄일 수 있다.
// index.js

// const express = require('express') // 옛날방식 => commonjs
import express from "express"; // 요즘방식 => module
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";

const app = express();

// 추가되는 부분
const cashService = new CashService();

// 상품 API
const productController = new ProductController(cashService);
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, () => {
  console.log("백엔드 API 서버가 켜졌어요!!!");
});

controller.js 에 있는 new Cashservice() 을 index.js 밖에서 실행시켜 준다.

ProductController 인자를 cashService 을 넣어줌으로써 cashService 를 생성자로 넣어주게 된다.

그리고 product.controller.js 파일에서 constructor(){} 함수를 추가해준다.

// product.controller.js

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

export class ProductController {
	  //추가 코드 🐥
		constructor(cashService) {
    this.cashService = cashService;
  }

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

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

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

  refundProduct = (req, res) => {
    // 1. 판매여부 검증하는 코드(10줄 => 2줄 => 1줄)
    const productService = new ProductService()
    const isSoldout = productService.checkSoldout();

    // 2. 상품 환불하는 코드
    if (isSoldout) {
      res.send("상품을 환불합니다.");
    }
  };
}

그리곤 hasMoney 선언해준 코드에서 cashService 앞에 this.를 반드시 붙여줘야한다.

this.을 사용하게 되면 ProductController class 안의 함수들 선택이 가능해지게 됩니다!

이와 같은 결과로 보면,

ProductController 클래스는 CashService 클래스를 사용해 객체를 생성하지 않는다.

ProductController 외부에서 객체를 생성하여 constructor를 통해 안으로 전달하는 형태이다.

Constructor Injection(생성자 주입)을 사용하는 의존성 주입(Dependency Injection)으로 두 클래스를 느슨한 결합 상태로 만든 것이다.

🐤의존성 주입(DI)로 발생하는 장점?

  • new 한번으로 모든 곳에서 재사용 가능(싱글톤패턴)
  • 의존성 주입으로 한꺼번에 변경 가능
  • 의존성 주입으로 코드를 안전하게 변경가능
  • 의존성 주입으로 강한결합을 느슨한 결합으로 바꿀수 있다.

✋ 주의점 . 의존성주입 으로 싱글톤 패턴 을 구현가능하게 하지만 의존성주입싱글톤 패턴이 아니다.

🐤 싱글톤 패턴이란?

객체의 인스턴스가 오직 1개만 생성되는 패턴이다.

인스턴스 ??

비슷한 성질(?)을 가진 여러개의 객체를 만들기 위해서 생성자 함수, Constructor를 만들어 찍어내듯이 사용하는데 이렇게 생성된 객체를 인스턴스라 부를 수 있습니다. 객체지향언어에서 흔히 사용되는 클래스(Class)가 자바스크립트에서는 프로토타입(prototype)이며 생성자 함수가 사용됩니다. 다시 말하면 클래스나 프로토타입을 사용하여 만들어 낸 것이 인스턴스라고 볼 수 있습니다.

🐤싱글톤 패턴을 사용하는 이유

  • 최초 한번의 New 연산자를 통해 메모리 낭비를 방지 할 수있다.
  • 다른 클래스 간에 데이터 공유가 쉽다.
profile
간절하고 치열하게 살자

0개의 댓글