๐Ÿ‘จโ€๐Ÿ’ป ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ฝ”๋”ฉ ์ปจ๋ฒค์…˜๊ณผ ํ…Œ์ŠคํŠธ - OOP Study 1

oopstudy1

4์›”๋ถ€ํ„ฐ ์Šคํ„ฐ๋””๋ฅผ ์‹œ์ž‘ํ–ˆ๋‹ค. ์Šคํ„ฐ๋””๋Š” java ์–ธ์–ด๋ฅผ ์‚ฌ์šฉํ•˜์ง€๋งŒ ๋‚˜๋Š” javascript๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์ฐธ์—ฌํ•˜๊ณ  ์žˆ๋‹ค..!๐Ÿ˜‚ ์‹ค์ œ ์ฝ”๋“œ์— ๋Œ€ํ•œ ํ”ผ๋“œ๋ฐฑ์€ ๋งŽ์ด ๋ฐ›์ง€ ๋ชปํ•ด์„œ ์•„์‰ฝ์ง€๋งŒ java์™€ javascript ๊ฐ๊ฐ์˜ ์–ธ์–ด์˜ ๊ฐœ๋ฐœ์ฒ ํ•™๋„ ๋น„๊ตํ•ด๋ณผ ์ˆ˜๋„ ์žˆ๊ณ  ๋ฌด์—‡๋ณด๋‹ค ์–ธ์–ด์— ๊ตญํ•œ๋˜์ง€ ์•Š๋Š” ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๊ธฐ๋ณธ ์›์น™๋“ค, ์ฝ”๋“œ ์งœ๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด์„œ ๋งŽ์ด ์ƒ๊ฐํ•ด๋ณผ ์ˆ˜ ์žˆ๋Š” ์ข‹์€ ์‹œ๊ฐ„์ด ๋  ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•œ๋‹ค. ๋งค์ฃผ ์•Œ๊ฒŒ๋œ ๋‚ด์šฉ์ด๋‚˜ ์ •๋ฆฌํ• ๋งŒ ํ•œ ๋‚ด์šฉ์„ ๊ธฐ๋กํ•˜๋ คํ•œ๋‹ค.


#. Series

์‹œ๋ฆฌ์ฆˆ ํ•œ๋ˆˆ์—๋ณด๊ธฐ[์ ‘๊ธฐ/ํŽผ์น˜๊ธฐ]

##. Source

๊นƒํ—ˆ๋ธŒ ์†Œ์Šค[์ ‘๊ธฐ/ํŽผ์น˜๊ธฐ]

1. ๋งค์ง๋„˜๋ฒ„ ์ƒ์ˆ˜ํ™”

๋งค์ง๋„˜๋ฒ„๋Š” ์„ค๋ช… ์—†์ด ๋ฌด์ž‘์ • ๋“ฑ์žฅํ•˜๋Š” ์ƒ์ˆ˜๋ฅผ ์˜๋ฏธํ•œ๋‹ค.

if๊ฐ™์€ ์ œ์–ด๋ฌธ์ด๋‚˜ for๊ฐ™์€ ๋ฐ˜๋ณต๋ฌธ์—์„œ ๋งŽ์ด ๋“ฑ์žฅํ•˜๋ฉฐ, ๋งค์ง๋„˜๋ฒ„๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•  ๋•Œ ์ผ์ผ์ด ๋‹ค ์ˆ˜์ •ํ•ด์•ผํ•œ๋‹ค๋Š” ๋ฒˆ๊ฑฐ๋กœ์›€ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์ฝ”๋“œ๋ฅผ ๋ณด๊ณ  ์ดํ•ดํ•˜๋Š”๋ฐ ํฐ ์–ด๋ ค์›€์„ ์ค€๋‹ค. ๊ทธ๋ž˜์„œ ์ด๋Ÿฌํ•œ ๋งค์ง๋„˜๋ฒ„๋Š” const ํ‚ค์›Œ๋“œ๋ฅผ ํ†ตํ•ด ํ•จ์ˆ˜ ์ƒ๋‹จ์— ์ƒ์ˆ˜ ๋ณ€์ˆ˜์— ๋„ฃ์–ด์ค€ ํ›„, ์‚ฌ์šฉํ•ด์ฃผ๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

์•„๋ž˜ ์ฝ”๋“œ๋Š” ์ˆซ์ž์•ผ๊ตฌ ๋žœ๋ค์ˆซ์ž๋ฅผ ๋ฌธ์ž์—ด์— ๋‹ด๋Š” ํ•จ์ˆ˜์ธ๋ฐ ๋ฐ˜๋ณต๋ฌธ ๋‚ด๋ถ€์— ๋งค์ง๋„˜๋ฒ„ 3์„ ์‚ฌ์šฉํ–ˆ๋‹ค.

bad..!

const chooseRandomNumber = () => {
  const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]
  answerNum = ''
  for (let i = 0; i < 3; i++) {
    const randomNumber = Math.floor(Math.random() * (9 - i))
    const chosenNumber = numbers.splice(randomNumber, 1)[0]
    const chosen = String(chosenNumber)
    answerNum += chosen
  }
  return answerNum
}

BASEBALLNUMBERLENGTH ๋ผ๋Š” ๋ณ€์ˆ˜์— 3์„ ์ดˆ๊ธฐํ™”ํ•ด์คŒ์œผ๋กœ์จ, ๋งค์ง๋„˜๋ฒ„๋ฅผ ์—†์• ์ฃผ์—ˆ๋‹ค.

good!๐Ÿ‘

const chooseRandomNumber = () => {
  const BASEBALL_NUMBER_LENGTH = 3
  const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]
  answerNum = ''
  for (let i = 0; i < BASEBALL_NUMBER_LENGTH; i++) {
    const randomNumber = Math.floor(Math.random() * (9 - i))
    const chosenNumber = numbers.splice(randomNumber, 1)[0]
    const chosen = String(chosenNumber)
    answerNum += chosen
  }
  return answerNum
}

2. ๋ณ€์ˆ˜ ๋„ค์ด๋ฐ ๊ทœ์น™

๋จผ์ € ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ๋Š” ๋ณ€์ˆ˜๋ช… ์ฒซ๊ธ€์ž์— ๊ธ€์ž ํ˜น์€ _, $๋งŒ ์˜ฌ ์ˆ˜ ์žˆ๋‹ค. ๊ทธ ์ด์™ธ์˜ ์ˆซ์ž๋‚˜ ๋‹ค๋ฅธ ํŠน์ˆ˜๋ฌธ์ž๋Š” ์—๋Ÿฌ๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค.

const 1num; // x
const num1 // o

const _name; // o
const $name; // o

์ง€์—ญ๋ณ€์ˆ˜๋‚˜ private ๋ณ€์ˆ˜์˜ ๊ฒฝ์šฐ์—๋Š” _๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

let _privateVariableName
let _privateFunctionName

๊ทธ๋ฆฌ๊ณ  ์˜ˆ์•ฝ์–ด๋Š” ๋ณ€์ˆ˜๋ช…์œผ๋กœ ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค. ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์—๋Ÿฌ๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค. MDN ์˜ˆ์•ฝ์–ด ๋ชจ์Œ

const true; // x
const case; // x
const break; // x
// ...

๊ทธ๋ฆฌ๊ณ  ๋ณ€์ˆ˜๋ช…์€ ์ผ๋ฐ˜์ ์œผ๋กœ ์นด๋ฉœ์ผ€์ด์Šค์™€ ์Šค๋„ค์ดํฌ์ผ€์ด์Šค๋ฅผ ํ˜ผ์šฉํ•ด์„œ ์ž‘์„ฑํ•œ๋‹ค.

์นด๋ฉœ์ผ€์ด์Šค๋Š” ์—ฌ๋Ÿฌ ๋‹จ์–ด๊ฐ€ ๋“ค์–ด๊ฐ€๋Š” ๋ณ€์ˆ˜๋ช…์ผ ๊ฒฝ์šฐ, ์ฒซ๋‹จ์–ด์˜ ์ฒซ๊ธ€์ž๋Š” ์†Œ๋ฌธ์ž๋กœ, ๋‘๋ฒˆ์งธ๋ถ€ํ„ฐ์˜ ์ฒซ๊ธ€์ž๋Š” ๋Œ€๋ฌธ์ž๋กœ ์ž‘์„ฑํ•˜๋Š” ํ‘œ๊ธฐ๋ฒ•์ด๋‹ค.

let myname = 'taeeun' // bad
let myName = 'taeeun' // good

์Šค๋„ค์ดํฌ์ผ€์ด์Šค๋Š” ์—ฌ๋Ÿฌ ๋‹จ์–ด๊ฐ€ ๋“ค์–ด๊ฐ€๋Š” ๋ณ€์ˆ˜๋ช…์ผ ๊ฒฝ์šฐ, _๋ฅผ ํ†ตํ•ด ๋„์–ด์„œ ํ‘œ๊ธฐํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

const MAXLENGTH = 10 // bad
const MAX_LENGTH = 10 // good

๋ณดํ†ต ์ƒ์ˆ˜์— ์Šค๋„ค์ดํฌ์ผ€์ด์Šค๋ฅผ, ์ผ๋ฐ˜์ ์ธ ๋ณ€์ˆ˜์—๋Š” ์นด๋ฉœ์ผ€์ด์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ ๊ฐ™๋‹ค.

3. ๋ณ€์ˆ˜์— ํƒ€์ž…์ด๋‚˜ ์ž๋ฃŒ๊ตฌ์กฐํ˜• ๋ช…์‹œํ•˜์ง€ ์•Š๊ธฐ

๋ณ€์ˆ˜๋ฅผ ๋„ค์ด๋ฐํ•  ๋•Œ๋Š” ๊ตณ์ด ํƒ€์ž…์ด๋‚˜ ์ž๋ฃŒ๊ตฌ์กฐํ˜•์„ ๋ช…์‹œํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

๊ทธ ์ด์œ ๋Š” ํ•ด๋‹น ๋ณ€์ˆ˜์˜ ํƒ€์ž…์ด๋‚˜ ์ž๋ฃŒ๊ตฌ์กฐํ˜•์„ ๋ฐ”๊ฟ€ ๊ฒฝ์šฐ, ๋ชจ๋“  ๋ณ€์ˆ˜์ด๋ฆ„์„ ๋ฐ”๊ฟ”์ค˜์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๋ณ€์ˆ˜ ๋„ค์ด๋ฐ์€ ๊ทธ ๋ณ€์ˆ˜์˜ ํ˜•์‹๋ณด๋‹ค๋Š” ํ• ๋‹น๋œ ๊ฐ’์˜ ์˜๋ฏธ๋ฅผ ๋“œ๋Ÿฌ๋‚ด๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

ํ•จ์ˆ˜์˜ ๊ฒฝ์šฐ

// bad
const compareTwoArray = (numbers1, numbers2) => {}
// good!
const compareNumbers = (numbers1, numbers2) => {}

๋ฐฐ์—ด์˜ ๊ฒฝ์šฐ

const numberArr = [1, 2, 3, 4]
const numbers = [1, 2, 3, 4]

4. ์ค‘๋ณต๋œ ๊ธฐ๋Šฅ ํ”ผํ•˜๊ธฐ

์ค‘๋ณต๋œ ๊ธฐ๋Šฅ์€ ์ตœ๋Œ€ํ•œ ํ”ผํ•˜๊ณ  ๊ฐ€๋Šฅํ•œ ์ฃผ์–ด์ง„ field๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

ํ•ด๋‹น ์ฝ”๋“œ๋Š” ์ž๋™์ฐจ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•œ ์ˆซ์ž๋งŒํผ ๋žœ๋ค์œผ๋กœ ๊ฐ๊ฐ์˜ ์ž๋™์ฐจ๋ฅผ ์ด๋™์‹œ์ผœ ๊ฐ€์žฅ ๋ฉ€๋ฆฌ๊ฐ„ ์ž๋™์ฐจ๋ฅผ ์ถœ๋ ฅํ•˜๋Š” ํ”„๋กœ๊ทธ๋žจ์ด๋ฉฐ,

์ฒ˜์Œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ๋•Œ, ๋‚˜๋Š” ๊ธฐ์กด์— ์ž๋™์ฐจ ๊ฐ์ฒด car ๋‚ด๋ถ€ position ๊ฐ’์ด ์žˆ์œผ๋ฉด์„œ๋„ ์ž๋™์ฐจ์˜ ์ด๋™ํ•œ ๊ฑฐ๋ฆฌ๋ฅผ ์ „์—ญ์— carDistances ๋ฐฐ์—ด์— ๋”ฐ๋กœ ์ €์žฅํ–ˆ์—ˆ๋‹ค.

bad..!

class Car {
  name
  position = 0

  constructor(name) {
    this.name = name
  }
  go() {
    this.position = this.position + 1
  }
}
const carDistances = [] // ๊ฐ๊ฐ์˜ ์ž๋™์ฐจ ์ด๋™๊ฑฐ๋ฆฌ
moveCar(car, carNames, carDistances) // ์ž๋™์ฐจ๋ฅผ ์ด๋™์‹œํ‚ค๊ณ  carDistances ๊ฐ’ ๋ณ€๊ฒฝ
// getWinner ํ•จ์ˆ˜์—์„œ๋„ ๋ถˆํ•„์š”ํ•˜๊ฒŒ carDistances ๋ฐฐ์—ด์„ ๋ฐ›์•„์•ผํ•œ๋‹ค.
const getWinner = (carNames, carDistances) => {
  const max = Math.max(...carDistances)
  let winner = ''

  for (let i = 0; i < carNames.length; i++) {
    if (max === carDistances[i]) winner += `${carNames[i]},`
  }
  return winner
}

ํ•˜์ง€๋งŒ ๋ฐฐ์—ด ๋Œ€์‹  car.position ์„ ์‚ฌ์šฉํ•˜๋ฉด ์ฝ”๋“œ๋„ ๊น”๋”ํ•ด์ง€๊ณ  ๋ถˆํ•„์š”ํ•œ ๋ฉ”๋ชจ๋ฆฌ ๋‚ญ๋น„๋ฅผ ๋ง‰์„ ์ˆ˜ ์žˆ๋‹ค.

good ๐Ÿ‘

moveCar(car) // moceCar ํ•จ์ˆ˜๋Š” car๊ฐ์ฒด์˜ position๋งŒ ์˜ฌ๋ ค์ฃผ๋Š” ์—ญํ• ๋งŒ ์ˆ˜ํ–‰!
// getWinner ํ•จ์ˆ˜๋Š” car๊ฐ์ฒด๋“ค์ด ๋“ค์–ด์žˆ๋Š” cars ๋ฐฐ์—ด๋งŒ ๋ฐ›๊ณ  position ๋น„๊ต๋งŒ ํ•ด์ฃผ๋Š” ์—ญํ• ๋งŒ ์ˆ˜ํ–‰!
const getWinner = cars => {
  let max = 0
  cars.map(car => {
    if (car.position > max) max = car.position
  })
  let winner = []

  cars.map(car => {
    if (max === car.position) winner.push(car.name)
  })

  return winner.join()
}

์“ธ๋ฐ์—†๋Š” ์ค‘๋ณต์€ ๊ผญ ํ”ผํ•˜๊ณ  ๊ฐ๊ฐ์˜ ํ•จ์ˆ˜๋Š” ์ •๋ง ์ž๊ธฐ์˜ ๊ธฐ๋Šฅ๋งŒ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ์งœ๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

5. ๊ฐ๊ฐ์˜ ํ•จ์ˆ˜๋Š” ์ž๊ธฐ ๊ธฐ๋Šฅ๋งŒ ์ˆ˜ํ–‰ํ•˜๊ธฐ

์Šคํ„ฐ๋”” ๋ฏธ์…˜ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์š”๊ตฌ์‚ฌํ•ญ์—์„œ๋Š” ํ•ญ์ƒ ์ด๋Ÿฌํ•œ ์กฐ๊ฑด์ด ๋“ค์–ด์žˆ์—ˆ๋‹ค.

์กฐ๊ฑด
1 ์ตœ๋Œ€ํ•œ indent(์ธ๋ดํŠธ, ๋“ค์—ฌ์“ฐ๊ธฐ) depth๋ฅผ 2์ด์ƒ ์“ฐ์ง€ ์•Š์•„์•ผํ•จ
2๏ธ ํ•จ์ˆ˜ (๋˜๋Š” ๋ฉ”์†Œ๋“œ)์˜ ๊ธธ์ด๊ฐ€ 10๋ผ์ธ์„ ๋„˜์–ด๊ฐ€์ง€ ์•Š๋„๋ก ๊ตฌํ˜„

์ด๋Š” ํ•จ์ˆ˜๋ฅผ ์ตœ๋Œ€ํ•œ ์ž๊ธฐ ๊ธฐ๋Šฅ๋งŒ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ชผ๊ฐœ๋Š” ๊ฒƒ์„ ์š”๊ตฌํ•œ๋‹ค. ํ•จ์ˆ˜๋ฅผ ์ชผ๊ฐœ๋ฏ€๋กœ์„œ, ๊ฐ€๋…์„ฑ๊ณผ ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์ข‹์•„์ง€๋ฉฐ, ์•ˆ์ •์„ฑ์€ ์˜ฌ๋ผ๊ฐ„๋‹ค.

OO makes code understandable by encapsulating moving parts. FP makes code understandable by minimizing moving parts. -Michael Feathers

๊ฐ์ฒด์ง€ํ–ฅ์€ ๋™์ž‘ํ•˜๋Š” ๋ถ€๋ถ„์„ ์บก์Šํ™”ํ•ด์„œ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๊ณ , ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์€ ๋™์ž‘ํ•˜๋Š” ๋ถ€๋ถ„์„ ์ตœ์†Œํ™”ํ•ด์„œ ์ฝ”๋“œ ์ดํ•ด๋ฅผ ๋•๋Š”๋‹ค. - ๋งˆ์ดํด ํŽ˜๋”์Šค

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

6. ๋ฐ˜๋ณต๋ฌธ ๋Š์–ด์ฃผ๊ธฐ (break, return)

๋‹ค์Œ ํ•จ์ˆ˜๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•œ ์ž๋™์ฐจ์ด๋ฆ„์ด 5๊ธ€์ž ์ดˆ๊ณผ์ธ์ง€ ๊ฒ€์‚ฌํ•˜๋Š” ํ•จ์ˆ˜์ด๋‹ค.

ํ•ด๋‹น ํ•จ์ˆ˜๋Š” ์ž…๋ ฅํ•œ ๊ฐ’์˜ ๊ธธ์ด๋งŒํผ ๋ฐ˜๋ณต๋ฌธ์„ ๋Œ๋ฉด์„œ ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋ฉด errorCheck ๋ณ€์ˆ˜๋ฅผ ๋ฐ”๊พธ๋„๋ก ์งœ์„œ ์ค‘๊ฐ„์— ์กฐ๊ฑด์ด ๋งŒ์กฑํ•˜์—ฌ๋„ ๋ถˆํ•„์š”ํ•˜๊ฒŒ ๋ชจ๋“  ๋ฐ˜๋ณต๋ฌธ์„ ์ˆ˜ํ–‰ํ–ˆ๋‹ค.

badโ€ฆ!

const checkCarsNameLength = carNames => {
  const MAX_CARNAME_LENGTH = 5
  let errorCheck = true

  for (let i = 0; i < carNames.length; i++) {
    if (carNames[i].length > MAX_CARNAME_LENGTH) errorCheck = false
  }
  // ์ด๋ฆ„์ด 5์ดˆ๊ณผ์ธ ๊ฒƒ์ด ์žˆ์œผ๋ฉด false๋ฅผ, ์—†์œผ๋ฉด true๋ฅผ ๋ฆฌํ„ด.
  return errorCheck
}

ํ•˜์ง€๋งŒ ์กฐ๊ฑด์„ ๋งŒ์กฑํ–ˆ์„ ๋•Œ ๋ฐ”๋กœ ๊ฐ’์„ return ํ•˜๋„๋ก ๋ฐ”๊ฟจ๋”๋‹ˆ ๋ณ€์ˆ˜๋ฅผ ์“ฐ์ง€์•Š์•„๋„ ๋˜๊ณ , ์กฐ๊ฑด ๋งŒ์กฑ์‹œ, ๋ฐ˜๋ณต๋ฌธ๋„ ์ „๋ถ€ ํƒ์ƒ‰ํ•˜์ง€ ์•Š์•„๋„ ๋˜์—ˆ๋‹ค.

good!!๐Ÿ‘

const checkCarsNameLength = carNames => {
  const MAX_CARNAME_LENGTH = 5
  for (let i = 0; i < carNames.length; i++) {
    if (carNames[i].length > MAX_CARNAME_LENGTH) return false
  }
  return true
}

์ด๋ ‡๊ฒŒ ๋ถˆํ•„์š”ํ•œ ๋ณ€์ˆ˜๋ฅผ ์ค„์ด๊ณ , return ๊ณผ break ๋กœ ๊ฐ€๋Šฅํ•˜๋ฉด ๋ฐ˜๋ณต๋ฌธ์„ ๋น ๋ฅด๊ฒŒ ๋น ์ ธ๋‚˜์˜ฌ ์ˆ˜ ์žˆ๋„๋ก ์งœ๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

7. ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ ์‚ฌ์šฉํ•˜๊ธฐ

java ์Šคํ„ฐ๋””์—ฌ์„œ ์ฃผ์–ด์ง„ ๋ฏธ์…˜์€ ๊ฐ์ฒด์ง€ํ–ฅ์ ์ธ class Type์„ ์ฃผ๋กœ ์‚ฌ์šฉํ–ˆ๋‹ค. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—๋„ class ๋ฌธ๋ฒ•์ด ์žˆ์–ด์„œ ์ฝ”๋”ฉ์€ ๊ฐ€๋Šฅํ–ˆ์ง€๋งŒ, ํƒ€์ž…์ด ์ง€์ •๋˜์–ด์žˆ์ง€ ์•Š์•„์„œ ์ฝ”๋“œ๋ฅผ ์งœ๋ฉด์„œ ํ˜„์žฌ ๋ณ€์ˆ˜๊ฐ€ ์–ด๋–ค ํƒ€์ž…์ธ์ง€๊ฐ€ ๋งค์šฐ ํ—ท๊ฐˆ๋ ธ๋‹ค.

Car๊ฐ์ฒด ๋ฐฐ์—ด์„ ์ธ์ž๋กœ ๋ฐ›๋Š” ํ•จ์ˆ˜์˜ ๊ฒฝ์šฐ

// javascript : ๋ฐฐ์—ด์ธ๋ฐ, ๋‚ด๋ถ€ ์š”์†Œ๋“ค์˜ ํƒ€์ž…์ด ๋ถˆ๋ช…ํ™•ํ•จ
makeCars(cars, carNames)
// typescript : ๋ฐฐ์—ด ๋‚ด๋ถ€ ํƒ€์ž… ๋ช…์‹œ๋กœ ์—๋Ÿฌ๋ฐฉ์ง€ + ํ—ท๊ฐˆ๋ฆผ๋ฐฉ์ง€!
makeCars(cars: Car[], carNames: string[])

๋‹ค์Œ ์ฝ”๋“œ๋Š” ๋กœ๋˜๋ฅผ ๊ตฌ๋งคํ•˜๊ณ  ๋‹น์ฒจ๋กœ๋˜์™€ ๋น„๊ตํ•˜๋Š” ํ”„๋กœ๊ทธ๋žจ์ด๋ฉฐ, ๋กœ๋˜ ํ•œ์žฅ์„ ์˜๋ฏธํ•˜๋Š” Lotto ํƒ€์ž…๊ณผ ์‹ค์ œ ๋‹น์ฒจ๋กœ๋˜๋ฅผ ์˜๋ฏธํ•˜๋Š” WinningLotto ํƒ€์ž…์ด ๋”ฐ๋กœ ์ •์˜๋˜์–ด์žˆ์–ด ๋”์šฑ ํ—ท๊ฐˆ๋ ธ๋‹ค.

/**
 * ๋กœ๋˜ ํ•œ์žฅ์„ ์˜๋ฏธํ•˜๋Š” ๊ฐ์ฒด
 */
class Lotto {
  numbers = []

  constructor(numbers) {
    this.numbers = numbers
  }
}
/**
 * ๋‹น์ฒจ ๋ฒˆํ˜ธ๋ฅผ ๋‹ด๋‹นํ•˜๋Š” ๊ฐ์ฒด
 */
class WinningLotto {
  lotto = null
  bonusNo = 0

  constructor(lotto, bonusNo) {
    this.lotto = lotto
    this.bonusNo = bonusNo
  }

  match(userLotto) {
    let count = 0
    let bonusCount = 0
    this.lotto.numbers.map(number => {
      userLotto.numbers.indexOf(number) >= 0 && count++
    })
    userLotto.numbers.indexOf(this.bonusNo) >= 0 && bonusCount++
    if (count === 6) return 'FIRST'
    if (count === 5 && bonusCount) return 'SECOND'
    if (count + bonusCount === 5) return 'THIRD'
    if (count + bonusCount === 4) return 'FOURTH'
    if (count + bonusCount === 3) return 'FIFTH'
    return 'MISS'
  }
}
// javascript : ํ•จ์ˆ˜์˜ ์ธ์ž๋กœ ๋“ค์–ด๊ฐ€๋Š” ๋ณ€์ˆ˜๋ช…๋“ค์ด ๋งค์šฐ ํ—ท๊ฐˆ๋ฆผ!!
matchLottos(myLottos, winningLotto)
// typescript : ๋‚ด๋ถ€ ํƒ€์ž… ๋ช…์‹œ๋กœ ์—๋Ÿฌ๋ฐฉ์ง€ + ํ—ท๊ฐˆ๋ฆผ๋ฐฉ์ง€!
matchLottos(myLottos: Lotto[], winningLotto: WinningLotto): void

์•„์ง ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๋Š” ์ต์ˆ™์น˜ ์•Š์ง€๋งŒ, ์ด ๊ธฐํšŒ์— ๊ฐ™์ด ํ•™์Šตํ•˜๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™๋‹ค.

8. ํ…Œ์ŠคํŠธ์ฝ”๋“œ ์ž‘์„ฑํ•˜๊ธฐ

2020๋…„ 4์›” 18์ผ, ์ž ์‹ค ์˜คํ”„๋ผ์ธ ์Šคํ„ฐ๋””์—์„œ ํ…Œ์ŠคํŠธ ์— ๋Œ€ํ•ด์„œ ๋ฐฐ์› ๋‹ค.

์Šคํ„ฐ๋””์—์„œ๋Š” java ํ…Œ์ŠคํŒ… ํ”„๋ ˆ์ž„์›Œํฌ JUnit ๋ฅผ ์‚ฌ์šฉํ–ˆ๋Š”๋ฐ, ๋‚˜๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์ด๊ธฐ ๋•Œ๋ฌธ์— jest๋ผ๋Š” ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์„ ํƒํ•ด์„œ ํ•œ๋ฒˆ ํ…Œ์ŠคํŠธ ํ•ด๋ณด์•˜๋‹ค.

์‚ฌ์šฉ๋ฐฉ์‹์€ ๋น„์Šทํ–ˆ๋‹ค.

๋จผ์ € jest ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์„ค์น˜ํ•˜๊ณ ,

npm i -D jest

package.json ํŒŒ์ผ์˜ script์— jest ๋ช…๋ น์–ด๋ฅผ ์ถ”๊ฐ€์‹œ์ผœ์ฃผ๋ฉด ๋œ๋‹ค. ์‹คํ–‰์‹œ : npm run test

  "scripts": {
    "test": "jest"
  }

๊ทธ๋ฆฌ๊ณ  test ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ๋งŒ๋“ค์–ด ํ•ด๋‹น ํ…Œ์ŠคํŒ… ํŒŒ์ผ.js ์„ ์ƒ์„ฑํ•ด์ฃผ๋ฉด ๋˜์—ˆ๋‹ค.

// calculatorTest.js
class Calculator {
  add(i, j) {
    return i + j
  }
  subtract(i, j) {
    return i - j
  }
  multiple(i, j) {
    return i * j
  }
  divide(i, j) {
    return i / j
  }
}

test('๋ง์…ˆ', () => {
  let calculator = new Calculator()
  expect(calculator.add(1, 2)).toBe(3)
})

test('๋บ„์…ˆ', () => {
  let calculator = new Calculator()
  expect(calculator.subtract(1, 2)).toBe(-1)
})

test('๊ณฑ์…ˆ', () => {
  let calculator = new Calculator()
  expect(calculator.multiple(1, 2)).toBe(2)
})

test('๋‚˜๋ˆ—์…ˆ', () => {
  let calculator = new Calculator()
  expect(calculator.divide(2, 1)).toBe(2)
})

jest API์˜ test๋ผ๋Š” ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉํ–ˆ๋Š”๋ฐ, jest API ๋ฉ”์†Œ๋“œ๋„ ๋‹ค์–‘ํ•˜๊ฒŒ ์žˆ๋Š” ๊ฒƒ ๊ฐ™๋‹ค. ์‹œ๊ฐ„๋‚  ๋•Œ jest ๊ณต์‹๋ฌธ์„œ๋ฅผ ํ•œ๋ฒˆ ์ญ‰ ๋ณผ ๊ฒƒ.

test("ํ…Œ์ŠคํŠธ ์ด๋ฆ„", function, timeout)

9. ํ…Œ์ŠคํŠธ์ฝ”๋“œ ์ž‘์„ฑ๊ทœ์น™ & ํŒ

1๏ธโƒฃ ํ…Œ์ŠคํŠธ ์ด๋ฆ„์€ ํ•œ๊ธ€๋กœ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค. ์œ„์˜ ํ…Œ์ŠคํŠธ๋Š” ๋งค์šฐ ๊ฐ„๋‹จํ•˜์ง€๋งŒ ํ”„๋กœ๊ทธ๋žจ์ด ๋ณต์žกํ•ด์ง€๋ฉด ํ…Œ์ŠคํŠธ๋ช…๋„ ๊ธธ์–ด์งˆ ๊ฒƒ์ด๊ณ  ๊ฐ๊ฐ ํ…Œ์ŠคํŠธ๋งˆ๋‹ค ์ดํ•ดํ•˜๊ธฐ ์‰ฝ๊ณ  ์˜๋ฏธ๋ฅผ ์ž˜ ์ „๋‹ฌํ•ด์ฃผ์–ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

2๏ธโƒฃ ํ…Œ์ŠคํŠธ๋Š” ๊ฐ€์žฅ ์ž‘์€ ๋‹จ์œ„์˜ ๊ธฐ๋Šฅ๋ถ€ํ„ฐ ํ…Œ์ŠคํŠธํ•œ๋‹ค. ์˜ˆ๋ฅผ๋“ค์–ด, A,B๊ฐ€ C๋ผ๋Š” ๊ธฐ๋Šฅ์— ์˜์กด๋  ๊ฒฝ์šฐ, A,B๋ฅผ ํ…Œ์ŠคํŠธํ•˜๊ณ  ๊ฒ€์ฆ์ด ์™„๋ฃŒ๋˜๋ฉด C์—์„œ A,B๊ฐ€ ํฌํ•จ๋˜์ง€ ์•Š์€ ๊ธฐ๋Šฅ๋งŒ ํ…Œ์ŠคํŠธํ•˜๋ฉด ๋œ๋‹ค.

3๏ธโƒฃ ํ•˜๋‚˜์˜ ํ…Œ์ŠคํŠธ๋Š” ๋…๋ฆฝ์ ์ด์–ด์•ผ ํ•œ๋‹ค. ํ…Œ์ŠคํŠธ๋ผ๋ฆฌ ์˜์กดํ•ด์„œ๋Š” ์•ˆ๋œ๋‹ค.

10. ์ฐธ๊ณ 

https://ui.toast.com/fe-guide/ko_CODING-CONVENSION/#promise-executor-%ED%95%A8%EC%88%98

https://rinae.dev/posts/functional-js-tutorial

https://velog.io/@nakta/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EB%A1%9C-%EC%A0%91%ED%95%B4%EB%B3%B4%EB%8A%94-%ED%95%A8%EC%88%98%ED%98%95-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D-

https://futurecreator.github.io/2018/10/05/why-functional-programming/

https://developer.mozilla.org/ko/docs/Web/JavaScript/IntroductiontoObject-Oriented_JavaScript

https://developer.mozilla.org/ko/docs/Are-introductionto_JavaScript

https://www.zerocho.com/category/JavaScript/post/576cafb45eb04d4c1aa35078

https://meetup.toast.com/posts/90

11. ๋งˆ์น˜๋ฉฐ.

์ข‹์€ ๊ธฐํšŒ๊ฐ€ ์žˆ์–ด์„œ OOP ์Šคํ„ฐ๋””๋ฅผ ํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค. ๋น„๋ก java ์Šคํ„ฐ๋””์ง€๋งŒ ์Šคํ„ฐ๋””๋ฅผ ํ•˜๋ฉด์„œ ๋งŽ์€ ๊ฒƒ๋“ค์„ ๋ฐฐ์šฐ๋Š” ๊ฒƒ ๊ฐ™๋‹ค. ํ‰์†Œ์— ๊ธฐ๋Šฅ๊ตฌํ˜„ ์œ„์ฃผ์˜ ๊ณต๋ถ€๋ฅผ ํ–ˆ๋‹ค๋ฉด ์ด๋ฒˆ ์Šคํ„ฐ๋””๋ฅผ ํ†ตํ•ด์„œ๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด์„œ ๋งŽ์ด ์ƒ๊ฐํ•ด๋ณผ ์ˆ˜ ์žˆ์–ด์„œ ์ข‹์•˜๋‹ค. ํ˜„์žฌ๋Š” ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž‘์„ฑ์— ๊ด€ํ•œ ๋ฏธ์…˜์„ ์ง„ํ–‰ ์ค‘์— ์žˆ๋Š”๋ฐ ์•ž์œผ๋กœ ๋” ์—ด์‹ฌํžˆ ์ž„ํ•ด์•ผ๊ฒ ๋‹ค!!


Written by@taenyKim
์›น ํ”„๋ก ํŠธ์—”๋“œ ๊ณต๋ถ€ ๋ธ”๋กœ๊ทธ / Learn in Public

GitHubFacebook