☀️ BE TIL Day 12 0329


⬇️ Main Note
https://docs.google.com/document/d/1w-Hvs30xbcNfWlWkO06nhAB1KIvPKHW9b3jCV146HNw/edit

🧀 Single-tone function



➡️ This whole flow is single-tone

🥨 VS Code

// ============ 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 cashService = new CashService(); // new 한번으로 모든 곳에서 재사용 가능 (싱글톤 패턴)
const pointService = new PointService();

// 상품 API 
const productController = new ProductController(cashService, productService); // Argument (인자 넘기기)
app.post("/products/buy", productController.buyProduct); // 상품 구매하기
app.post("/products/refund", productController.refundProduct); // 상품 환불하기

// 상품권(쿠폰) 구매 API
const couponController = new CouponController(pointService);
app.post("/coupons/buy", couponController.buyCoupon); // 쿠폰(상품권) 구매하기

app.listen(3000, () => {
  console.log(`🚀 Server launched 🚀`);
});
// ============ product.controller.js ============
export class ProductController {
  constructor(cashService, productService) {
    // parameter (변수를 받는 부분 )
    this.cashService = cashService;
    this.productService = productService;
    // cashService라는 거를 cashService 함수로 넣겠다이거
  }

  buyProduct = (req, res) => {
    // 1. 가진 돈 검증
    const hasMoney = this.cashService.checkValue();
    // 2. 판매 여부 검증
    const isSoldout = this.productService.checkSoldout();
    // 3. 상품 구매하는 코드  >> 핵심
    if (hasMoney && !isSoldout) {
      // hasMoney === true && isSoldout === false
      res.send("🛍 상품 구매 완료");
    }
  };

  refundProduct = (req, res) => {
    // 1. 판매 여부 검증
    const isSoldout = this.productService.checkSoldout();

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

🥨 Overview Diagram


  • Service is declared outside, and reuse it inside.
  • Easy to manage memory, since same function are used multiple times.
  • No need to declare anything in controllers.
  • 🥨 Flow



    ➡️ No need to change the whole code. => nest.js handles these actions by IoC.

    ➡️ Single tone can be used in diverse places since the declaration is held outside: Dependency Injection

    🧀 Dependency Injection _ nest.js



    ProductController is depending on CashService.
    ➡️ Here, to change the CashService , ProductController itself should be changed.
    ➡️ Injecting the dependency from const cashService = new CashService to cashService in index.js which is outside code.
    ➡️ Injecting the dependency by using nest.js.
  • nest.js does the job that the developers should do in DI.
  • Here, the control is taken by nest.js. (制御反転)
  • This action is called "Inversion of Control"(IoC)
    --> Inside nest.js, there is a tool that inverses the control: IoC container.
  • So what nest.js does, is declaring const cashService = new CashService() .
  • If config file of nest.js is properly done, IoC is possible.
    => this.cashService : Common commands in nest.js
  • 🥨 Quiz


    Q. If DI, then single-tone?
    A: No it isn't. Single-tone is just a basic-normal format of nest.js.
    => This can be adjusted by developers.

    ➡️ Here, yes they are having dependency injection, but they are not in a single-tone format.
    ➡️ The point of single-tone is once declared, diverse reusages.

    🧀 nest.js

    Language -- DI-framework
    ------------------------
      node 	      nest.js
      Java        spring
     Python       Django
    ➡️ DI-frameworks help dependency injection.

    🥨 How to use nest.js


    install: yarn add nest.jscreate: npx nest new newProjectNameexecute : node index.js(Executing in postman for example)
    POST http://localhost:3000/products/buy
    When uplaoding to git hurb, need to delete .git file inside the newly made nest.js file.
    ➡️ rm -rf .git

    🥨 File Structure



    🧀 Typescript


    🥨 Object type type setting

    interface IProfile {
        name: string
        age: number
    }
    
    let profile: IProfile = {
        name: 'Joobee',
        age: 18
    }
    
    profile.age = "aaa"	// => error

    🥨 Typescript Decorator


    Structure Flow
    function zzz(aaa) {
      console.log("=======");
      console.log(aaa);
      console.log("=======");
    }
    
    @zzz
    class AppController {}
    
    // ========== public ==========
    class Aaa {
      constructor(public myPower) {
        this.myPower = myPower;
      }
    
      ggg() {
        console.log("안녕 나는 Aaa"); // 의미없는 메소드
      }
    }
    const aaa = new Aaa(50);
    aaa.myPower = 5;
    
    // ========== private ==========
    class Bbb {
      constructor(private myPower) {
        // 이 안에서는 myPower 할당 가능함
        this.myPower = myPower;
      }
    
      ggg() {
        this.myPower = 10; // 접근 가능
        console.log("안녕 나는 Bbb");
      }
    }
    const bbb = new Bbb(50);
    bbb.ggg();
    // bbb.myPower = 5; // => 밖에서 접근이 불가능함 // 안에서만 접근 가능함
    
    // ========== Read Only ========== => 안전하게 가져다가 쓰기만 해라 안전하게, 이거임
    class Ccc {
      constructor(readonly myPower) {
        // 이 안에서는 myPower 할당 가능함
        this.myPower = myPower;
      }
    
      ggg() {
        this.myPower = 10; // 접근 불가능 (그냥 가져다가 쓰는거만 가능함)
        console.log("안녕 나는 Bbb");
      }
    }
    // const ccc = new Ccc(); // 외부에서 사용 불가능