๐ŸฆŠcodecamp 10~13์ผ์ฐจ ์ •๋ฆฌ๋ณธ

JBoBยท2023๋…„ 2์›” 25์ผ
0
post-custom-banner

๐Ÿงย ์Šคํฌ๋ž˜ํ•‘ 10์ผ์ฐจ

์Šคํฌ๋ž˜ํ•‘

: ์–ด๋–ค ํŠน์ •ํ•œ ์›น์‚ฌ์ดํŠธ์— ๊ฐ€์„œ ๊ทธ ์‚ฌ์ดํŠธ์˜ HTML๋ฅผ ๊ธ์–ด์˜ค๋Š” ๊ฒƒ์ด๋‹ค.

๐Ÿ’ก **์–ธ์ œ ์“ฐ์ด๋‚˜์š”?**

์Šฌ๋ž™์ด๋‚˜ ์นดํ†ก์„ ์‚ฌ์šฉํ•  ๋•Œ, ๋งํฌ๋ฅผ ๊ณต์œ ํ•˜๋ฉด ๋ฐ‘์— ์ž๋™์œผ๋กœ ์‚ฌ์ดํŠธ์˜ ์†Œ๊ฐœ์™€ ์ด๋ฏธ์ง€๊ฐ€ ๋‚˜์˜ต๋‹ˆ๋‹ค!
ํ”„๋ก ํŠธ์—”๋“œ๋‚˜ ๋ฐฑ์—”๋“œ์—์„œ ์ง์ ‘ ์‚ฌ์ดํŠธ์— ๊ฐ€์„œ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์œ ์ €๊ฐ€ ๊ฒŒ์‹œ๊ธ€์„ ์ž‘์„ฑํ•ด์„œ ๋“ฑ๋กํ•  ๋•Œ, ๋ฐฑ์—”๋“œ API๋กœ ๊ธ€์˜ ๋‚ด์šฉ์„ ๋ณด๋‚ด์ฃผ๊ฒŒ ๋œ๋‹ค.

๊ธ€์˜ ๋‚ด์šฉ์— http๊ฐ€ ํฌํ•จ๋œ URL์ด ์žˆ๋‹ค๋ฉด, ๊ทธ ์‚ฌ์ดํŠธ์— ์ ‘์†ํ•˜์—ฌ open graph๊ฐ€ ์žˆ๋Š” ๋‚ด์šฉ์„ ๊ธ์–ด์™€์„œ ์ €์žฅํ•œ๋‹ค.

ํƒœ๊ทธ ์•ˆ์— meta ํƒœ๊ทธ๋“ค์ด ์žˆ๊ณ  og ๋กœ ์‹œ์ž‘ํ•˜๋Š” ํƒœ๊ทธ๋“ค์ด ๋ณด์ธ๋‹ค.
  1. og:title - ์‚ฌ์ดํŠธ์˜ ์ œ๋ชฉ ํƒœ๊ทธ
  2. og:type - ์‚ฌ์ดํŠธ์˜ ์ข…๋ฅ˜ ์Šคํƒ€์ผ ์˜ˆ) video.movie
  3. og:image - ์‚ฌ์ดํŠธ๋ฅผ ๋‚˜ํƒ€๋‚ผ ๋Œ€ํ‘œ ์ด๋ฏธ์ง€
  4. og:url - ์‚ฌ์ดํŠธ์˜ ๋Œ€ํ‘œ url
  5. og:description - ์‚ฌ์ดํŠธ์˜ ์„ค๋ช…

ํฌ๋กค๋ง

: ์‚ฌ์ „์ ์˜๋ฏธ๋กœ๋Š” ๊ธฐ์–ด๋‹ค๋‹Œ๋‹ค๋Š” ๋œป์ธ๋ฐ ์—ฌ๋Ÿฌ ์›น ์‚ฌ์ดํŠธ๋“ค์„ ๋Œ์•„๋‹ค๋‹ˆ๋ฉฐ ์Šคํฌ๋ž˜ํ•‘(ํ•˜์œ„์–ด)์„ ์ •๊ธฐ์ ์œผ๋กœ ์ฃผ๊ธฐ์ ์œผ๋กœ ํ•˜๋Š” ๊ฒƒ์„ ๋งํ•œ๋‹ค.

์Šคํฌ๋ž˜ํ•‘์„ ๋„์™€์ฃผ๋Š” cheerio ์„ค์น˜ํ•˜๊ธฐ

yarn add cheerio

======

//index.js

import axios from 'axios'
import cheerio from 'cheerio'

const createMessage = async () => {
    // ์ž…๋ ฅ๋œ ๋ฉ”์‹œ์ง€: "์•ˆ๋…•ํ•˜์„ธ์š”~ https://www.naver.com ์— ๋ฐฉ๋ฌธํ•ด ์ฃผ์„ธ์š”!"

    // 1. ์ž…๋ ฅ๋œ ๋ฉ”์‹œ์ง€์—์„œ http๋กœ ์‹œ์ž‘ํ•˜๋Š” ๋ฌธ์žฅ์ด ์žˆ๋Š”์ง€ ๋จผ์ € ์ฐพ๊ธฐ!(.find() ๋“ฑ์˜ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์‚ฌ์šฉํ•˜๊ธฐ)
    const url = "https://www.daum.net"

    // 2. axios.get์œผ๋กœ ์š”์ฒญํ•ด์„œ html์ฝ”๋“œ ๋ฐ›์•„์˜ค๊ธฐ => ์Šคํฌ๋ž˜ํ•‘
    const result = await axios.get(url)
    console.log(result.data)

    // 3. ์Šคํฌ๋ž˜ํ•‘ ๊ฒฐ๊ณผ(result)์—์„œ OG(์˜คํ”ˆ๊ทธ๋ž˜ํ”„) ์ฝ”๋“œ ๊ณจ๋ผ๋‚ด์„œ ๋ณ€์ˆ˜์— ์ €์žฅํ•˜๊ธฐ
    const $ = cheerio.load(result.data)
    $("meta").each((i, el) => {
        if($(el).attr("property") && $(el).attr("property").includes("og:")){
            const key = $(el).attr("property") // og:title, og:description, ...
            const value = $(el).attr("content") // ๋„ค์ด๋ฒ„, ๋„ค์ด๋ฒ„ ๋ฉ”์ธ์—์„œ ~~~
            console.log(key, value)
		// attr: ์†์„ฑ์„ ๊ฐ€์ ธ์˜ค๋Š” ๋ฉ”์„œ๋“œ
		// each: Cherio ๊ฐ์ฒด๋ฅผ ๋ฐ˜๋ณตํ•˜์—ฌ ์ผ์น˜ํ•˜๋Š” ๊ฐ ์š”์†Œ์— ๋Œ€ํ•œ ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰
        }
    })

}

createMessage()

๐Ÿงย Class & OOP 12์ผ์ฐจ

class

: ํด๋ž˜์Šค(class) ๋Š” ๊ฐ์ฒด ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ ํŠน์ • ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•ด ๋ณ€์ˆ˜์™€ ๋ฉ”์†Œ๋“œ๋ฅผ ์ •์˜ํ•˜๋Š” ์ผ์ข…์˜ ํ‹€๋กœ ๊ฐ์ฒด๋ฅผ ์ •์˜ํ•˜๊ธฐ ์œ„ํ•œ ์ƒํƒœ(๋ณ€์ˆ˜)์™€ ๋ฉ”์„œ๋“œ(ํ•จ์ˆ˜) ๋กœ ๊ตฌ์„ฑ๋œ๋‹ค.

class โ‡’ ๋ฌผ๊ฑด ๋งŒ๋“œ๋Š” ์„ค๋ช…์„œ

์‹ค๋ฌด์—์„  ์‚ฌ์šฉ์ž๋‚˜ ๋ฌผ๊ฑด๊ฐ™์ด ๋™์ผํ•œ ์ข…๋ฅ˜์˜ ๊ฐ์ฒด๋ฅผ ์—ฌ๋Ÿฌ๊ฐœ ์ƒ์„ฑํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ ํด๋ž˜์Šค ์‚ฌ์šฉ

class Date{
	getFullyear(){
		}
	getMonth(){
		}
}

const aaa = new Date()
console.log(aaa.getFullyear())
console.log(aaa.getMonth() + 1)

=> aaa์— Date ๋ฅผ ํ• ๋‹นํ•ด์ฃผ๋ฉด getMonth,getFullyear ๊ฐ์ฒด ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ• ์ˆ˜ ์žˆ๋‹ค.
์ด๋Ÿฌํ•œ ๊ฐ์ฒด๋ฅผ **๋‚ด์žฅ๊ฐ์ฒด** ๋ผ๊ณ  ํ•œ๋‹ค.

class ๊ธฐ์ดˆ

// index.js
class Monster {
    power = 10

    // ์ƒ์„ฑ์ž ๋ฐ‘์— new monster() ๊ฐ€๋กœ์— ์‹คํ–‰์‹œ์ผœ์ฃผ๋Š” ํ•จ์ˆ˜
    constructor(qqq){ => ์ดˆ๊ธฐ๊ฐ’ ์ƒ์„ฑ๊ฐ€๋Šฅ!
        this.power = qqq
    }

    attack = () => {
        console.log("๊ณต๊ฒฉํ•˜์ž!!!");
        console.log("๋‚ด ๊ณต๊ฒฉ๋ ฅ์€" + this.power + "์•ผ");
    }

    run = () => {
        console.log("๋„๋ง์ณ!!!");
    }
}

const mymonster1 = new Monster(20)
mymonster1.attack()
mymonster1.run()

const mymonster2 = new Monster(50)
mymonster2.attack()
mymonster2.run()
// ๊ฒฐ๊ณผ
๊ณต๊ฒฉํ•˜์ž!!!
๋‚ด ๊ณต๊ฒฉ๋ ฅ์€20์•ผ
๋„๋ง์ณ!!!
๊ณต๊ฒฉํ•˜์ž!!!
๋‚ด ๊ณต๊ฒฉ๋ ฅ์€50์•ผ
๋„๋ง์ณ!!!

class ์ƒ์† ์‹ค์Šต(extends)

class Monster {
    power = 10

    // ์ƒ์„ฑ์ž ๋ฐ‘์— new monster() ๊ฐ€๋กœ์— ์‹คํ–‰์‹œ์ผœ์ฃผ๋Š” ํ•จ์ˆ˜
    constructor(qqq){
        this.power = qqq
    }

    attack = () => {
        console.log("๊ณต๊ฒฉํ•˜์ž!!!");
        console.log("๋‚ด ๊ณต๊ฒฉ๋ ฅ์€" + this.power + "์•ผ");
    }

    run = () => {
        console.log("๋„๋ง์ณ!!!");
    }
}

// ์ƒ์†ํŒจํ„ด์„ ์จ์ค„๋–„๋Š” extends์„ ๋ถ™์—ฌ์ค€๋‹ค!
class ๊ณต์ค‘๋ชฌ์Šคํ„ฐ extends Monster{
    // nest.js์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๊ตฌ๋ฌธ
    constructor(aaa){
        super(aaa + 1) 
    }
    
    // ์˜ค๋ฒ„๋ผ์ด๋”ฉ(๋ถ€๋ชจ์˜ run์„ ๋ฎ์–ด์”€)
    run = () => {
        console.log("๋‚ ์•„์„œ ๋„๋ง์ณ!!!");
    }
}

class ์ง€์ƒ๋ชฌ์Šคํ„ฐ extends Monster{
    // nest.js์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๊ตฌ๋ฌธ
    constructor(bbb){
        super(bbb)
    }
    

    // ์˜ค๋ฒ„๋ผ์ด๋”ฉ(๋ถ€๋ชจ์˜ run์„ ๋ฎ์–ด์”€) 
    run = () => {
        console.log("๋›ฐ์–ด์„œ ๋„๋ง์ณ!!!");
    }
}

const mymonster1 = new ๊ณต์ค‘๋ชฌ์Šคํ„ฐ(20)
mymonster1.attack()
mymonster1.run()

const mymonster2 = new ์ง€์ƒ๋ชฌ์Šคํ„ฐ(50)
mymonster2.attack()
mymonster2.run()

//๊ฒฐ๊ณผ
๊ณต๊ฒฉํ•˜์ž!!!
๋‚ด ๊ณต๊ฒฉ๋ ฅ์€21์•ผ
๋‚ ์•„์„œ ๋„๋ง์ณ!!!
๊ณต๊ฒฉํ•˜์ž!!!
๋‚ด ๊ณต๊ฒฉ๋ ฅ์€50์•ผ
๋›ฐ์–ด์„œ ๋„๋ง์ณ!!!

super : ํ˜„์žฌ power ๋ณ€์ˆ˜๋Š” ์ƒ์†ํ•ด ์ค€ Monster ๋‚ด๋ถ€์— ์กด์žฌํ•˜๋ฏ€๋กœ, Monster class ๋‚ด๋ถ€์— ์žˆ๋Š” constructor ๋กœ ์ธ์ˆ˜๋ฅผ ๋„˜๊ฒจ์ฃผ๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ

Class ์ „๋žต ํŒจํ„ด ์‹ค์Šต(****Strategy Pattern****)

class ๊ณต์ค‘๋ถ€ํ’ˆ {
    run = () => {
        console.log("๋‚ ๋ผ์„œ ๋„๋ง์ณ!!!");
    }
}

class ์ง€์ƒ๋ถ€ํ’ˆ {
    run = () => {
        console.log("๋›ฐ์–ด์„œ ๋„๋ง์ณ!!!");
    }
}

class Monster {
    power = 10
    ๋ถ€ํ’ˆ;
    // ์ƒ์„ฑ์ž ๋ฐ‘์— new monster() ๊ฐ€๋กœ์— ์‹คํ–‰์‹œ์ผœ์ฃผ๋Š” ํ•จ์ˆ˜
    constructor(qqq){
        this.๋ถ€ํ’ˆ = qqq
    }

    attack = () => {
        console.log("๊ณต๊ฒฉํ•˜์ž!!!");
        console.log("๋‚ด ๊ณต๊ฒฉ๋ ฅ์€" + this.power + "์•ผ");
    }

    run = () => {
        this.๋ถ€ํ’ˆ.run()
    }
}

const aaa = new ๊ณต์ค‘๋ถ€ํ’ˆ()
const bbb = new ์ง€์ƒ๋ถ€ํ’ˆ()

const mymonster1 = new Monster(aaa)
mymonster1.attack()
mymonster1.run()

const mymonster2 = new Monster(bbb)
mymonster2.attack()
mymonster2.run()

๊ฐ์ฒด ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(Object-Oriented-Programming)?

  • ์ปดํ“จํ„ฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ํŒจ๋Ÿฌ๋‹ค์ž„ ์ค‘ ํ•˜๋‚˜๋‹ค

โ‡’ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ํŒจ๋Ÿฌ๋‹ค์ž„ : ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์Šคํƒ€์ผ, ์ „์ฒด์ ์ธ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ฐฉ์‹

  • ์ตœ์†Œ ๋‹จ์œ„๊ฐ€ ๊ฐ์ฒด์ด๋ฉฐ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๊ณ , ์ด ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ์™€ ๋ฉ”์†Œ๋“œ๋ฅผ ๋ฌถ๊ณ  ์†Œํ†ตํ•˜๋Š” ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ฐฉ์‹์ด๋‹ค.
  • ์ง๊ด€์ ์ด๋ฉฐ ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์‰ฝ๋‹ค.
  • ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์ถ”์ƒํ™” ์‹œ์ผœ ์ƒํƒœ์™€ ํ–‰์œ„๋ฅผ ๊ฐ€์ง„ ๊ฐ์ฒด ๋กœ ๋งŒ๋“ค๊ณ , ๊ฐ์ฒด๋“ค๊ฐ„์˜ ์ƒํ˜ธ์ž‘์šฉ์„ ํ†ตํ•ด ๋กœ์ง์„ ๊ตฌ์„ฑํ•˜๋Š” ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ฐฉ๋ฒ•์ด๋‹ค.

๊ฐ์ฒด ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(OOP)**์˜ 4๊ฐ€์ง€ ํŠน์ง•**

1. ์ถ”์ƒํ™”(Abstraction)

  • ์ถ”์ƒํ™”๋Š” ๋ชฉ์ ๊ณผ ๊ด€๋ จ์ด ์—†๋Š” ๋ถ€๋ถ„์„ ์ œ๊ฑฐํ•˜์—ฌ ํ•„์š”ํ•œ ๋ถ€๋ถ„๋งŒ์„ ํ‘œํ˜„
  • ์‚ฌ๋ฌผ๋“ค์˜ ๊ณตํ†ต์ ์ธ ํŠน์ง•, ์ถ”์ƒ๋œ ํŠน์ง•์„ ํŒŒ์•…ํ•ด ์ธ์‹์˜ ๋Œ€์ƒ์œผ๋กœ ์‚ผ๋Š” ํ–‰์œ„
  • ์ถ”์ƒํ™”๋Š” ๊ตฌ์ฒด์ ์ธ ์‚ฌ๋ฌผ๋“ค์˜ ๊ณตํ†ต์ ์ธ ํŠน์ง•์„ ํŒŒ์•…ํ•ด์„œ ์ด๋ฅผ ํ•˜๋‚˜์˜ ์ง‘ํ•ฉ์œผ๋กœ ๋‹ค๋ฃจ๋Š” ์ˆ˜๋‹จ.

์•„์šฐ๋””์™€ ๋ฒค์ธ ๋Š” ๋ชจ๋‘ ์ž๋™์ฐจ์— ํ•ด๋‹นํ•œ๋‹ค.

๋”ฐ๋ผ์„œ ์ž๋™์ฐจ๋ผ๋Š” ์ง‘๋‹จ์„ ์ถ”์ƒํ™”ํ•˜์—ฌ ํ•˜๋‚˜์˜ ์ง‘ํ•ฉ์œผ๋กœ ๋งŒ๋“ค์–ด ๋†“์„ ์ˆ˜ ์žˆ๋‹ค.

2. ์บก์Šํ™”(Encapsulation)

์บก์Šํ™” : ํ•˜๋‚˜์˜ ๊ฐ์ฒด์— ๋Œ€ํ•ด ๊ทธ ๊ฐ์ฒด๊ฐ€ ํŠน์ •ํ•œ ๋ชฉ์ ์„ ์œ„ํ•œ ํ•„์š”ํ•œ ๋ณ€์ˆ˜๋‚˜ ๋ฉ”์†Œ๋“œ๋ฅผ ํ•˜๋‚˜๋กœ ๋ฌถ๋Š” ๊ฒƒ

  • ์‘์ง‘๋„ : ํด๋ž˜์Šค๋‚˜ ๋ชจ๋“ˆ ์•ˆ์˜ ์š”์†Œ๊ฐ€ ์–ผ๋งˆ๋‚˜ ๋ฐ€์ ‘ํ•˜๊ฒŒ ๊ด€๋ จ ์žˆ๋Š”์ง€๋ฅผ ๋‚˜ํƒ€๋‚ธ๋‹ค.
  • ๊ฒฐํ•ฉ๋„: ์–ด๋–ค ๊ธฐ๋Šฅ์„ ์‹คํ–‰ํ•˜๋Š”๋ฐ ๋‹ค๋ฅธ ํด๋ž˜์Šค๋‚˜ ๋ชจ๋“ˆ์— ์–ผ๋งˆ๋‚˜ ์˜์กดํ•˜๋Š”์ง€ ๋‚˜ํƒ€๋‚ธ๋‹ค.
  • ์ •๋ณด์€๋‹‰: ์บก์Šํ™”๋Š” ์ •๋ณด์€๋‹‰์„ ํ†ตํ•ด ๋†’์€ ์‘์ง‘๋„์™€ ๋‚ฎ์€ ๊ฒฐํ•ฉ๋ ฅ์„ ๊ฐ€์ง€๊ฒŒ ๋œ๋‹ค.

3. ์ƒ์†์„ฑ(Inheritance)

์ƒ์†์ด๋ž€ ๊ธฐ์กดย ์ƒ์œ„ ํด๋ž˜์Šค์— ๊ทผ๊ฑฐํ•˜์—ฌ ์ƒˆ๋กญ๊ฒŒ ํด๋ž˜์Šค์™€ ํ–‰์œ„๋ฅผ ์ •์˜ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋„์™€์ฃผ๋Š” ๊ฐœ๋…์ž…๋‹ˆ๋‹ค.

  • ๊ธฐ์กด ํด๋ž˜์Šค์˜ย ๊ธฐ๋Šฅ์„ ๊ฐ€์ ธ์™€ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฉด์„œ๋„ย ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค.
  • ์—ฌ๋Ÿฌ ๊ฐœ์ฒด๊ฐ€ ๊ฐ€์ง„ ๊ณตํ†ต๋œ ํŠน์„ฑ์„ ๋ถ€๊ฐ์‹œ์ผœ ํ•˜๋‚˜์˜ ๊ฐœ๋…์ด๋‚˜ ๋ฒ•์น™์œผ๋กœ ์„ฑ๋ฆฝ์‹œํ‚ค๋Š” ๊ณผ์ •์ž…๋‹ˆ๋‹ค.
  • ๋”ฐ๋ผ์„œ ๊ฐ™์€ ํŠน์ง•์ด ์žˆ๋Š” ํด๋ž˜์Šค๋ฅผ ๊ทธ๋Œ€๋กœ ๋ฌผ๋ ค๋ฐ›์•„, ๋‹ค์‹œ ์ž‘์„ฑํ•  ํ•„์š” ์—†์ด ์žฌ์‚ฌ์šฉ์œผ๋กœ ํšจ์œจ์„ฑ์„ ๋†’์ž…๋‹ˆ๋‹ค.
  • ์ด๋ฅผ ํ†ตํ•ดย ๋‹คํ˜•์„ฑ์„ ํ™•๋ณดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

4. ๋‹คํ˜•์„ฑ(polymorphism)

๋‹คํ˜•์„ฑ์€ ์ƒ์†์„ ํ†ตํ•ดย ๊ธฐ๋Šฅ์„ ํ™•์žฅํ•˜๊ฑฐ๋‚˜ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒƒ์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค. ์ฆ‰, ๋‹คํ˜•์„ฑ์€ ํ˜•ํƒœ๊ฐ€ ๊ฐ™์€๋ฐ ๋‹ค๋ฅธ ๊ธฐ๋Šฅ์„ ํ•˜๊ณ  ์„œ๋กœ ๋‹ค๋ฅธ ํด๋ž˜์Šค์˜ ๊ฐ์ฒด๊ฐ€ ๊ฐ™์€ ๋ฉ”์‹œ์ง€๋ฅผ ๋ฐ›์•˜์„ ๋•Œ ๊ฐ์ž์˜ ๋ฐฉ์‹์œผ๋กœ ๋™์ž‘ํ•˜๋Š” ๋Šฅ๋ ฅ์ž…๋‹ˆ๋‹ค.

  • ๋‹คํ˜•์„ฑ์€ย ์ƒ์†๊ณผ ์—ฐ๊ณ„๋˜์–ด ๋™์ž‘ํ•˜๋ฉด ๋งค์šฐ ๊ฐ•๋ ฅํ•œ ํž˜์„ ๋ฐœํœ˜ํ•ฉ๋‹ˆ๋‹ค.
  • ๋‹คํ˜•์„ฑ๊ณผ ์ผ๋ฐ˜ํ™” ๊ด€๊ณ„๋Š” ์ฝ”๋“œ๋ฅผ ๊ฐ„๊ฒฐํ•˜๊ฒŒ ํ•˜์—ฌ ์žฌ์‚ฌ์šฉ๊ณผ ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์šฉ์ดํ•˜๋„๋ก ๋„์™€์ฃผ๊ณ  ๋ณ€ํ™”์—๋„ ์œ ์—ฐํ•˜๊ฒŒ ๋Œ€์ฒ˜ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค.
๐Ÿ’ก **`์˜ค๋ฒ„๋ผ์ด๋”ฉ(Overriding)`**
  • ๋ถ€๋ชจ ํด๋ž˜์Šค์—์„œ ์ƒ์†๋ฐ›์€ ์ž์‹ ํด๋ž˜์Šค์—์„œ ๋ถ€๋ชจ ํด๋ž˜์Šค์—์„œ ๋งŒ๋“ค์–ด์ง„ ๋ฉ”์„œ๋“œ๋ฅผ ์ž์‹ ์˜ ์ž…๋ง›๋Œ€๋กœ ๋‹ค์‹œย ์žฌ์ •์˜ํ•ด์„œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ๋งํ•ฉ๋‹ˆ๋‹ค.

์˜ค๋ฒ„๋กœ๋”ฉ(Overloading)

  • ๊ฐ™์€ ์ด๋ฆ„์˜ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์ง€๋งŒ ๋ฉ”์„œ๋“œ๋งˆ๋‹คย ๋‹ค๋ฅธ ์šฉ๋„๋กœ ์‚ฌ์šฉ๋˜๋ฉฐ ๊ทธ ๊ฒฐ๊ณผ๋ฌผ๋„ ๋‹ค๋ฅด๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋งŒ๋“œ๋Š” ๊ฐœ๋…์ž…๋‹ˆ๋‹ค.
  • ์˜ค๋ฒ„๋กœ๋”ฉ์ด ๊ฐ€๋Šฅํ•˜๋ ค๋ฉด ๋ฉ”์„œ๋“œ๋ผ๋ฆฌ ์ด๋ฆ„์€ ๊ฐ™์ง€๋งŒ ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ๊ฐฏ์ˆ˜๋‚˜ ๋ฐ์ดํ„ฐ ํƒ€์ž…์ด ๋‹ค๋ฅด๋ฉด ์˜ค๋ฒ„๋กœ๋”ฉ์ด ์ ์šฉ๋ฉ๋‹ˆ๋‹ค.

๐Ÿคย MVC ํŒจํ„ด

Design Pattern?

  • ๋””์ž์ธ ํŒจํ„ด์ด๋ž€ ํ”„๋กœ๊ทธ๋žจ์ด๋‚˜ ์–ด๋–ค ํŠน์ •ํ•œ ๊ฒƒ์„ ๊ฐœ๋ฐœํ•˜๋Š” ์ค‘์— ๋ฐœ์ƒํ–ˆ๋˜ ๋ฌธ์ œ์ ๋“ค์„ ์ •๋ฆฌํ•ด์„œ ์ƒํ™ฉ์— ๋”ฐ๋ผ ๊ฐ„ํŽธํ•˜๊ฒŒ ์ ์šฉํ•ด์„œ ์“ธ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์„ ์ •๋ฆฌํ•˜์—ฌ ํŠน์ •ํ•œ โ€˜๊ทœ์•ฝโ€™์„ ํ†ตํ•ด ์‰ฝ๊ฒŒ ์“ธ ์ˆ˜ ์žˆ๋Š” ํ˜•ํƒœ๋กœ ๋งŒ๋“  ๊ฒƒ . ๊ทธ ์ค‘ ํ•˜๋‚˜๊ฐ€ MVC ํŒจํ„ด์ด๋‹ค.

MVC(Model-View-Controller) Pattern

MVC ๋Š” ์œ„ ๊ทธ๋ฆผ๊ณผ ๊ฐ™์ด ์„ธ๊ฐœ๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ๋‹ค. ํ•˜๋‚˜์˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜, ํ”„๋กœ์ ํŠธ๋ฅผ ๊ตฌ์„ฑํ•  ๋•Œ ๊ทธ ๊ตฌ์„ฑ์š”์†Œ๋ฅผ ์„ธ๊ฐ€์ง€์˜ ์—ญํ• ๋กœ ๊ตฌ๋ถ„ํ•œ ํŒจํ„ด.

controllers ์—์„œ๋Š” ๋ฏธ๋“ค์›จ์–ด ํ•จ์ˆ˜๋ฅผ ๋ถ„๋ฆฌํ•ด์„œ ๊ด€๋ฆฌํ•ด ์ค„ ๊ฒƒ์ด๋‹ค.

models ์—์„œ๋Š” DB ์ƒ์„ฑ์„ ๊ด€๋ฆฌํ•ด์ฃผ๋Š” ๊ณณ์œผ๋กœ ์ด์ „์— ๋ฐฐ์šด Schema ์ •์˜๋ฅผ ํ•ด ์ค€ ํด๋”์™€ ๋™์ผํ•˜๋‹ค.

view ์—๋Š” ํ™”๋ฉด์— ๋ณด์—ฌ์ง€๋Š” ํŒŒ์ผ๋“ค(html ํŒŒ์ผ)์„ ๊ด€๋ฆฌํ•ด์ฃผ๋Š” ํด๋”

์œ„์˜ ๊ทธ๋ฆผ์ฒ˜๋Ÿผ ์‚ฌ์šฉ์ž๊ฐ€ controller๋ฅผ ์กฐ์ž‘ํ•˜๋ฉด controller๋Š” model์„ ํ†ตํ•ด์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๊ณ  ๊ทธ ์ •๋ณด๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ์‹œ๊ฐ์ ์ธ ํ‘œํ˜„์„ ๋‹ด๋‹นํ•˜๋Š” View๋ฅผ ์ œ์–ดํ•ด์„œ ์‚ฌ์šฉ์ž์—๊ฒŒ ์ „๋‹ฌํ•˜๊ฒŒ ๋œ๋‹ค.

๐Ÿงย ๋Š์Šจํ•œ๊ฒฐํ•ฉ๊ณผ ๊ฐ•ํ•œ๊ฒฐํ•ฉ 13์ผ์ฐจ

๐ŸคTight-coupling & Dependency

  • ๊ฐ•ํ•œ ๊ฒฐํ•ฉ์€ ํด๋ž˜์Šค์™€ ๊ฐ์ฒด๊ฐ€ ์„œ๋กœ ์˜์กดํ•˜๊ณ  ์žˆ๋Š” ๊ฒƒ์ด๋‹ค.

๊ฐ•ํ•œ ๊ฒฐํ•ฉ(Tight Coupling)์˜ ํŠน์ง•

  • ํ•˜๋‚˜์˜ ๊ฐ์ฒด๋ฅผ ๋ณ€๊ฒฝํ•˜๊ฒŒ ๋˜๋ฉด ๋‹ค๋ฅธ ๊ฐ์ฒด๋“ค์„ ๋ณ€๊ฒฝ์„ ์š”๊ตฌ๋˜์–ด ๋ณ€๊ฒฝ์ ๋“ค์„ ํ™•์ธํ•˜๊ณ  ์‰ฝ๊ฒŒ ๋†“์น  ์ˆ˜ ์žˆ๋‹ค.
  • ๊ฒฐํ•ฉ์ด ๊ฐ•ํ•˜๊ฒŒ ๋˜์–ด์žˆ์–ด ๊ฒฐํ•ฉ์ด ๋˜์–ด์žˆ์ง€ ์•Š์œผ๋ฉด ์‚ฌ์šฉ์„ ํ•  ์ˆ˜ ์—†๋‹ค.
  • new๋ฅผ ์„ ์–ธํ•  ๋•Œ ๋งˆ๋‹ค ์ปดํ“จํ„ฐ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋Š”๋ฐ ๋น„๊ต์ ์œผ๋กœ ๊ฐ•ํ•œ ๊ฒฐํ•ฉ์—์„œ new๋ฅผ ๋” ๋งŽ์ด ์‚ฌ์šฉํ•ด ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๋งŽ์ด ์žก์•„๋จน๊ฒŒ ๋œ๋‹ค.

์‹ค์Šต

// coupon.controller.js

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

export class CouponController {
  buyCoupon = (req, res) => {
    // 1. ๊ฐ€์ง„๋ˆ ๊ฒ€์ฆํ•˜๋Š” ์ฝ”๋“œ (10์ค„ => 2์ค„)
    const cashService = new CashService();
    const hasMoney = cashService.checkValue(); // true ๋˜๋Š” false ๋ฆฌํ„ด

    // 2. ์ฟ ํฐ ๊ตฌ๋งคํ•˜๋Š” ์ฝ”๋“œ
    if (hasMoney) {
      res.send("์ฟ ํฐ ๊ตฌ๋งค ์™„๋ฃŒ!!");
    }
  };
}
=> CouponController๊ฐ€ CashService์— ์˜์กดํ•˜๊ณ  ์žˆ์œผ๋ฏ€๋กœ Coupontrollerdhk CashService
๊ฐ€ ๊ฐ•ํ•˜๊ฒŒ ๊ฒฐํ•ฉ๋˜์–ด ์žˆ๋‹ค.

๐ŸคLoose-coupling & Dependency

๋Š์Šจํ•œ๊ฒฐํ•ฉ

: โ€œ๊ฐ์ฒด๋“ค ๊ฐ„์— ๊ฒฐํ•ฉ์ด ๋˜์–ด์žˆ๊ธด ํ•œ๋ฐ ํ—๊ฒ๊ฒŒ ๋๋‹ค.โ€๋กœ ํ•ด์„ํ•  ์ˆ˜ ์žˆ๋‹ค.

๋‹ค๋ฅธ ํด๋ž˜์Šค๋ฅผ ์ง์ ‘์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ํด๋ž˜์Šค์˜ ์˜์กด์„ฑ์„ ์ค„์ด์ž.

๋Š์Šจํ•œ ๊ฒฐํ•ฉ(Loose Coupling)์˜ ํŠน์ง•

  • class/class ๋ฅผ ๋Š์Šจํ•˜๊ฒŒ ๊ฒฐํ•ฉ๋˜์–ด ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ๊ฐœ๋ฐœํ•˜๊ฑฐ๋‚˜ ๊ธฐ์กด ๊ธฐ๋Šฅ์„ ์ˆ˜์ •ํ•˜๊ณ  ํ™•์žฅํ•˜๋Š”๊ฒŒ ์‰ฝ๋‹ค.
  • ์ฝ”๋“œ์˜ ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์‰ฝ๋‹ค.
  • ํ…Œ์ŠคํŠธ ๋Œ€์—ญ์œผ๋กœ ์น˜ํ™˜ํ•˜๊ธฐ๊ฐ€ ์‰ฌ์›Œ ์œ ๋‹› ํ…Œ์ŠคํŠธ๊ฐ€ ์šฉ์ด

์‹ค์Šต


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 ์„œ๋ฒ„๊ฐ€ ์ผœ์กŒ์–ด์š”!!!");
});

cashServicer ๋ฅผ ๋ฐ–์—์„œ ์‹คํ–‰ํ•ด ์ƒ์„ฑ์ž๋กœ ๋„ฃ์–ด์ฃผ์—ˆ๋‹ค. ์ฆ‰, ์‹ฑ๊ธ€ํ†ค ํŒจํ„ด์„ ์ ์šฉํ•˜์—ฌ

๋Š์Šจํ•œ ๊ฒฐํ•ฉ์œผ๋กœ ๋งŒ๋“ค์–ด ์ฃผ์—ˆ๋‹ค.

Singleton Pattern(์‹ฑ๊ธ€ํ†ค ํŒจํ„ด)

// 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("์ƒํ’ˆ์„ ํ™˜๋ถˆํ•ฉ๋‹ˆ๋‹ค.");
    }
  };
}
import express from 'express'
const app = express()

import { ProductController} from './mvc/controllers/product.controller.js'
import { CouponController } from './mvc/controllers/coupon.controller.js'
import { CashService } from './mvc/controllers/services/cash.service.js'
import { PointService } from './mvc/controllers/services/point.service.js'
import { ProductService } from './mvc/controllers/services/product.service.js'
//  ์˜์กด์„ฑ                                   // == ์˜์กด์„ฑ์ฃผ์ž…์œผ๋กœ ๋ฐœ์ƒํ•˜๋Š” ์žฅ์ !! ==
const cashService = new CashService()      // 1. new ํ•œ๋ฒˆ์œผ๋กœ ๋ชจ๋“  ๊ณณ์—์„œ ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅ(์‹ฑ๊ธ€ํ†คํŒจํ„ด)
const productService = new ProductService()// 2. ์˜์กด์„ฑ ์ฃผ์ž…์œผ๋กœ ํ•œ๊บผ๋ฒˆ์— ๋ณ€๊ฒฝ ๊ฐ€๋Šฅ
const pointService = new PointService()    // 3. ์˜์กด์„ฑ ์ฃผ์ž…์œผ๋กœ ์ฟ ํฐ ๊ตฌ๋งค ๋ฐฉ์‹์„ ํฌ์ธํŠธ๊ฒฐ์ œ๋กœ ์•ˆ์ „ํ•˜๊ฒŒ ๋ณ€๊ฒฝ๊ฐ€๋Šฅ

                                           // [๋ถ€๊ฐ€ ์„ค๋ช…]
                                           // 1. ProductController๊ฐ€ CashService์— ์˜์กดํ•˜๊ณ  ์žˆ์Œ.(CashService => ์˜์กด์„ฑ)
                                           // => ์ด ์ƒํ™ฉ์„ "๊ฐ•ํ•˜๊ฒŒ ๊ฒฐํ•ฉ๋˜์–ด ์žˆ๋‹ค" ๋ผ๊ณ  ํ‘œํ˜„
                                           // => tight-coupling

                                           // 2. ์ด๋ฅผ ๊ฐœ์„ ํ•˜๊ธฐ ์œ„ํ•ด์„œ "๋Š์Šจํ•œ ๊ฒฐํ•ฉ"์œผ๋กœ ๋ณ€๊ฒฝํ•  ํ•„์š”๊ฐ€ ์žˆ์Œ
                                           // => loose-coupling
                                           // => ์ด๋ฅผ "์˜์กด์„ฑ ์ฃผ์ž…"์œผ๋กœ ํ•ด๊ฒฐ(์˜์กด์„ฑ ์ฃผ์ž…:Dependency-Injection ===> DI:์•ฝ์ž )
                                           // => ์ด ์—ญํ• ์„ ๋Œ€์‹  ํ•ด์ฃผ๋Š” Nest.js ๊ธฐ๋Šฅ : IoC container (์ œ์–ด๋ฅผ ์—ญ์ „์‹œ์ผœ์ฃผ๋Š”) => ์•Œ์•„์„œ new ํ•ด์„œ ๋„ฃ์–ด์ฃผ๋Š”์• . ์ฆ‰ DI ํ•ด์คŒ
                                           //                                 => Inversion-Of-Control

                                           // 3. "์˜์กด์„ฑ์ฃผ์ž…"์œผ๋กœ "์‹ฑ๊ธ€ํ†คํŒจํ„ด" ๊ตฌํ˜„ ๊ฐ€๋Šฅํ•ด์ง
                                           // => โ“"์˜์กด์„ฑ ์ฃผ์ž…"์ด๋ฉด "์‹ฑ๊ธ€ํ†ค ํŒจํ„ด" ์ธ๊ฐ€..? ๊ทธ๊ฑด ์•„๋‹˜!!

// ์ƒํ’ˆ API
const productController = new ProductController(cashService, productService)
app.post('/products/buy', productController.buyProduct) // ์ƒํ’ˆ ๊ตฌ๋งคํ•˜๊ธฐ API
app.post("/products/refund", productController.refundProduct) // ์ƒํ’ˆ ํ™˜๋ถˆํ•˜๊ธฐ API

// ์ฟ ํฐ ์ƒํ’ˆ๊ถŒ API
const couponController = new CouponController(cashService, pointService)
app.post("/coupons/buy", couponController.buyCoupon) // ์ƒํ’ˆ๊ถŒ์„ ๋ˆ์ฃผ๊ณ  ๊ตฌ๋งคํ•˜๋Š” API

// ๊ฒŒ์‹œํŒ API
// app.get("/boards/...")

app.listen(3000)

๐Ÿ™Type-script

  • ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ํƒ€์ž…์„ ๊ฐ•์ œ์‹œํ‚ค๋Š” ์–ธ์–ด
    • ์—๋Ÿฌ์˜ ์‚ฌ์ „ ๋ฐฉ์ง€
    • ์ฝ”๋“œ ๊ฐ€์ด๋“œ ๋ฐ ์ž๋™ ์™„์„ฑ(๊ฐœ๋ฐœ ์ƒ์‚ฐ์„ฑ ํ–ฅ์ƒ)
function sumJs(a, b) {
  return a + b;
}

function sumTs(a: number, b: number) {
	return a + b;
}

sumJS(10, 20) // '1020'
sumTS(10, 20) // 30

์ด์ฒ˜๋Ÿผ ํƒ€์ž…์„ ์ง€์ •ํ•ด์ฃผ์ง€ ์•Š์œผ๋ฉด ์ˆซ์ž๊ฐ€ ์•„๋‹Œ ๋ฌธ์ž์—ด๋กœ ๋”ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ๋Š” 1020์ด๋ผ๋Š” ๋ฌธ์ž์—ด์„ ๋‚˜ํƒ€๋‚ด๊ฒŒ๋œ๋‹ค. ์‚ฌ์ „์— ํƒ€์ž… ์—๋Ÿฌ๋ฅผ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค.

let aaa : string = "์•ˆ๋…•ํ•˜์„ธ์š”"
let bbb : number = 123

interface IProfile {
    name : string;
    age: number;
}

let profile:IProfile = { name: "์ฒ ์ˆ˜", age: 15 }

๊ฐ์ฒด์—๋Š” interface ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํƒ€์ž…์„ ์ง์ ‘ ๋งŒ๋“ค์–ด์„œ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค

๋ฐฐ์—ด ํƒ€์ž… ์ง€์ •

let fff : number[] = [1,2,3,4,5]
fff = ['์ฒ ์ˆ˜', '์˜ํฌ', 'ํ›ˆ์ด' ] //  ๋ฌธ์ž ํƒ€์ž… ๋ถˆ๊ฐ€

let ggg: string[] = ['์ฒ ์ˆ˜', '์˜ํฌ', 'ํ›ˆ์ด']

let hhh: (number | string)[] = ['์ฒ ์ˆ˜', '์˜ํฌ', 'ํ›ˆ์ด', 10]
// ํƒ€์ž…์„ ์ถ”๋ก ํ•ด์„œ ์–ด๋–ค ํƒ€์ž…์„ ์‚ฌ์šฉํ•˜๋Š”์ง€ ์•Œ์•„๋ณด๊ธฐ

๊ฐ์ฒด ํƒ€์ž… ์ง€์ •

interface IProfile{
	name: string
	age: number | string
	school: string
	hobby? : string // ํ•„์ˆ˜์ ์œผ๋กœ ์กด์žฌํ•˜์ง€ ์•Š์•„๋„ ๋ ๋•Œ๋Š” ? ์‚ฌ์šฉํ•ด์„œ ์“ฐ๋Š”๊ฑด ๋‚ด๋ง˜๋Œ€๋กœ๋ผ๊ณ  ์ง€์ •
}
let profile: IProfile = {
    name: "์ฒ ์ˆ˜",
    age: 8,
    school: "๋‹ค๋žŒ์ฅ์ดˆ๋“ฑํ•™๊ต"
}
profile.age = "8์‚ด" // ๐Ÿšจ ๋ฌธ์ž ํƒ€์ž… ๋ถˆ๊ฐ€๋Šฅ!
profile.hobby = "์ˆ˜์˜" // ๐Ÿšจ ๊ธฐ์กด profile ๊ฐ์ฒด์—๋Š” hobby๊ฐ€ ์—†๊ธฐ์— ๋ฐ์ดํ„ฐ ์ถ”๊ฐ€ ๋ถˆ๊ฐ€๋Šฅ!

ํ•จ์ˆ˜ ํƒ€์ž… ์ง€์ •

// ํ•จ์ˆ˜ํƒ€์ž… 1
function add(num1: number, num1: number): number {   
    return num1 + num1
		// return "์•ˆ๋…•ํ•˜์„ธ์š”!!" // ๐Ÿšจ return ๊ฐ’์ด ๋ฌธ์ž ํƒ€์ž…์ด๊ธฐ์— ๋ถˆ๊ฐ€๋Šฅ!
}

const result = add(1000, 2000) 

// ํ•จ์ˆ˜ํƒ€์ž… 2
function add2(num1: number, num1: number, unit: string): string {   
		return num1 + num2 + unit
}

let result2 = add2(1000, 2000, "์›") // result์˜ ํƒ€์ž…์€ string์ด ๋˜๋Š”๊ฒƒ

ํ•จ์ˆ˜ ํƒ€์ž…์—์„œ๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜ ๋ฐ›๋Š” ์œ„์น˜์—์„œ ํƒ€์ž…์„ ์ง€์ •ํ•ด์ค˜์•ผํ•œ๋‹ค.

์‹คํ–‰๋„ ์ง€์ •ํ•ด์ค€ ํƒ€์ž…๊ณผ ๋™์ผํ•˜๊ฒŒ ์ž‘์„ฑํ•ด์„œ ์‹คํ–‰์‹œ์ผœ์ค˜์•ผํ•œ๋‹ค.

Decorator ์›๋ฆฌ ์‹ค์Šต

โ†’ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋Š” ์‹คํ–‰ํ•˜๋ ค๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ๊ตฌ์กฐ๋ฅผ ์ˆ˜์ •ํ•˜์ง€ ์•Š๊ณ  ๊ธฐ์กด ๊ฐ์ฒด์— ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๋””์ž์ธ ํŒจํ„ด

โ†’ ์ผ๋ฐ˜์ ์œผ๋กœ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐํ•˜๋ ค๋Š” ํ•จ์ˆ˜์˜ ์ •์˜์ „์— ํ˜ธ์ถœ๋œ๋‹ค. ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋Š” ํ•จ์ˆ˜๋ฅผ ์ธ์ˆ˜๋กœ ์–ป๊ณ  ๋Œ€๊ฐ€๋กœ ์ƒˆ๋กœ์šด ํ•จ์ˆ˜๋กœ ๋Œ๋ ค์ฃผ๋Š” cllable(์ „๋‹ฌ๋ฐ›์€ object์ธ์ž๊ฐ€ ํ˜ธ์ถœ ๊ฐ€๋Šฅํ•œ์ง€ ํŒ๋‹จ)๊ตฌ์กฐ์ด๋‹ค.

โ‡’ ํด๋ž˜์Šค,๋ฉ”์„œ๋“œ,์ ‘๊ทผ์ž,ํ”„๋กœํผํ‹ฐ,ํŒŒ๋ฆฌ๋ฏธํ„ฐ์— ์ ์šฉ๋ ์ˆ˜ ์žˆ๋”ฐ.

index.ts ํŒŒ์ผ์„ ์‹คํ–‰์‹œ์ผœ์ฃผ๊ธฐ ์ „์— decorator๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ TypeScript ํŒŒ์ผ ์„ค์ •์„ ๋จผ์ € ํ•ด์ฃผ๊ฒ ์Šต๋‹ˆ๋‹ค.

07-02-typescript-decorator ํด๋”๋กœ ํ„ฐ๋ฏธ๋„์„ ์ด๋™ํ•˜์—ฌ ์•„๋ž˜ ์ˆœ์„œ๋Œ€๋กœ ์ง„ํ–‰ํ•ด ์ฃผ์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

  1. **yarn init** ๋ช…๋ น์–ด๋ฅผ ์ž…๋ ฅํ•ด์ฃผ๊ณ , ๋ชจ๋“  ์งˆ๋ฌธ์— ์—”ํ„ฐ๋ฅผ ๋ˆŒ๋Ÿฌ ๋„˜์–ด๊ฐ‘๋‹ˆ๋‹ค.

    ์ด๋ฅผ ํ†ตํ•ด package.json ํŒŒ์ผ์ด ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.

{
  "name": "07-02-typescript-decorator",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT"
}
  1. yarn add typescript --dev๋ฅผ ์ž…๋ ฅํ•ด ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ ๋ชจ๋“ˆ์„ ์„ค์น˜ํ•ด์ฃผ์„ธ์š”.
{
  "name": "07-02-typescript-decorator",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "devDependencies": {
    "typescript": "^4.8.4"
  }
}
  1. **yarn add ts-node**๋ฅผ ์ž…๋ ฅํ•ด ts-node๋ฅผ ์„ค์น˜ํ•ด ์ฃผ์„ธ์š”.
{
  "name": "07-02-typescript-decorator",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "devDependencies": {
    "typescript": "^4.8.4"
  },
  "dependencies": {
    "ts-node": "^10.9.1"
  }
}

ts-node๋ฅผ ์„ค์น˜ํ•˜๊ฒŒ ๋˜๋ฉด ํƒ€์ž… ์Šคํฌ๋ฆฝํŠธ ํŒŒ์ผ์„ ์‹คํ–‰ํ•ด ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ ์ž์ฒด๋กœ๋Š” ์‹คํ–‰์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๊ธฐ์— ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋กœ ๋ณ€ํ™”ํ•˜์—ฌ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

  1. ์‹คํ–‰์‹œํ‚ค๋Š” ๋ช…๋ น์–ด๋ฅผ ์ถ”๊ฐ€ํ•ด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

    ์•„๋ž˜์™€ ๊ฐ™์ด scripts ๋ฅผ ์ถ”๊ฐ€ํ•ด์ฃผ์„ธ์š”.

{
  "name": "07-02-typescript-decorator",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "scripts": {
    "start:dev": "ts-node index.ts"
  },
  "devDependencies": {
    "typescript": "^4.8.4"
  },
  "dependencies": {
    "ts-node": "^10.9.1"
  }
}
  1. **yarn tsc --init** ๋ฅผ ์ž…๋ ฅํ•ด tsconfig.json ์ƒ์„ฑํ•ด์ฃผ์„ธ์š”.
// tsconfig.json

{
  "compilerOptions": {
    "target": "es2016",                                  
    "module": "commonjs",                               
    "esModuleInterop": true,                            
    "forceConsistentCasingInFileNames": true,           
    "strict": true,                                      
    "skipLibCheck": true,
    "experimentalDecorators": true,                  
    "noImplicitAny": false                               
  }
}
  • ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ์‚ฌ์šฉ์„ ์œ„ํ•ด "experimentalDecorators": true ๋ฅผ ์ถ”๊ฐ€ํ•ด ์ฃผ์„ธ์š”.
  • ์ถ”๊ฐ€๋กœ, any ํƒ€์ž…์— ๋Œ€ํ•œ Error ๋ฐœ์ƒ์„ ๋ฌด๋ ฅํ™” ์‹œํ‚ค๊ธฐ ์œ„ํ•ด์„œ "noImplicitAny": false ๋ฅผ ์ถ”๊ฐ€ํ•ด ์ฃผ์„ธ์š”.
  • tsconfig์˜ ์ปดํŒŒ์ผ๋Ÿฌ ์˜ต์…˜์— ๋Œ€ํ•ด์„œ ๋” ์•Œ๊ณ ์‹ถ๋‹ค๋ฉด typescipt Docs์—์„œ ๊ณต๋ถ€ํ•ด ๋ณด์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค๐Ÿ’ช.

$ yarn start:dev ๋ฅผ ์ž…๋ ฅํ•ด์„œ index.ts ํŒŒ์ผ์„ ์‹คํ–‰์‹œ์ผœ์ฃผ์„ธ์š”.

ProductController ํด๋ž˜์Šค ์œ„์— ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ Controller ๋ฅผ ์ž‘์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค. ProductController ํด๋ž˜์Šค๊ฐ€ ํ•จ์ˆ˜์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋ฐ›์•„์ ธ์„œ ํ•จ์ˆ˜ Controller ๋‚ด๋ถ€์—์„œ ์‚ฌ์šฉ๋จ์œผ๋กœ, Controller ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๊ฐ€ ์‚ฌ์‹ค์€ ํ•จ์ˆ˜์˜€๋‹ค๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

profile
๊ฐ„์ ˆํ•˜๊ณ  ์น˜์—ดํ•˜๊ฒŒ ์‚ด์ž
post-custom-banner

0๊ฐœ์˜ ๋Œ“๊ธ€