๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿ“‚ Project/์šฐ์•„ํ•œํ…Œํฌ์ฝ”์Šค

[์šฐ์•„ํ•œํ…Œํฌ์ฝ”์Šค] ์šฐํ…Œ์ฝ” ํ”„๋ฆฌ์ฝ”์Šค 6๊ธฐ 3์ฃผ์ฐจ ๋กœ๋˜ ๋ฏธ์…˜ ํšŒ๊ณ 

by Dev. Ella 2023. 11. 8.
๊ฐœ์ธ์ ์œผ๋กœ๋Š” ๋ฏธ์…˜ ์ˆ˜ํ–‰์„ ํ†ตํ•ด ์„ฑ์žฅํ•œ ๊ณผ์ •์„ ๊ธฐ๋กํ•˜๊ณ ,
๋ˆ„๊ตฐ๊ฐ€์—๊ฒŒ๋Š” ์ด ๊ธ€์ด ๋„์›€์ด ๋˜์—ˆ์œผ๋ฉด ํ•˜๋Š” ๋งˆ์Œ์ž…๋‹ˆ๋‹ค :)

 

๐Ÿ› ๏ธ 3์ฃผ ์ฐจ ๊ฒฐ๊ณผ๋ฌผ

3์ฃผ ์ฐจ ๋ฏธ์…˜ : ๋กœ๋˜ PR

๊ฒŒ์ž„ ์‹คํ–‰ ํ™”๋ฉด๊ณผ ํ…Œ์ŠคํŠธ ํ†ต๊ณผ ํ™”๋ฉด

 

 

๐Ÿ“ฎ 3์ฃผ ์ฐจ ๋ฉ”์ผ ๋‚ด์šฉ

1๏ธโƒฃ 3์ฃผ ์ฐจ ๋ฏธ์…˜์˜ ๋ชฉํ‘œ

2์ฃผ ์ฐจ ๋ฏธ์…˜์˜ ๋ชฉํ‘œ๋Š” ํ•จ์ˆ˜ ๋ถ„๋ฆฌ์™€ ํ•จ์ˆ˜๋ณ„ ํ…Œ์ŠคํŠธ ์ž‘์„ฑ์ด ๋ชฉํ‘œ์˜€๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ด๋ฒˆ 3์ฃผ ์ฐจ ๋ฏธ์…˜์—์„œ๋Š” 2์ฃผ ์ฐจ์—์„œ ํ•™์Šตํ•œ ๊ฒƒ์— ๋”ํ•ด (1) ํด๋ž˜์Šค(๊ฐ์ฒด)๋ฅผ ๋ถ„๋ฆฌํ•˜๋Š” ์—ฐ์Šต, (2) ๋„๋ฉ”์ธ ๋กœ์ง์— ๋Œ€ํ•œ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ์—ฐ์Šต์ด๋ผ๋Š” ๋‘ ๊ฐ€์ง€ ๋ชฉํ‘œ๊ฐ€ ์ถ”๊ฐ€๋˜์—ˆ๋‹ค.

 

2๏ธโƒฃ ํ…Œ์ŠคํŠธ ์—ฐ์Šต

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

 

 

๐ŸŒณ ์ง€๋‚œ 2์ฃผ ์ฐจ ๊ณตํ†ต ํ”ผ๋“œ๋ฐฑ

์•„๋ž˜๋Š” 2์ฃผ ์ฐจ ๋ฏธ์…˜ ๋งˆ๊ฐ ํ›„, ๋ชจ๋“  ํ”„๋ฆฌ์ฝ”์Šค ์ฐธ์—ฌ ์ธ์›์—๊ฒŒ ๋ฐœ์†ก๋œ ๊ณตํ†ต ํ”ผ๋“œ๋ฐฑ์ด๋‹ค. ์—„์ฒญ ์˜์™ธ์˜ ๋‚ด์šฉ์ด๋ผ๊ธฐ๋ณด๋‹ค, ์š”๊ตฌ์‚ฌํ•ญ์— ์žˆ๋Š” ๋‚ด์šฉ๋“ค์„ ํ•œ๋ฒˆ ๋” ๊ฐ•์กฐํ•˜๊ฑฐ๋‚˜ ์ถ”๊ฐ€๋กœ ํ•™์Šตํ• ๋งŒํ•œ ๋‚ด์šฉ์ด์—ˆ๋‹ค. ํŠนํžˆ ์ด๋ฒˆ 3์ฃผ ์ฐจ ๋ฏธ์…˜์—์„œ ๊ฐ•์กฐํ•˜๋“ฏ ๊ฐ์ฒด ๋ถ„๋ฆฌ ๋ฐ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž‘์„ฑ์— ๊ด€ํ•œ ๋‚ด์šฉ์ด ์ฃผ๋ฅผ ์ด๋ฃจ์—ˆ๋‹ค.

1. README.md๋ฅผ ์ƒ์„ธํžˆ ์ž‘์„ฑํ•œ๋‹ค
2. ๊ธฐ๋Šฅ ๋ชฉ๋ก์„ ์žฌ๊ฒ€ํ† ํ•œ๋‹ค
3. ๊ธฐ๋Šฅ ๋ชฉ๋ก์„ ์—…๋ฐ์ดํŠธํ•œ๋‹ค
4. ๊ฐ’์„ ํ•˜๋“œ ์ฝ”๋”ฉํ•˜์ง€ ์•Š๋Š”๋‹ค
5. ๊ตฌํ˜„ ์ˆœ์„œ๋„ ์ฝ”๋”ฉ ์ปจ๋ฒค์…˜์ด๋‹ค
6. ํ•œ ํ•จ์ˆ˜๊ฐ€ ํ•œ ๊ฐ€์ง€ ๊ธฐ๋Šฅ๋งŒ ๋‹ด๋‹นํ•˜๊ฒŒ ํ•œ๋‹ค
7. ํ•จ์ˆ˜๊ฐ€ ํ•œ ๊ฐ€์ง€ ๊ธฐ๋Šฅ์„ ํ•˜๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๊ธฐ์ค€์„ ์„ธ์šด๋‹ค
8. JavaScript์—์„œ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“œ๋Š” ๋‹ค์–‘ํ•œ ๋ฐฉ๋ฒ•์„ ์ดํ•ดํ•˜๊ณ  ์‚ฌ์šฉํ•œ๋‹ค.
9. ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ์ด์œ ์— ๋Œ€ํ•ด ๋ณธ์ธ์˜ ๊ฒฝํ—˜์„ ํ† ๋Œ€๋กœ ์ •๋ฆฌํ•ด ๋ณธ๋‹ค
10. ์ฒ˜์Œ๋ถ€ํ„ฐ ํฐ ๋‹จ์œ„์˜ ํ…Œ์ŠคํŠธ๋ฅผ ๋งŒ๋“ค์ง€ ์•Š๋Š”๋‹ค

 

 

๐Ÿคš ๋ฏธ์…˜์— ์•ž์„œ,

1๏ธโƒฃ ๊ธฐ๋Šฅ ๋ชฉ๋ก ๋งŒ๋“ค๊ธฐ

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

 

2๏ธโƒฃ ์ œ์ถœ ์ „ ํ…Œ์ŠคํŠธ ํ•„์ˆ˜

๊ธฐ๋Šฅ ๊ตฌํ˜„์„ ๋ชจ๋‘ ์ •์ƒ์ ์œผ๋กœ ํ–ˆ๋”๋ผ๋„ ์š”๊ตฌ ์‚ฌํ•ญ์— ๋ช…์‹œ๋œ ์ถœ๋ ฅ๊ฐ’ ํ˜•์‹์„ ์ง€ํ‚ค์ง€ ์•Š์„ ๊ฒฝ์šฐ 0์ ์œผ๋กœ ์ฒ˜๋ฆฌ๋œ๋‹ค. ๊ธฐ๋Šฅ ๊ตฌํ˜„์„ ์ œ๋Œ€๋กœ ํ–ˆ๋”๋ผ๋„ ์ถœ๋ ฅ ๊ฐ’ ํ˜•์‹์„ ์ง€ํ‚ค์ง€ ์•Š์œผ๋ฉด 0์ ์ด๋ผ๋Š” ์†Œ๋ฆฌ๋‹ค. ๊ธฐ๋Šฅ ๊ตฌํ˜„์„ ์™„๋ฃŒํ•œ ๋’ค ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ–ˆ์„ ๋•Œ ํ…Œ์ŠคํŠธ๊ฐ€ ์‹คํŒจํ•  ๊ฒฝ์šฐ 0์ ์œผ๋กœ ์ฒ˜๋ฆฌ๋˜๋ฏ€๋กœ, ๋ฐ˜๋“œ์‹œ ํ™•์ธ ํ›„ ์ œ์ถœํ•œ๋‹ค. ํ•„์ž๋Š” Node ํ™˜๊ฒฝ์—์„œ ํ”„๋กœ๊ทธ๋žจ์ด ์ž˜ ๋Œ์•„๊ฐ€๋Š”์ง€ ํ™•์ธํ•˜๊ณ , ๋กœ์ปฌ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ํ†ต๊ณผ๊นŒ์ง€ ํ™•์ธํ–ˆ๋‹ค.

 

๋ฟ๋งŒ ์•„๋‹ˆ๋ผ, ์ œ์ถœ ๊ฐ€๋Šฅ ๊ธฐ๊ฐ„์—๋Š” ๋ฏธ๋ฆฌ PR์„ ์˜ฌ๋ฆฌ๊ณ  ์ง€์›ํ•˜๊ธฐ ํ”Œ๋žซํผ์˜ ์˜ˆ์ œ ํ…Œ์ŠคํŠธ๊นŒ์ง€ ๋ฏธ๋ฆฌ ๋Œ๋ ค๋ณด์•˜๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ๋งˆ๊ฐ์ด ๋ช‡ ์‹œ๊ฐ„ ๋‚จ์ง€ ์•Š์€ ์ƒํƒœ์—์„œ ์ถ”์ธก์ด ์–ด๋ ค์šด ์—๋Ÿฌ์™€ ๊ธฐ์•ฝ ์—†์ด ์‹ธ์›Œ์•ผ ํ•˜๋‹ˆ ๋ฏธ๋ฆฌ๋ฏธ๋ฆฌ ํ™•์ธํ•˜์ž.

 

3๏ธโƒฃ Node ๋ฒ„์ „ ํ™•์ธ ํ•„์ˆ˜

ํ…Œ์ŠคํŠธ ํŒจํ‚ค์ง€ ์„ค์น˜๋ฅผ ์œ„ํ•ด Node.js ๋ฒ„์ „ 18.17.1 ์ด์ƒ์ด ํ•„์š”ํ•˜๋‹ค. ๋ณธ์ธ ๋กœ์ปฌ์˜ Node ๋ฒ„์ „์ด ๋ช‡์ธ์ง€ ๊ผญ ํ™•์ธ ํ›„ ๋ฏธ์…˜์„ ์ง„ํ–‰ํ•˜์ž. ์ฐธ๊ณ ๋กœ Node ๋ฒ„์ „ ํ™•์ธ์€ 'node --version'์œผ๋กœ ํ™•์ธ ๊ฐ€๋Šฅํ•˜๋ฉฐ, ์—…๋ฐ์ดํŠธ๋Š” Node.js ๊ณต์‹ ์‚ฌ์ดํŠธ๋ฅผ ์ฐธ๊ณ ํ•˜๊ฑฐ๋‚˜, ์•„๋ž˜์™€ ๊ฐ™์ด 'nvm install'๋กœ ํŠน์ • Node ๋ฒ„์ „์„ ์„ค์น˜ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

Node ๋ฒ„์ „ ์„ค์ • ํ™”๋ฉด

 

 

๐ŸŽฑ ๊ธฐ๋Šฅ ์š”๊ตฌ ์‚ฌํ•ญ

1๏ธโƒฃ ๋กœ๋˜ ๋ฏธ์…˜ ์„ค๋ช…

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

 

์—ฌ๊ธฐ์„œ ์ž ๊น, ํ˜„์‹ค์—์„œ์˜ ๋กœ๋˜์™€ ๋ฏธ์…˜ ์ƒ์—์„œ์˜ ๋กœ๋˜ ๊ทœ์น™์€ ์•„๋ž˜์™€ ๊ฐ™์ด ๋‹ค๋ฅด๋‹ค.

๐ŸŽฑ ํ˜„์‹ค ๋กœ๋˜ 
๐Ÿ‘‰ ์‚ฌ์šฉ์ž๋Š” ๋กœ๋˜ ๋ฒˆํ˜ธ ์ง์ ‘ ์„ ํƒ or ๋žœ๋ค
๐Ÿ‘‰ ๋‹น์ฒจ ๋ฒˆํ˜ธ๋Š” ๋ฌด์กฐ๊ฑด ๋žœ๋ค ์ถ”์ฒจ

๐ŸŽฑ ๋ฏธ์…˜ ๋กœ๋˜
๐Ÿ‘‰ ์‚ฌ์šฉ์ž๋Š” ๋กœ๋˜ ๋ฒˆํ˜ธ ๋žœ๋ค์œผ๋กœ ์ˆ˜๋ น
๐Ÿ‘‰ ๋‹น์ฒจ ๋ฒˆํ˜ธ๋ฅผ ์ง์ ‘ ์ž…๋ ฅ ํ•„์š”

 

์ฒ˜์Œ ์ด ๋ฏธ์…˜์„ ์ ‘ํ•˜๋ฉด ํ—ท๊ฐˆ๋ฆด ์ˆ˜ ์žˆ๋‹ค. ํ˜„์‹ค์—์„œ๋Š” ๋‚ด๊ฐ€ ๋‹น์ฒจ ๋ฒˆํ˜ธ๋ฅผ ์ ˆ๋Œ€ ์„ ํƒํ•  ์ˆ˜ ์—†๋Š”๋ฐ, ๋ฏธ์…˜์—์„œ๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ๋‹น์ฒจ ๋ฒˆํ˜ธ๋ฅผ ์ง์ ‘ ์ž…๋ ฅํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ํ•˜์ง€๋งŒ ๋ฏธ์…˜์€ ๋ฏธ์…˜์ผ ๋ฟ. ํ˜„์‹ค์— ๋Œ€์ž…ํ•˜๋ฉด ์˜คํžˆ๋ ค ๋” ์š”๊ตฌ ์‚ฌํ•ญ์—์„œ ๋ฒ—์–ด๋‚  ์ˆ˜ ์žˆ์œผ๋‹ˆ ๋งŽ์€ ์ƒ๊ฐ์„ ํ•˜์ง€ ๋ง์ž. (๋งˆ์น˜ ์†Œ๊ธˆ๋ฌผ ๊ตฌํ•˜๋Š” ๋ฌธ์ œ์—์„œ ์™œ ์†Œ๊ธˆ์˜ ๋ฌด๊ฒŒ๋ฅผ ๊ตฌํ•˜๋Š”์ง€ ์˜๋ฌธ์„ ํ’ˆ์ง€ ๋ง์•„์•ผ ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ..)

 

2๏ธโƒฃ ๋กœ๋˜ ์‹คํ–‰ ๊ฒฐ๊ณผ ์˜ˆ์‹œ

๊ตฌ์ž…๊ธˆ์•ก์„ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”.
8000

8๊ฐœ๋ฅผ ๊ตฌ๋งคํ–ˆ์Šต๋‹ˆ๋‹ค.
[8, 21, 23, 41, 42, 43]
[3, 5, 11, 16, 32, 38]
[7, 11, 16, 35, 36, 44]
[1, 8, 11, 31, 41, 42]
[13, 14, 16, 38, 42, 45]
[7, 11, 30, 40, 42, 43]
[2, 13, 22, 32, 38, 45]
[1, 3, 5, 14, 22, 45]

๋‹น์ฒจ ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”.
1,2,3,4,5,6

๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”.
7

๋‹น์ฒจ ํ†ต๊ณ„
---
3๊ฐœ ์ผ์น˜ (5,000์›) - 1๊ฐœ
4๊ฐœ ์ผ์น˜ (50,000์›) - 0๊ฐœ
5๊ฐœ ์ผ์น˜ (1,500,000์›) - 0๊ฐœ
5๊ฐœ ์ผ์น˜, ๋ณด๋„ˆ์Šค ๋ณผ ์ผ์น˜ (30,000,000์›) - 0๊ฐœ
6๊ฐœ ์ผ์น˜ (2,000,000,000์›) - 0๊ฐœ
์ด ์ˆ˜์ต๋ฅ ์€ 62.5%์ž…๋‹ˆ๋‹ค.

 

์ด๋ฒˆ ๋ฏธ์…˜ ๋˜ํ•œ ์ง€๋‚œ 2์ฃผ ์ฐจ์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ (ํ˜น์€ ํ›จ์”ฌ ๋” ๊ผผ๊ผผํ•˜๊ฒŒ) ์‚ฌ์šฉ์ž์˜ ๋‹ค์–‘ํ•œ ์ธํ’‹์„ ์˜ˆ์ƒํ•˜๋ฉฐ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๋ฅผ ํ–ˆ์–ด์•ผ ํ–ˆ๋‹ค. ์š”๊ตฌ ์‚ฌํ•ญ์„ ๊ผผ๊ผผํ•˜๊ฒŒ ์ฝ์ง€ ์•Š์œผ๋ฉด ๋†“์น˜๊ธฐ ์‰ฌ์šด ๊ฒƒ๋“ค์ด ๋งŽ์œผ๋‹ˆ ๋”์šฑ ๊ผผ๊ผผํ•˜๊ฒŒ ์ฝ์–ด๋ณด์ž.

 

์•„๋ž˜ ์š”๊ตฌ์‚ฌํ•ญ๋“ค์„ ์•„์ฃผ ๊ผผ๊ผผํ•˜๊ฒŒ ์”น์–ด๋จน๋“ฏ ์ฝ์–ด๋ณด์ž. (์ค‘์š”)

 

3๏ธโƒฃ ๋กœ๋˜ ๊ธฐ๋Šฅ ์š”๊ตฌ ์‚ฌํ•ญ

โœ… ๋กœ๋˜ ๋ฒˆํ˜ธ์˜ ์ˆซ์ž ๋ฒ”์œ„๋Š” 1~45๊นŒ์ง€์ด๋‹ค.

๐Ÿ‘‰ ๋กœ๋˜ ๋ฒˆํ˜ธ์˜ ์ˆซ์ž ๋ฒ”์œ„๋Š” 1 ์ด์ƒ 45 ์ดํ•˜๋‹ค. ์ด ๋ง์€ ์ด ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚˜๋ฉด ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๋ฅผ ๊ผญ ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค๋Š” ์˜๋ฏธ.

 

โœ… 1๊ฐœ์˜ ๋กœ๋˜๋ฅผ ๋ฐœํ–‰ํ•  ๋•Œ ์ค‘๋ณต๋˜์ง€ ์•Š๋Š” 6๊ฐœ์˜ ์ˆซ์ž๋ฅผ ๋ฝ‘๋Š”๋‹ค.

๐Ÿ‘‰ 1๊ฐœ์˜ ๋กœ๋˜์—๋Š” ์„œ๋กœ ์ค‘๋ณต๋˜์ง€ ์•Š๋Š” 6๊ฐœ์˜ ์ˆซ์ž๋ฅผ ๋ฝ‘์•„์•ผ ํ•œ๋‹ค. ๋”๋ถˆ์–ด, ๊ฐ ๋กœ๋˜ ๋ฒˆํ˜ธ ๊ตฌ์„ฑ์ด ์ค‘๋ณต๋˜์–ด์„œ๋„ ์•ˆ๋œ๋‹ค.

 

โœ… ๋‹น์ฒจ ๋ฒˆํ˜ธ ์ถ”์ฒจ ์‹œ ์ค‘๋ณต๋˜์ง€ ์•Š๋Š” ์ˆซ์ž 6๊ฐœ์™€ ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ 1๊ฐœ๋ฅผ ๋ฝ‘๋Š”๋‹ค.

๐Ÿ‘‰ (๋กœ๋˜ ๋ฒˆํ˜ธ๊ฐ€ ์•„๋‹ˆ๋ผ) ์‚ฌ์šฉ์ž๊ฐ€ ๋‹น์ฒจ ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•˜๋ฉด ์„œ๋กœ ์ค‘๋ณต๋˜์ง€ ์•Š๋Š” ์ˆซ์ž 6๊ฐœ, ๊ทธ๋ฆฌ๊ณ  ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ 1๊ฐœ๋ฅผ ๋ฝ‘๋Š”๋‹ค. ์ด๋•Œ ๋‹น์ฒจ ๋ฒˆํ˜ธ ๊ฐ„์˜ ์ค‘๋ณต์ด ์žˆ์–ด์„œ๋„ ์•ˆ๋˜๊ณ , ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ์™€ ๋‹น์ฒจ ๋ฒˆํ˜ธ ๊ฐ„์˜ ์ค‘๋ณต์ด ์žˆ์–ด์„œ๋„ ์•ˆ๋˜๋‹ˆ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๋ฅผ ๊ผญ ํ•ด์ฃผ์ž.

 

โœ… ๋‹น์ฒจ์€ 1๋“ฑ๋ถ€ํ„ฐ 5๋“ฑ๊นŒ์ง€ ์žˆ๋‹ค. ๋‹น์ฒจ ๊ธฐ์ค€๊ณผ ๊ธˆ์•ก์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

 

- 1๋“ฑ: 6๊ฐœ ๋ฒˆํ˜ธ ์ผ์น˜ / 2,000,000,000์›
- 2๋“ฑ: 5๊ฐœ ๋ฒˆํ˜ธ + ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ ์ผ์น˜ / 30,000,000์›
- 3๋“ฑ: 5๊ฐœ ๋ฒˆํ˜ธ ์ผ์น˜ / 1,500,000์›
- 4๋“ฑ: 4๊ฐœ ๋ฒˆํ˜ธ ์ผ์น˜ / 50,000์›
- 5๋“ฑ: 3๊ฐœ ๋ฒˆํ˜ธ ์ผ์น˜ / 5,000์›

 

๐Ÿ‘‰ ์œ„์˜ ์ถœ๋ ฅ ๊ฒฐ๊ณผ๋ฅผ ๊ทธ๋Œ€๋กœ ๋”ฐ๋ฅด์ž. ๋˜๋„๋ก์ด๋ฉด ๊ทธ๋Œ€๋กœ ๋ณต์‚ฌ ๋ถ™์—ฌ ๋„ฃ๊ธฐ ํ•ด์„œ ์ƒ์ˆ˜ํ™” ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์„ ๊ฒƒ ๊ฐ™๋‹ค. ๋˜ํ•œ, 5๊ฐœ ๋ฒˆํ˜ธ๊ฐ€ ์ผ์น˜ํ•œ๋‹ค๊ณ  ํ•ด์„œ ๋ชจ๋‘ 2๋“ฑ์ด ์•„๋‹ˆ๋‹ค. 2๋“ฑ์€ 5๊ฐœ ๋ฒˆํ˜ธ ๊ทธ๋ฆฌ๊ณ  ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๊นŒ์ง€ ์ผ์น˜ํ•ด์•ผ ํ•œ๋‹ค.

 

โœ… ๋กœ๋˜ ๊ตฌ์ž… ๊ธˆ์•ก์„ ์ž…๋ ฅํ•˜๋ฉด ๊ตฌ์ž… ๊ธˆ์•ก์— ํ•ด๋‹นํ•˜๋Š” ๋งŒํผ ๋กœ๋˜๋ฅผ ๋ฐœํ–‰ํ•ด์•ผ ํ•œ๋‹ค.

๐Ÿ‘‰ ๋กœ๋˜ ๊ฒŒ์ž„ ์‹œ์ž‘ ์‹œ, ์‚ฌ์šฉ์ž๊ฐ€ ๊ตฌ์ž… ๊ธˆ์•ก์„ ์ž…๋ ฅํ•˜๋Š”๋ฐ ์ด๋•Œ ๊ตฌ์ž… ๊ธˆ์•ก์— ํ•ด๋‹นํ•˜๋Š” ๋งŒํผ ๋กœ๋˜๋ฅผ ๋ฐœํ–‰ํ•ด์•ผ ํ•œ๋‹ค. ์ด ๋ง์€ ์ฆ‰, ๊ตฌ์ž… ๊ธˆ์•ก / ๋กœ๋˜ ๊ฐ€๊ฒฉ์œผ๋กœ ๋‚˜๋ˆ„์–ด ๋กœ๋˜ ๊ฐœ์ˆ˜๋ฅผ ๋ฑ‰์–ด๋‚ด์•ผ ํ•œ๋‹ค๋Š” ๋ง.

 

โœ… ๋กœ๋˜ 1์žฅ์˜ ๊ฐ€๊ฒฉ์€ 1,000์›์ด๋‹ค.

๐Ÿ‘‰ ์ด ๋ง์€ ์‚ฌ์šฉ์ž๊ฐ€ 1,000์› ์ดํ•˜๋ฅผ ์ž…๋ ฅํ•˜๊ฑฐ๋‚˜ 1,000์›์œผ๋กœ ๋–จ์–ด์ง€์ง€ ์•Š๋Š” ์ˆ˜ (e.g. 1,200)๋ฅผ ์ž…๋ ฅํ•˜๋ฉด ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๋ฅผ ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค๋Š” ์˜๋ฏธ๋‹ค.

 

โœ… ๋‹น์ฒจ ๋ฒˆํ˜ธ์™€ ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅ๋ฐ›๋Š”๋‹ค.

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

 

โœ… ์‚ฌ์šฉ์ž๊ฐ€ ๊ตฌ๋งคํ•œ ๋กœ๋˜ ๋ฒˆํ˜ธ์™€ ๋‹น์ฒจ ๋ฒˆํ˜ธ๋ฅผ ๋น„๊ตํ•˜์—ฌ ๋‹น์ฒจ ๋‚ด์—ญ ๋ฐ ์ˆ˜์ต๋ฅ ์„ ์ถœ๋ ฅํ•˜๊ณ  ๋กœ๋˜ ๊ฒŒ์ž„์„ ์ข…๋ฃŒํ•œ๋‹ค.

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

 

โœ… ์‚ฌ์šฉ์ž๊ฐ€ ์ž˜๋ชป๋œ ๊ฐ’์„ ์ž…๋ ฅํ•  ๊ฒฝ์šฐ throw๋ฌธ์„ ์‚ฌ์šฉํ•ด ์˜ˆ์™ธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚จ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ, "[ERROR]"๋กœ ์‹œ์ž‘ํ•˜๋Š” ์—๋Ÿฌ ๋ฉ”์‹œ์ง€๋ฅผ ์ถœ๋ ฅํ•˜๊ณ  ํ•ด๋‹น ๋ถ€๋ถ„๋ถ€ํ„ฐ ์ž…๋ ฅ์„ ๋‹ค์‹œ ๋ฐ›๋Š”๋‹ค.

๐Ÿ‘‰ ์ •๋ง ์ค‘์š”ํ•œ ํฌ์ธํŠธ. ์ด ํฌ์ธํŠธ๋ฅผ ๋’ค๋Šฆ๊ฒŒ ๋ด์„œ ํ…Œ์ŠคํŠธ๊ฐ€ ํ†ต๊ณผ๋˜์ง€ ์•Š์•˜๋˜ ์ ์ด ์žˆ๋‹ค. 1, 2์ฃผ ์ฐจ์—๋Š” ์—๋Ÿฌ ๋ฉ”์‹œ์ง€๋ฅผ ์ถœ๋ ฅํ•˜๊ณ  ์ฆ‰์‹œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์ข…๋ฃŒํ–ˆ๋Š”๋ฐ, ์ด๋ฒˆ ๋ฏธ์…˜๋ถ€ํ„ฐ๋Š” ํ•ด๋‹น ๋ถ€๋ถ„๋ถ€ํ„ฐ ๋‹ค์‹œ ์ž…๋ ฅ์„ ๋ฐ›์•„์•ผ ํ•œ๋‹ค. ๋””์Šค์ฝ”๋“œ ์ปค๋ฎค๋‹ˆํ‹ฐ๋ฅผ ์ง€์ผœ๋ณด๋‹ˆ ์ด ๋ถ€๋ถ„์„ ๊ฝค ๋งŽ์€ ์‚ฌ๋žŒ๋“ค์ด ๋†“์น˜๋Š” ๊ฒƒ ๊ฐ™์•˜๋‹ค. ์ •๋ง ์š”๊ตฌ์‚ฌํ•ญ์— ๋‹ต์ด ๋‹ค ๋‚˜์™€์žˆ๋‹ค!

 

 

๐Ÿšจ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์š”๊ตฌ ์‚ฌํ•ญ - ์‹คํ–‰ ํ™˜๊ฒฝ

โœ… Node.js 18.17.1 ๋ฒ„์ „์—์„œ ์‹คํ–‰ ๊ฐ€๋Šฅํ•ด์•ผ ํ•œ๋‹ค.

๐Ÿ‘‰ Node ๋ฒ„์ „ ์ฒดํฌ ํ•„์ˆ˜๋‹ค. ์ž‘์—…ํ•  ๋•Œ ํ™•์ธํ–ˆ๋”๋ผ๋„ ์ œ์ถœํ•˜๊ธฐ ์ง์ „์— ๋‹ค์‹œ ํ•œ๋ฒˆ ํ•ด๋‹น ๋ฒ„์ „์—์„œ ์ž˜ ๋Œ์•„๊ฐ€๋Š”์ง€ ํ™•์ธํ•˜์ž.

 

โœ… ํ”„๋กœ๊ทธ๋žจ ์‹คํ–‰์˜ ์‹œ์ž‘์ ์€ App.js์˜ play ๋ฉ”์„œ๋“œ๋‹ค.

๐Ÿ‘‰ App.js๋กœ ๊ฒŒ์ž„์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋˜ ์ง€๋‚œ 1์ฃผ ์ฐจ์™€๋Š” ๋‹ฌ๋ฆฌ 2,3์ฃผ ์ฐจ๋Š” App ํด๋ž˜์Šค๊ฐ€ index.js์— import ๋˜์–ด node ํ™˜๊ฒฝ์—์„œ index.js๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค. ๋งค ๋ฏธ์…˜๋งˆ๋‹ค ์‹คํ–‰ ํ™˜๊ฒฝ์ด๋‚˜ ์š”๊ตฌ ์‚ฌํ•ญ์ด ์™„์ „ํžˆ ๋˜‘๊ฐ™์ง€ ์•Š์„ ํ…Œ๋‹ˆ ์ด๋ฏธ ์•Œ๊ณ  ์žˆ๋Š” ๊ฒƒ์ด๋ผ๋„ ๋‹ค์‹œ ์ฝ์–ด๋ณด๋Š” ๊ฒƒ์ด ์ข‹๊ฒ ๋‹ค.

 

โœ… package.json์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†๊ณ  ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ(jQuery, Lodash ๋“ฑ)๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค. ์ˆœ์ˆ˜ Vanilla JS๋กœ๋งŒ ๊ตฌํ˜„ํ•œ๋‹ค.

๐Ÿ‘‰ 1์ฃผ ์ฐจ ๊ณตํ†ต ํ”ผ๋“œ๋ฐฑ์— ๋‚˜์™€ ์žˆ๋“ฏ์ด ์ด์ œ๋Š” ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ESLint์™€ Prettier๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋ณ€๊ฒฝ๋œ package.json ๋‚ด์—ญ์€ ๊ตณ์ด push ํ•˜์ง€ ์•Š์•˜๋‹ค.

 

โœ… JavaScript ์ฝ”๋“œ ์ปจ๋ฒค์…˜์„ ์ง€ํ‚ค๋ฉด์„œ ํ”„๋กœ๊ทธ๋ž˜๋ฐํ•œ๋‹ค.

๐Ÿ‘‰ Airbnb ์ฝ”๋“œ ์ปจ๋ฒค์…˜์„ ํ•˜๋‚˜ํ•˜๋‚˜ ๋ณด๊ณ  ๋”ฐ๋ฅด๊ธฐ์—๋Š” ๋„ˆ๋ฌด ๋ฒˆ๊ฑฐ๋กœ์šฐ๋ฏ€๋กœ ESLint์™€ Prettier๋ฅผ ์„ค์ •ํ•ด์„œ ์ปจ๋ฒค์…˜์„ ๋งž์ถ”์—ˆ๋‹ค.

 

โœ… ํ”„๋กœ๊ทธ๋žจ ์ข…๋ฃŒ ์‹œ process.exit()๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š๋Š”๋‹ค.

๐Ÿ‘‰ ๋ณดํ†ต ํ”„๋กœ๊ทธ๋žจ์„ ์ข…๋ฃŒํ•  ๋•Œ Console.Close()๋‚˜ process.exit()๋ฅผ ์‚ฌ์šฉํ•˜๊ณ ๋Š” ํ–ˆ์ง€๋งŒ, ์—ฌ๊ธฐ์„œ๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š๋Š”๋‹ค. ์ง€๋‚œ 1์ฃผ ์ฐจ ๋ฏธ์…˜์—์„œ๋Š” ๊ฒŒ์ž„ ์ข…๋ฃŒ ์‹œ '๊ฒŒ์ž„ ์ข…๋ฃŒ' ๋ฌธ๊ตฌ๋ฅผ ์ถœ๋ ฅํ–ˆ๊ณ , 2์ฃผ ์ฐจ๋Š” ์—๋Ÿฌ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๊ณ  ๊ทธ๋Œ€๋กœ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์ข…๋ฃŒ๋˜๋„๋ก ํ–ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ด๋ฒˆ 3์ฃผ ์ฐจ๋Š” ํ•ด๋‹น ๋ถ€๋ถ„๋ถ€ํ„ฐ ๋‹ค์‹œ ์ž…๋ ฅ์„ ๋ฐ›๋Š”๋‹ค.

 

โœ… ํ”„๋กœ๊ทธ๋žจ ๊ตฌํ˜„์ด ์™„๋ฃŒ๋˜๋ฉด ApplicationTest์˜ ๋ชจ๋“  ํ…Œ์ŠคํŠธ๊ฐ€ ์„ฑ๊ณตํ•ด์•ผ ํ•œ๋‹ค. ํ…Œ์ŠคํŠธ๊ฐ€ ์‹คํŒจํ•  ๊ฒฝ์šฐ 0์  ์ฒ˜๋ฆฌํ•œ๋‹ค.

๐Ÿ‘‰ ์ด๋ฒˆ ๋ฏธ์…˜์˜ ApplicationTest๋Š” ์ด 3๊ฐœ์˜ ํ…Œ์ŠคํŠธ์˜€๊ณ , ์ด ์„ธ ๊ฐ€์ง€ ํ…Œ์ŠคํŠธ๋ฅผ ๋ชจ๋‘ ํ†ต๊ณผํ•ด์•ผ ํ•œ๋‹ค.

 

โœ… ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์š”๊ตฌ ์‚ฌํ•ญ์—์„œ ๋‹ฌ๋ฆฌ ๋ช…์‹œํ•˜์ง€ ์•Š๋Š” ํ•œ ํŒŒ์ผ, ํŒจํ‚ค์ง€ ์ด๋ฆ„์„ ์ˆ˜์ •ํ•˜๊ฑฐ๋‚˜ ์ด๋™ํ•˜์ง€ ์•Š๋Š”๋‹ค.

๐Ÿ‘‰ ๋””ํดํŠธ๋กœ ์žˆ๋˜ ํŒŒ์ผ(package.json, package-lock.json ๋“ฑ)๊ณผ ์ฝ”๋“œ, ํด๋”๋Š” ๊ตณ์ด ๊ฑด๋“ค์ง€ ์•Š์•˜๋‹ค. ํ˜น์‹œ๋‚˜ ์ง€์› ํ”Œ๋žซํผ ์˜ˆ์ œ ํ…Œ์ŠคํŠธ์— ํ†ต๊ณผํ•˜์ง€ ๋ชปํ• ๊นŒ ๋ด ๊ต‰์žฅํžˆ ์กฐ์‹ฌ์Šค๋Ÿฌ์› ๋˜ ๊ฒƒ๋„ ์žˆ๋‹ค. ์‚ฌ์‹ค src ํด๋” ๋ฐ”๋กœ ํ•˜์œ„์— ์žˆ๋˜ Lotto.js๋ฅผ src > model ํด๋” ํ•˜์œ„์— ๋‘๊ณ  ์‹ถ์—ˆ์œผ๋‚˜.. ์ด ์š”๊ตฌ ์‚ฌํ•ญ์„ ๋ณด๊ณ ๋Š” ๊ทธ๋ƒฅ ๋‘˜ ์ˆ˜๋ฐ–์— ์—†์—ˆ๋‹ค.

 

โœ… indent(์ธ๋ดํŠธ, ๋“ค์—ฌ ์“ฐ๊ธฐ) depth๋ฅผ 3์ด ๋„˜์ง€ ์•Š๋„๋ก ๊ตฌํ˜„ํ•œ๋‹ค. 2๊นŒ์ง€๋งŒ ํ—ˆ์šฉํ•œ๋‹ค. 

๐Ÿ‘‰ ์ด๋ฒˆ๋ถ€ํ„ฐ ์ƒˆ๋กญ๊ฒŒ ์ถ”๊ฐ€๋œ ์š”๊ตฌ์‚ฌํ•ญ์ด์ง€๋งŒ, ์‚ฌ์‹ค ํ•จ์ˆ˜ ํ•˜๋‚˜์— 15์ค„ ์ด์ƒ ๋„˜์–ด๊ฐ€๊ณ  depth๊ฐ€ ๋งŽ์•„์ง€๋ฉด ํ•œ ๊ฐ€์ง€ ์ผ์„ ํ•˜์ง€ ์•Š์„ ๊ฐ€๋Šฅ์„ฑ์ด ๋†’๋‹ค. ๋”ฐ๋ผ์„œ indent depth๋ฅผ ์ค„์ด๊ณ ์ž ํ•œ๋‹ค๋ฉด ํ•จ์ˆ˜ ๋˜๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ๋ถ„๋ฆฌํ•˜๋ฉด ๋œ๋‹ค. ๋”๋ถˆ์–ด, ๋งŽ์€ ์ด๋“ค์ด depth์— ๋Œ€ํ•ด ์ปค๋ฎค๋‹ˆํ‹ฐ์— ์งˆ๋ฌธ์„ ๋‚จ๊ฒผ๋Š”๋ฐ, ์˜ˆ๋ฅผ ๋“ค์–ด while๋ฌธ ์•ˆ์— if๋ฌธ์ด ์žˆ์œผ๋ฉด ๋“ค์—ฌ ์“ฐ๊ธฐ๋Š” 2์ด๋‹ค.

 

โœ… ํ•จ์ˆ˜(๋˜๋Š” ๋ฉ”์„œ๋“œ)๊ฐ€ ํ•œ ๊ฐ€์ง€ ์ผ๋งŒ ํ•˜๋„๋ก ์ตœ๋Œ€ํ•œ ์ž‘๊ฒŒ ๋งŒ๋“ค์–ด๋ผ.

๐Ÿ‘‰ ๊ณตํ†ต ํ”ผ๋“œ๋ฐฑ์„ ๋น„๋กฏํ•ด ๊ณ„์†ํ•ด์„œ ๊ฐ•์กฐํ•˜๋Š” ๋ง์ด๋‹ค. ํ•จ์ˆ˜๊ฐ€ ๋šฑ๋šฑํ•ด์ง€์ง€ ์•Š๋„๋ก ์‹ ๊ฒฝ ์จ์•ผ ํ•œ๋‹ค.


โœ… Jest๋ฅผ ์ด์šฉํ•˜์—ฌ ๋ณธ์ธ์ด ์ •๋ฆฌํ•œ ๊ธฐ๋Šฅ ๋ชฉ๋ก์ด ์ •์ƒ ๋™์ž‘ํ•จ์„ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋กœ ํ™•์ธํ•œ๋‹ค. 

๐Ÿ‘‰ ๋˜๋„๋ก ๋ชจ๋“  ๋ฉ”์„œ๋“œ๋ฅผ ํ…Œ์ŠคํŠธํ•˜๊ณ ์ž ํ–ˆ๋‹ค. ํŠนํžˆ ์ž‘์€ ๋‹จ์œ„๋Š” ๊ผญ ํ…Œ์ŠคํŠธํ•ด์„œ ์ถ”ํ›„ ์ปจํŠธ๋กค๋Ÿฌ์—์„œ ํ„ฐ์ง€๋ฉด ์•ˆ ๋˜๋‹ˆ๊นŒ.

 

 

โž• 3์ฃผ ์ฐจ๋ถ€ํ„ฐ ์ถ”๊ฐ€๋œ ์š”๊ตฌ์‚ฌํ•ญ

โœ… ํ•จ์ˆ˜(๋˜๋Š” ๋ฉ”์„œ๋“œ)์˜ ๊ธธ์ด๊ฐ€ 15๋ผ์ธ์„ ๋„˜์–ด๊ฐ€์ง€ ์•Š๋„๋ก ๊ตฌํ˜„ํ•˜๋ฉฐ, ํ•จ์ˆ˜(๋˜๋Š” ๋ฉ”์„œ๋“œ)๊ฐ€ ํ•œ ๊ฐ€์ง€ ์ผ๋งŒ ์ž˜ํ•˜๋„๋ก ๊ตฌํ˜„ํ•œ๋‹ค.

๐Ÿ‘‰ ์ด ์š”๊ตฌ์‚ฌํ•ญ์ด ์žˆ์–ด์„œ ๋” ์˜์‹์ ์œผ๋กœ ์ข‹์€ ์ฝ”๋“œ๋ฅผ ์“ธ ์ˆ˜ ์žˆ๊ฒŒ ๋œ ๊ฒƒ ๊ฐ™๋‹ค. ๋”๋ถˆ์–ด, ์ด๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ESLint ์ƒ์—์„œ ์„ค์ •ํ•˜๋ฉด ์ข‹๋‹ค.

 

// .eslintrc.cjs
'max-lines-per-function': ['error', { max: 15 }],


โœ… else๋ฅผ ์ง€์–‘ํ•œ๋‹ค. 

๐Ÿ‘‰ if ์กฐ๊ฑด์ ˆ์—์„œ return ํ•˜๋ฉด ๊ตณ์ด else๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค. ๋‹ค๋งŒ, ๋ฌด์กฐ๊ฑด์ ์œผ๋กœ ์ง€์–‘ํ•œ๋‹ค๊ธฐ๋ณด๋‹ค ๋•Œ๋กœ๋Š” if/else์™€ switch๋ฌธ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋” ๊น”๋”ํ•ด ๋ณด์ผ ์ˆ˜ ์žˆ์–ด์„œ ์ด๋Š” ๊ณ ๋ฏผํ•ด ๋ณด๋ผ๊ณ  ํ•œ๋‹ค.

 

โœ… ๋„๋ฉ”์ธ ๋กœ์ง์— ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋ฅผ ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค. ๋‹จ, UI(Console.readLineAsync, Console.print) ๋กœ์ง์— ๋Œ€ํ•œ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋Š” ์ œ์™ธํ•œ๋‹ค.

๐Ÿ‘‰ ์—ฌ๊ธฐ์„œ ์ค‘์š”ํ•œ ๊ฑด ํ•ต์‹ฌ ๋กœ์ง์„ ๊ตฌํ˜„ํ•˜๋Š” ์ฝ”๋“œ์™€ UI๋ฅผ ๋‹ด๋‹นํ•˜๋Š” ๋กœ์ง์„ ๊ตฌ๋ถ„ํ•œ๋‹ค๋Š” ๊ฒƒ. ์นœ์ ˆํ•˜๊ฒŒ๋„ ์ง€๋‚œ 2์ฃผ ์ฐจ์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ํ…Œ์ŠคํŠธ ๋„๊ตฌ ์‚ฌ์šฉ๋ฒ•์ด ์ต์ˆ™ํ•˜์ง€ ์•Š์€ ์‚ฌ๋žŒ๋“ค์—๊ฒŒ ์˜ˆ์ œ๋กœ ์ฃผ์–ด์ง„ LottoTest.js๋ผ๋Š” ํŒŒ์ผ์ด ์ฃผ์–ด์กŒ๋‹ค. 

 

 

๐Ÿšจ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์š”๊ตฌ ์‚ฌํ•ญ - ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

โœ… @woowacourse/mission-utils์˜ Random ๋ฐ Console API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค.

โœ… Random ๊ฐ’ ์ถ”์ถœ์€ Random.pickUniqueNumbersInRange()๋ฅผ ํ™œ์šฉํ•œ๋‹ค.

โœ… ์‚ฌ์šฉ์ž์˜ ๊ฐ’์„ ์ž…๋ ฅ๋ฐ›๊ณ  ์ถœ๋ ฅํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” Console.readLineAsync, Console.print๋ฅผ ํ™œ์šฉํ•œ๋‹ค.

๐Ÿ‘‰ 1, 2์ฃผ ์ฐจ์™€ ๋‹ค๋ฅธ ์ ์€ Random.pickNumberInRange()๊ฐ€ ์•„๋‹ˆ๋ผ, Random.pickUniqueNumbersInRange()๋ฅผ ํ™œ์šฉํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ์ด ๋ฉ”์„œ๋“œ๋Š” ์ธ์ž๊ฐ€ 3๊ฐœ ๋“ค์–ด๊ฐ„๋‹ค.

 

โœ… Lotto ํด๋ž˜์Šค

๐Ÿ‘‰ ์ œ๊ณต๋œ Lotto ํด๋ž˜์Šค๋กœ ๊ตฌํ˜„ํ•ด์•ผ ํ•˜๋ฉฐ, prefix ๋ณ€๊ฒฝ์ด๋‚˜ ํ•„๋“œ ์ถ”๊ฐ€๋Š” ๋ถˆ๊ฐ€ํ•˜๋‹ค.

 

 

๐Ÿ“š ๋ฏธ์…˜์„ ํ†ตํ•ด ์ ์šฉํ•˜๊ณ  ๋ฐฐ์šด ์ 

1๏ธโƒฃ README ์ƒ์„ธํ•˜๊ฒŒ ์ž‘์„ฑํ•˜๊ธฐ

์ž‘์„ฑํ•œ README.md

 

์ง€๋‚œ 2์ฃผ ์ฐจ ๊ณตํ†ต ํ”ผ๋“œ๋ฐฑ์˜ 1๋ฒˆ ์‚ฌํ•ญ "README.md๋ฅผ ์ƒ์„ธํžˆ ์ž‘์„ฑํ•œ๋‹ค"๋ฅผ ์ค€์ˆ˜ํ•˜๊ณ ์ž ํ–ˆ๋‹ค. ๋ฌผ๋ก  ์ง€๋‚œ ๋ฏธ์…˜๋“ค๋„ README ์ž‘์„ฑ์„ ๊ผผ๊ผผํ•˜๊ฒŒ ํ•œ ํŽธ์ด์ง€๋งŒ, ๋งค ๋ฏธ์…˜์„ ๊ฑฐ์น˜๋ฉด์„œ README์— ๋ฌด์–ธ๊ฐ€๊ฐ€ ๋ณ€๊ฒฝ๋œ๋‹ค. (๊ทธ๋งŒํผ ํ•™์Šตํ•˜๊ณ  ์„ฑ์žฅํ•˜๊ณ  ์žˆ๋‹ค๋Š” ๋œป?) ํ•„์ž๋Š” ๊ณตํ†ต ํ”ผ๋“œ๋ฐฑ์„ ์•„๋ž˜์™€ ๊ฐ™์ด ๋ฐ˜์˜ํ•˜๊ณ ์ž ํ–ˆ๋‹ค.

 

โœ… ํ•ด๋‹น ํ”„๋กœ์ ํŠธ๊ฐ€ ์–ด๋–ค ํ”„๋กœ์ ํŠธ์ด๋ฉฐ, ์–ด๋–ค ๊ธฐ๋Šฅ์„ ๋‹ด๊ณ  ์žˆ๋Š”์ง€ ๊ธฐ์ˆ ํ•œ๋‹ค.

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

 

โœ… ๊ธฐ๋Šฅ ๋ชฉ๋ก์„ ํด๋ž˜์Šค ์„ค๊ณ„์™€ ๊ตฌํ˜„, ํ•จ์ˆ˜(๋ฉ”์„œ๋“œ) ์„ค๊ณ„์™€ ๊ตฌํ˜„๊ณผ ๊ฐ™์ด ๋„ˆ๋ฌด ์ƒ์„ธํ•˜๊ฒŒ ์ž‘์„ฑํ•˜์ง€ ์•Š๋Š”๋‹ค. 

๐Ÿ‘‰ 1์ฃผ ์ฐจ ๋•Œ๋Š” ๋ฉ”์„œ๋“œ ์„ค๊ณ„์™€ ๊ตฌํ˜„์„ ์—„์ฒญ ์ƒ์„ธํ•˜๊ฒŒ ์ ์–ด๋‘์—ˆ๋Š”๋ฐ, ๊ทธ๋ ‡๊ฒŒ ๋˜๋ฉด ๋ฌธ์„œ ์ˆ˜์ •์—๋„ ๊ฝค ์‹œ๊ฐ„์„ ์ผ์–ด์•ผ ํ–ˆ๋‹ค. 2์ฃผ ์ฐจ๋ถ€ํ„ฐ๋Š” ๋„ˆ๋ฌด ์„ธ์„ธํ•œ ๋ถ€๋ถ„๊นŒ์ง€ ์ •๋ฆฌํ•˜๊ธฐ๋ณด๋‹ค ๊ตฌํ˜„ํ•ด์•ผ ํ•  ๊ธฐ๋Šฅ ๋ชฉ๋ก์„ ์ •๋ฆฌํ•˜๋Š” ๋ฐ ์ง‘์ค‘ํ•˜๊ณ ์ž ํ–ˆ๋‹ค. 

 

โœ… ์ •์ƒ์ ์ธ ๊ฒฝ์šฐ๋„ ์ค‘์š”ํ•˜์ง€๋งŒ, ์˜ˆ์™ธ์ ์ธ ์ƒํ™ฉ๋„ ๊ธฐ๋Šฅ ๋ชฉ๋ก์— ์ •๋ฆฌํ•œ๋‹ค.

๐Ÿ‘‰ ์ •๋ง ์ค‘์š”ํ•œ ํฌ์ธํŠธ! ์ง€๋‚œ 2์ฃผ ์ฐจ ๋•Œ ๋‚˜๋ฆ„ ์‹ ๊ฒฝ ์ผ๋‹ค๊ณ  ํ–ˆ์ง€๋งŒ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ๋ถ€๋ถ„์—์„œ ์Šค์Šค๋กœ ์•„์‰ฌ์›€์ด ์žˆ์—ˆ๋‹ค. ์ด๋ฒˆ์—๋Š” ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๋งŒํผ์€ ๋นˆํ‹ˆ์—†์ด ํ•ด์•ผ๊ฒ ๋‹ค ์ƒ๊ฐํ–ˆ๊ณ , ์˜ˆ์™ธ ์ƒํ™ฉ์— ๋Œ€ํ•œ ์ถœ๋ ฅ ๋ฉ”์‹œ์ง€๊นŒ์ง€ ๋ชจ๋‘ ์ •๋ฆฌํ•ด ๋‘์—ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ์ •๋ฆฌํ•ด ๋‘๋‹ˆ ๊ธฐ๋Šฅ ํ…Œ์ŠคํŠธ๋ฅผ ํ•  ๋•Œ QA๋ฅผ ํ•˜๋Š” ๊ฒƒ ๊ฐ™์ด ํ•˜๋‚˜ํ•˜๋‚˜ ์ƒ์„ธํ•˜๊ฒŒ ์ฒดํฌํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.

 

โœ… ๊ธฐ๋Šฅ ๋ชฉ๋ก์„ ์—…๋ฐ์ดํŠธํ•œ๋‹ค.

๐Ÿ‘‰ ์ฒ˜์Œ๋ถ€ํ„ฐ ๋ชจ๋“  ๊ธฐ๋Šฅ ๋ชฉ๋ก์„ ์™„๋ฒฝํ•˜๊ฒŒ ์ •๋ฆฌํ•˜๊ธฐ๋ณด๋‹ค, ์š”๊ตฌ์‚ฌํ•ญ์— ์žˆ๋Š” ๊ฒƒ์„ ์ž˜ ์ •๋ฆฌํ•ด ๋‘”๋‹ค ๋ผ๋Š” ๋Š๋‚Œ์ด์—ˆ๊ณ , ์ดํ›„ ๊ธฐ๋Šฅ ๊ตฌํ˜„์„ ํ•˜๋ฉด์„œ README๋„ ์ˆ˜์ •ํ•ด ๋‚˜๊ฐ€๋ฉฐ ์‚ด์•„์žˆ๋Š” ๋ฌธ์„œ๋ฅผ ๋งŒ๋“ค๊ณ ์ž ํ–ˆ๋‹ค.

 

โœ… ๊ทธ ์™ธ ์ž‘์„ฑํ•œ ๊ฒƒ

๐Ÿ‘‰ ์ด๋ฒˆ 3์ฃผ ์ฐจ ๋•Œ ์šฐํ…Œ์ฝ” ์ธก์—์„œ ์ œ์‹œํ•œ ๋ชฉํ‘œ์™€ ํ•จ๊ป˜ ์Šค์Šค๋กœ 2์ฃผ ์ฐจ๋ณด๋‹ค ๊ฐœ์„ ํ•˜๊ณ  ์‹ถ์€ ๊ฒƒ๋“ค์„ ์ ์–ด์„œ ๊ตฌํ˜„ํ•˜๋Š” ๋‚ด๋‚ด ์ž˜ ์ง€ํ‚ค๊ณ  ์žˆ๋Š”์ง€ ์ฒดํฌํ•˜๊ธฐ๋„ ํ–ˆ๋‹ค. ๋งค์ฃผ ์‹ค๋ ฅ์ด ๋˜‘๊ฐ™์œผ๋ฉด ์•ˆ ๋œ๋‹ค. ๋ญ”๊ฐ€ ๋งค์ฃผ ๋” ๋‚˜์•„์ ธ์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

 

2๏ธโƒฃ ์ƒ์ˆ˜ ์ปจ๋ฒค์…˜

์ง€๋‚œ 2์ฃผ ์ฐจ ๋•Œ ์ƒ์ˆ˜ ๊ด€๋ จ Airbnb ์ปจ๋ฒค์…˜์„ ๋”ฐ๋ฅด์ง€ ์•Š์•„์„œ ๊ด€๋ จํ•ด ํ”ผ๋“œ๋ฐฑ์„ ๋ฐ›์•˜๊ณ , ์•„๋ž˜์™€ ๊ฐ™์ด 3์ฃผ ์ฐจ ๋•Œ ๋ฐ”๋กœ ๋ฐ˜์˜ํ•ด ๋ณด์•˜๋‹ค. ๋งˆ์นจ 2์ฃผ ์ฐจ ๊ณตํ†ต ํ”ผ๋“œ๋ฐฑ์—์„œ "๊ฐ’์„ ํ•˜๋“œ์ฝ”๋”ฉํ•˜์ง€ ์•Š๋Š”๋‹ค"๋ผ๋Š” ๋ง์ด ์žˆ๊ธฐ๋„ ํ–ˆ๋‹ค. ๋”๋ถˆ์–ด, ์ƒ์ˆ˜๋กœ ๋งŒ๋“œ๋Š” ๊ฒƒ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ํ•ด๋‹น ๋ณ€์ˆ˜์˜ ์—ญํ• ์ด ๋ฌด์—‡์ธ์ง€ ๋„ค์ด๋ฐ์—๋„ ๋งŽ์€ ๊ณ ๋ฏผ์„ ํ–ˆ๋‹ค.

์ƒ์ˆ˜ ๊ด€๋ จ 2์ฃผ์ฐจ ํ”ผ๋“œ๋ฐฑ์„ 3์ฃผ์ฐจ์— ๋ฐ˜์˜

 

 

Airbnb ์ปจ๋ฒค์…˜์— ๋”ฐ๋ฅด๋ฉด, ์•„๋ž˜์™€ ๊ฐ™์ด ํ‚ค๋Š” ๋Œ€๋ฌธ์ž, ๊ฐ’์€ ์†Œ๋ฌธ์ž๋กœ ์ž‘์„ฑํ•œ๋‹ค๊ณ  ํ•œ๋‹ค. ๋ฌด์˜์‹์ ์œผ๋กœ ์ƒ์ˆ˜๋Š” ๋ฌด์กฐ๊ฑด ๋Œ€๋ฌธ์ž๋ผ๊ณ  ์ƒ๊ฐํ–ˆ๋Š”๋ฐ ์ด ๋ถ€๋ถ„์„ ํ•œ๋ฒˆ ๋” ์ฒดํฌํ•  ์ˆ˜ ์žˆ์–ด ์ข‹์•˜๋‹ค.

 

// bad - unnecessarily uppercases key while adding no semantic value
export const MAPPING = {
  KEY: 'value'
};

// good
export const MAPPING = {
  key: 'value',
};

 

3๏ธโƒฃ ๋ฉ”์„œ๋“œ ์„ธ์„ธํ•˜๊ฒŒ ์ฒดํฌํ•˜๊ธฐ

๋ฉ”์„œ๋“œ ๊ด€๋ จ 2์ฃผ์ฐจ ํ”ผ๋“œ๋ฐฑ์„ 3์ฃผ์ฐจ์— ๋ฐ˜์˜

 

์ง€๋‚œ 2์ฃผ ์ฐจ ์ฝ”๋“œ๋ฆฌ๋ทฐ์—์„œ 2~3๊ฐ€์ง€ ์ •๋„๊ฐ€ ๋ฉ”์„œ๋“œ์— ๋Œ€ํ•œ ๋‚ด์šฉ์ด์—ˆ๋‹ค. ๋Œ€์ฒด๋กœ ํ•„์š”ํ•˜์ง€ ์•Š์€ ๊ฒƒ์„ ์ถ”๊ฐ€ํ–ˆ๋‹ค๋Š” ํ”ผ๋“œ๋ฐฑ์ด์—ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์ด๋ฒˆ์—๋Š” ๊ดœํžˆ ๋ถ„๋ฆฌํ•ด์„œ ํ•„์š”ํ•˜์ง€ ์•Š์€ ์—ญํ• ์„ ํ•˜๋Š” ๋ฉ”์„œ๋“œ๋Š” ์—†๋Š”์ง€ ์‚ดํŽด๋ณด์•˜๋‹ค. ๊ตฌํ˜„ ์ดˆ๋ฐ˜์—๋Š” ํ•„์š”ํ•ด ๋ณด์ด๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ์ผ๋‹จ ์ถ”๊ฐ€ํ•˜๊ณ , ๊ตฌํ˜„ํ•˜๋ฉด์„œ ๊ตณ์ด ํ•„์š”ํ•˜์ง€ ์•Š์€ ๊ฒƒ๋“ค์€ ์†Œ๊ฑฐํ•ด ๋‚˜๊ฐ€๋Š” ๋ฐฉ์‹์œผ๋กœ ์ง„ํ–‰ํ–ˆ๋‹ค.

 

4๏ธโƒฃ ๊ตฌํ˜„ ์ˆœ์„œ

๋”๋ถˆ์–ด, 2์ฃผ ์ฐจ์—๋Š” ์ˆœ์„œ ์—†์ด ๊ธฐ๋Šฅ ๊ตฌํ˜„์„ ํ–ˆ๋‹ค๋ฉด, ์ด๋ฒˆ 3์ฃผ ์ฐจ์—๋Š” ์ž‘์€ ๋ฉ”์„œ๋“œ๋ถ€ํ„ฐ ์ž‘์„ฑํ–ˆ๋‹ค. ์•„๋ฌด๋ž˜๋„ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋ฅผ ๋Œ๋ ค์•ผ ํ–ˆ๊ธฐ์—, ์ž‘์€ ๋‹จ์œ„๋ถ€ํ„ฐ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋กœ ๊ฒ€์ฆํ•ด ๋‚˜๊ฐ€๋ฉด ํฐ ๋‹จ์œ„์˜ ํ…Œ์ŠคํŠธ์—์„œ๋„ ์ž˜ ๋Œ์•„๊ฐ€์ง€ ์•Š์„๊นŒ ์‹ถ์–ด์„œ์˜€๋‹ค.

 

๊ทธ๋ž˜์„œ ์œ ํ‹ธ ํ•จ์ˆ˜(์ž…์ถœ๋ ฅ, ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ) → ๊ฐ ํ•ญ๋ชฉ๋‹น ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ํด๋ž˜์Šค → ๊ทธ๋ฆฌ๊ณ  ์ด ํด๋ž˜์Šค๋ฅผ ์ปจํŠธ๋กค๋Ÿฌ์—์„œ ๋ชจ๋‘ ํ•ฉ์น˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์ง„ํ–‰ํ–ˆ๋‹ค. ๋ฌผ๋ก  ์š”๊ตฌ์‚ฌํ•ญ์ด ์• ๋งคํ•˜๊ณ  ๋ถˆํ™•์‹คํ•œ ์ƒํ™ฉ์—์„œ๋Š” ํฐ ๋กœ์ง๋ถ€ํ„ฐ ์งœ๊ณ  ํ•„์š”ํ•œ ํ•จ์ˆ˜๋“ค์„ ์งœ๊ฑฐ๋‚˜ ์œ ํ‹ธ๋กœ ๋นผ๋Š” ๊ฒƒ์ด ์ข‹๊ธฐ๋„ ํ•˜๊ฒ ์ง€๋งŒ, ์š”๊ตฌ์‚ฌํ•ญ์ด ํ™•์‹คํ•œ ์ƒํ™ฉ์ด์—ˆ๊ธฐ์— ํ•„์š”ํ•œ ์ž‘์€ ํ•จ์ˆ˜๋“ค๋ถ€ํ„ฐ ๋งŒ๋“ค์–ด ๋‚˜๊ฐ”๋‹ค.

 

import { LOTTO, ERROR } from '../common/constants.js';
import { throwError } from '../common/utils.js';

// ๋งŒ๋“ค์–ด ๋‘” ์œ ํ‹ธ์„ฑ validator๋ฅผ import ํ•ด์˜ค๋Š” ๋ฐฉ์‹
import { isNumeric, isDivisibleByUnit } from '../common/validator.js';

// ๊ตฌ์ž… ๊ธˆ์•ก ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ํด๋ž˜์Šค
class MoneyValidator {
  constructor(input) {
    this.input = input;
  };

  validate() {
    this.#validateInput();
    this.#validateNumber();
    this.#validateMoneyUnit();
  };

// ๊ณต๋ฐฑ์ด ์žˆ๋‹ค๋ฉด ์—๋Ÿฌ ์ถœ๋ ฅ
  #validateInput() {
    if (!this.input) {
      throwError(ERROR.empty);
    }
  };

// ์–‘์˜ ์ •์ˆ˜๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด ์—๋Ÿฌ ์ถœ๋ ฅ
  #validateNumber() {
    if (!isNumeric(this.input)) {
      throwError(ERROR.numeric);
    }
  };

// 1000 ๋‹จ์œ„๋กœ ๋–จ์–ด์ง€์ง€ ์•Š์œผ๋ฉด ์—๋Ÿฌ ์ถœ๋ ฅ
  #validateMoneyUnit() {
    if (!isDivisibleByUnit(this.input, LOTTO.money_unit)) {
      throwError(ERROR.money);
    }
  };
};

export default MoneyValidator;

 

ํ•˜์ง€๋งŒ ์ด๋Š” 3์ฃผ ์ฐจ ๋ฏธ์…˜์— ํ•ด๋‹นํ•˜๋Š” ์ด์•ผ๊ธฐ์˜€๊ณ , ์•„๋งˆ 4์ฃผ ์ฐจ๋ถ€ํ„ฐ๋Š” ํ•ต์‹ฌ ๋กœ์ง์„ ์ž‘๊ฒŒ ๊ตฌํ˜„ํ•ด ๋ณด๋ฉด์„œ ํ•„์š”ํ•œ ํ•จ์ˆ˜๋“ค์„ ๊ทธ๋•Œ๊ทธ๋•Œ ๋งŒ๋“ค์–ด ๋‚˜๊ฐ€๋Š” ๋ฐฉ์‹์œผ๋กœ ์‹œ๋„ํ•ด ๋ณผ ๊ฒƒ ๊ฐ™๋‹ค. (๋ถˆํ™•์‹คํ•œ ๋ฌธ์ œ๋ฅผ ํ‘ธ๋Š” ๋ฐ์—๋Š” ์ตœ์†Œ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๋Š” MVP๋ฅผ ๋งŒ๋“ค์–ด ๋‘๊ณ  ํ•˜๋Š” ๊ฒƒ์ด ๋‚ซ์ง€ ์•Š์„๊นŒ ์ƒ๊ฐํ•ด์„œ๋‹ค.) ์–ด๋Š ๊ฒƒ์ด ๋” ์ข‹์€์ง€๋Š” ์ด๋ ‡๊ฒŒ ๋‹ค์–‘ํ•œ ์‹คํ—˜์„ ํ†ตํ•ด ์ง์ ‘ ๋Š๊ปด๋ณด๊ณ ์ž ํ•œ๋‹ค.

 

5๏ธโƒฃ ๋นˆํ‹ˆ์—†๋Š” ๊ตฌํ˜„

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

์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ๊ด€๋ จ 2์ฃผ์ฐจ ํ”ผ๋“œ๋ฐฑ์„ 3์ฃผ์ฐจ์— ๋ฐ˜์˜

 

๋”๋ถˆ์–ด, ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์š”๊ตฌ์‚ฌํ•ญ์„ ์ฝ๊ณ  ๋˜ ์ฝ์œผ๋ฉฐ ์ตœ๋Œ€ํ•œ ์ง€ํ‚ค๊ณ ์ž ๋…ธ๋ ฅํ–ˆ๋‹ค. ์ž์นซํ•˜๋ฉด ๋นผ๋จน์„ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ๋“ค๋„ ๋งŽ์•˜๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” ๊ณต๋ฐฑ์ด ์˜ค๋ฆ„ ์ฐจ์ˆœ์œผ๋กœ ๋‚˜์—ด๋œ ๋ฐฐ์—ด ํ˜•ํƒœ๋กœ ๋ฐ›๋Š”๋ฐ ๋‹น์ฒจ๋ฒˆํ˜ธ๋Š” ๊ณต๋ฐฑ ์—†๋Š” ๋ฌธ์ž์—ด ํ˜•ํƒœ๋กœ ๋ฐ›๊ณ , ์ˆ˜์ต๋ฅ ์€ 1000 ๋‹จ์œ„๋กœ ์‰ผํ‘œ๋ฅผ ์ฐ๊ณ  ์†Œ์ˆ˜์  ๋‘˜์งธ ์ž๋ฆฌ์—์„œ ๋ฐ˜์˜ฌ๋ฆผ์„ ํ•œ๋‹ค๋“ ๊ฐ€. ๋™์‹œ์— ์ด๋ฅผ ๊ฒ€์ฆํ•˜๋Š” ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ๋˜ํ•œ ๊ผผ๊ผผํ•˜๊ฒŒ ์งœ๊ณ ์ž ํ–ˆ๋‹ค.

 

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

 

6๏ธโƒฃ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์™œ ์ž‘์„ฑํ•ด์•ผ ํ•˜๋Š”๊ฐ€

์ง€๋‚œ 2์ฃผ ์ฐจ ๊ณตํ†ต ํ”ผ๋“œ๋ฐฑ์—์„œ๋Š” "ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ์ด์œ ์— ๋Œ€ํ•ด ๋ณธ์ธ์˜ ๊ฒฝํ—˜์„ ํ† ๋Œ€๋กœ ์ •๋ฆฌํ•ด ๋ณธ๋‹ค"๋ผ๋Š” ๋ฌธ์žฅ๊ณผ ํ•จ๊ป˜ ํ•™์Šต ์ž๋ฃŒ๋ฅผ ์ œ๊ณต๋ฐ›์•˜๋‹ค. JUnit์„ ํ•™์Šตํ•˜๋ฉฐ ์ž‘์€ ๋‹จ์œ„์˜ ์œ ๋‹› ํ…Œ์ŠคํŠธ๋ถ€ํ„ฐ ๋งŒ๋“ค๊ณ ์ž ํ–ˆ๋‹ค. 

 

์šฐํ…Œ์ฝ” ์ธก์—์„œ ์ œ๊ณตํ•œ ํ•™์Šต ํ…Œ์ŠคํŠธ ์ค‘ ์ผ๋ถ€

 

๋”๋ถˆ์–ด, ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋ผ๋Š” ๊ฒƒ์— ๋Œ€ํ•ด ๊ถ๊ธˆํ•ด ์„œ์นญํ•ด ๋ณด๋‹ค๊ฐ€ ์•„๋ž˜์˜ ํ…Œ์ŠคํŠธ ํ”ผ๋ผ๋ฏธ๋“œ๋ผ๋Š” ๊ฐœ๋…์„ ์•Œ๊ฒŒ ๋˜์—ˆ๋‹ค. ์ด ๊ฐœ๋…์—์„œ ์„ค๋ช…ํ•˜๊ธธ, Unit ํ…Œ์ŠคํŠธ๋Š” ๋…๋ฆฝ๋œ ์ž‘์€ ์กฐ๊ฐ์œผ๋กœ ํ…Œ์ŠคํŠธํ•˜๊ณ , Integration ํ…Œ์ŠคํŠธ๋Š” ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์œผ๋กœ ๊ทธ๋ฃน์œผ๋กœ ๊ฒฐํ•ฉ๋˜์–ด ํ…Œ์ŠคํŠธํ•œ๋‹ค๊ณ  ํ•œ๋‹ค. 

 

Test Pyramid @Amazon Alexa

 

์ด๋ฒˆ ๋ฏธ์…˜์—์„œ ์š”๊ตฌํ•˜๋Š” '๋‹จ์œ„ ํ…Œ์ŠคํŠธ'๋ž€ ๋ฌด์—‡์ธ์ง€ ๋จผ์ € ์ •์˜ํ•ด ๋ณด์ž.

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

์ฐธ๊ณ : Unit Testing @developerexperience


๋”ฐ๋ผ์„œ ๋‚˜๋Š” ์ด๋ฒˆ ๋ฏธ์…˜์—์„œ๋Š” ์ž‘์€ ๋‹จ์œ„์˜ ํ•จ์ˆ˜๋‚˜ ๋ชจ๋“ˆ์ด ์˜๋„๋œ ๋Œ€๋กœ ์ •ํ™•ํžˆ ์ž‘๋™ํ•˜๋Š”์ง€ ํ…Œ์ŠคํŠธํ•˜๊ณ , ์ปจํŠธ๋กค๋Ÿฌ ํ…Œ์ŠคํŠธ๋ฅผ ๋ณ„๋„๋กœ ์ง„ํ–‰ํ•˜์ง€ ์•Š์•˜๋‹ค.
๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ ํ•จ์ˆ˜๋ฅผ ๋ชจํ‚นํ™” ํ•˜์—ฌ๋„, ์‹ค์ œ๋กœ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๊ฐ’์„ ๋„ฃ๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ฏ€๋กœ, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€์˜ ์—ฐ๋™์—์„œ๋„ ์ œ๋Œ€๋กœ ํ…Œ์ŠคํŠธ๋˜๋Š” ๊ฒƒ์ธ์ง€๋Š” ์•Œ ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์ด์—ˆ๋‹ค.

 

๋”ฐ๋ผ์„œ ํ•ด๋‹น ํ•จ์ˆ˜์— ํ…Œ์ŠคํŠธ์— ์„ฑ๊ณต์„ ํ•ด๋„ ์‹ค์ œ ์„œ๋น„์Šค์˜ ์‹ค์ œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋Ÿด ๋• ์œ ๋‹› ํ…Œ์ŠคํŠธ๊ฐ€ ์•„๋‹Œ, ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ๋‚˜ ์‹œ์Šคํ…œ ํ…Œ์ŠคํŠธ๋ฅผ ์ง„ํ–‰ํ•ด์•ผ ํ•  ๊ฒƒ์ด๋‹ค. (์ฐธ๊ณ : [JEST] ๐Ÿ“š ๋ชจํ‚น Mocking ์ •๋ฆฌ)

 

๊ฐœ๋…์„ ๊ณต๋ถ€ํ•˜๊ณ , ํ…Œ์ŠคํŠธ ์ฝ”๋“œ์™€ ํ•จ๊ป˜ ๊ธฐ๋Šฅ ๊ตฌํ˜„์„ ํ•˜๋ฉฐ ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ์ด์œ ์— ๋Œ€ํ•ด ์•„๋ž˜์™€ ๊ฐ™์ด ์ •๋ฆฌํ•ด ๋ณด์•˜๋‹ค.

 

์ผ๋‹จ ๊ฐ€์žฅ ์ข‹์€ ์ด์œ ๋Š” "์†Œ์Šค ์ฝ”๋“œ์— ๋Œ€ํ•ด ๋น ๋ฅด๊ฒŒ ํ”ผ๋“œ๋ฐฑ์„ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ"์ด๋‹ค. ์‚ฌ์‹ค ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜์ง€ ์•Š์•„๋„ ๋˜์—ˆ๋˜ 1์ฃผ ์ฐจ ๋ฏธ์…˜์—์„œ๋Š” Integration ํ…Œ์ŠคํŠธ๋งŒ ํ•˜๋‹ค ๋ณด๋‹ˆ, ์—๋Ÿฌ๊ฐ€ ๋‚˜๋ฉด ์–ด๋Š ์ฝ”๋“œ์—์„œ ๋ˆ„์ˆ˜๊ฐ€ ๋˜์—ˆ๋Š”์ง€ ํŒŒ์•…์ด ์–ด๋ ค์› ๋‹ค. ๋ฐ˜๋ฉด, ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•œ 2์ฃผ ์ฐจ์™€ 3์ฃผ ์ฐจ์—๋Š” ์ž‘์€ ๋‹จ์œ„์˜ ๋ฉ”์„œ๋“œ๋“ค๋ถ€ํ„ฐ '์ด๊ฑด ์ž˜ ๋์–ด' '์ด๊ฑด ์ž˜๋ชป๋์–ด'๋ผ๋Š” ํ”ผ๋“œ๋ฐฑ์„ ๋ฐ›์œผ๋‹ˆ ๋‚ด ์ฝ”๋“œ์— ๋Œ€ํ•œ ์‹ ๋ขฐ๋„๊ฐ€ ์ƒ๊ฒผ๋‹ค.

 

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

 

import { ERROR } from '../../src/common/constants.js';
import MoneyValidator from '../../src/service/MoneyValidator.js';

describe('๊ตฌ๋งค ๊ธˆ์•ก ํ…Œ์ŠคํŠธ', () => {
  const validateMoney = (input, expectedError) => {
    const moneyValidator = new MoneyValidator(input);
    if (expectedError) {
      expect(() => moneyValidator.validate()).toThrow(expectedError);
    } else {
      expect(() => moneyValidator.validate()).not.toThrow();
    }
  };

  test('๊ธˆ์•ก์ด ์œ ํšจํ•œ ํ˜•์‹์ด๋ผ๋ฉด ์„ฑ๊ณต', () => {
    validateMoney('10000');
  });

  test('๊ธˆ์•ก์ด 1000 ๋‹จ์œ„๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด ์‹คํŒจ', () => {
    validateMoney('1010', ERROR.money);
  });

  test('๊ธˆ์•ก์ด ๋ฌธ์ž์—ด์ด๋ผ๋ฉด ์‹คํŒจ', () => {
    validateMoney('abc', ERROR.numeric);
  });

  test('๊ธˆ์•ก์ด ๊ณต๋ฐฑ์ด๋ผ๋ฉด ์‹คํŒจ', () => {
    validateMoney(' ', ERROR.numeric);
  });
});

 

 

๐Ÿ‘ฉ๐Ÿป‍๐Ÿ”ง ํŠธ๋Ÿฌ๋ธ” ์ŠˆํŒ…

์ผ๋ฐ˜์ ์ธ ์—๋Ÿฌ๋Š” ๋”ฐ๋กœ ๋‹ค๋ฅธ ๊ธ€๋กœ ๋ฐœํ–‰ํ•˜๊ณ ,
๋ณธ ๋ฏธ์…˜์—์„œ ๋งˆ์ฃผํ•  ์ˆ˜ ์žˆ๋Š” ๋ช‡ ๊ฐœ๋งŒ ๊ธฐ์ˆ ํ•ฉ๋‹ˆ๋‹ค.

 

1๏ธโƒฃ ๋ฌด์ง€์„ฑ ๋ณต๋ถ™ ๊ธˆ์ง€

๋กœ๋˜ ๊ตฌ์ž… ๊ธˆ์•ก์„ ๊ฒ€์ฆํ•˜๋Š” ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ํ†ต๊ณผ๋ฅผ ๋ชปํ•˜๊ณ  ์žˆ์—ˆ๋‹ค.

 

๊ตฌ์ž… ๊ธˆ์•ก ํ…Œ์ŠคํŠธ ์—๋Ÿฌ ํ™”๋ฉด

 

์ฝ”๋“œ๋ฅผ ์‚ดํŽด๋ณด์•˜๋”๋‹ˆ, ๋‹ค๋ฅธ ์˜ˆ์™ธ ์ƒํ™ฉ์ธ๋ฐ ๊ฐ™์€ ์—๋Ÿฌ ๋ฌธ๊ตฌ๋ฅผ ์ถœ๋ ฅํ•˜๊ณ  ์žˆ๋˜ ๊ฒƒ์ด๋‹ค..

 

// ์ˆ˜์ • ์ „
test('์ž…๋ ฅํ•œ ๊ตฌ์ž… ๊ธˆ์•ก์ด 1000 ๋‹จ์œ„๋กœ ๋–จ์–ด์ง€์ง€ ์•Š์œผ๋ฉด ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.', async () => {
    const invalidInput = '1010';
    Console.readLineAsync.mockResolvedValueOnce(invalidInput);

    await expect(isValidPaidAmount()).rejects.toThrow(ERROR.paid_amount); // ์—๋Ÿฌ ๋ฌธ๊ตฌ
  });

  test('์ž…๋ ฅํ•œ ๊ตฌ์ž… ๊ธˆ์•ก์ด ๋ฌธ์ž์—ด์ด๋ฉด ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.', async () => {
    const invalidInput = 'abc';
    Console.readLineAsync.mockResolvedValueOnce(invalidInput);

    await expect(isValidPaidAmount()).rejects.toThrow(ERROR.paid_amount); // ์—๋Ÿฌ ๋ฌธ๊ตฌ
  });
  
// ์ˆ˜์ • ํ›„
test('์ž…๋ ฅํ•œ ๊ตฌ์ž… ๊ธˆ์•ก์ด 1000 ๋‹จ์œ„๋กœ ๋–จ์–ด์ง€์ง€ ์•Š์œผ๋ฉด ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.', async () => {
    const invalidInput = '1010';
    Console.readLineAsync.mockResolvedValueOnce(invalidInput);

    await expect(isValidPaidAmount()).rejects.toThrow(ERROR.paid_amount); // ์—๋Ÿฌ ๋ฌธ๊ตฌ
  });

  test('์ž…๋ ฅํ•œ ๊ตฌ์ž… ๊ธˆ์•ก์ด ๋ฌธ์ž์—ด์ด๋ฉด ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.', async () => {
    const invalidInput = 'abc';
    Console.readLineAsync.mockResolvedValueOnce(invalidInput);

    await expect(isValidPaidAmount()).rejects.toThrow(ERROR.numeric); // ์—๋Ÿฌ ๋ฌธ๊ตฌ
  });

 

์›์ธ์€ ๋ฌด์ง€์„ฑ์œผ๋กœ ๋ณต์‚ฌ ๋ถ™์—ฌ ๋„ฃ๊ธฐ๋ฅผ ํ•œ ํƒ“์ด์—ˆ๋‹ค. ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋Š” (๋ฆฌํŒฉํ† ๋ง์„ ํ•˜๊ธฐ ์ „์—๋Š”) ์ฝ”๋“œ๊ฐ€ ๋ฐ˜๋ณต๋˜๋Š” ๊ฒฝํ–ฅ์ด ์žˆ๋‹ค ๋ณด๋‹ˆ ์•„๋ฌด ์ƒ๊ฐ ์—†์ด ๋ณต๋ถ™์„ ํ•ด์„œ ๋ฌด์—‡์ด ํ‹€๋ฆฐ ์ง€๋ฅผ ๋ชฐ๋ž๋‹ค. ๋ถ„๋ช… validator์—์„œ ์˜ˆ์™ธ ์ƒํ™ฉ์— ๋”ฐ๋ผ ์ถœ๋ ฅ๋˜๋Š” ๋ฌธ๊ตฌ๋ฅผ ๋‚˜๋ˆ„์–ด ๋‘์—ˆ๋Š”๋ฐ, ๋‘˜ ๋‹ค ๊ฐ™์€ ์—๋Ÿฌ ๋ฉ”์‹œ์ง€๋ฅผ ์ถœ๋ ฅํ•˜๊ฒŒ ๋‘์—ˆ์œผ๋‹ˆ ๋‹น์—ฐํžˆ ํ†ต๊ณผ๊ฐ€ ์•ˆ๋˜์ง€. ์ด๊ฒƒ ๋•Œ๋ฌธ์— ๊ดœํžˆ ์†Œ์Šค์ฝ”๋“œ๋งŒ ๋“ค์—ฌ๋‹ค๋ณด์•˜๋‹ค.

 

์œ„์™€ ๊ฐ™์€ ์ƒํ™ฉ์ด ๋ฐœ์ƒํ•œ ์ดํ›„์—๋Š” ์‚ฌ์†Œํ•œ ์‹ค์ˆ˜๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ๋‚˜๋ฅผ ์œ„ํ•œ ์ฃผ์„์„ ํ™œ์šฉํ–ˆ๋‹ค. ์Šต๊ด€์„ ์ž˜ ๋งŒ๋“ค์–ด์„œ ์‹œ๊ฐ„์„ ์•„๊ปด์•ผ ํ•ด..

 

validateWinningNumber() {
    this.validateNumber(); // ์ˆซ์ž(๊ณต๋ฐฑ ๋“ฑ) ์—ฌ๋ถ€ ํŒ๋‹จ -> ERROR.numeric ์ถœ๋ ฅ
    this.validateFormat(); // ์‰ผํ‘œ ๊ตฌ๋ถ„ ์—ฌ๋ถ€ ํŒ๋‹จ -> ERROR.winning_format ์ถœ๋ ฅ
    this.validateLength(); // ์ˆซ์ž 6๊ฐœ ํŒ๋‹จ -> ERROR.winning_length ์ถœ๋ ฅ
    this.validateUnique(); // ์ค‘๋ณต ์—ฌ๋ถ€ ํŒ๋‹จ -> ERROR.winning_duplicate ์ถœ๋ ฅ
    this.validateRange(); // 1~45 ์—ฌ๋ถ€ ํŒ๋‹จ -> ERROR.range ์ถœ๋ ฅ

    return this.input;
  }

 

2๏ธโƒฃ true? false?

์ด๋ฒˆ์—๋„ ๋˜ ๋‚ด๊ฐ€ ์ž‘์„ฑํ•œ ํ…Œ์ŠคํŠธ ํ†ต๊ณผ๊ฐ€ ์•ˆ ๋˜๋Š” ์ƒํ™ฉ์ด์—ˆ๋‹ค.

 

๋‹น์ฒจ ๋ฒˆํ˜ธ ํ…Œ์ŠคํŠธ ์—๋Ÿฌ ํ™”๋ฉด

 

ํ…Œ์ŠคํŠธ ๋Œ€์ƒ์ธ ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋ฅผ ๊ฒ€์ฆํ•˜๋Š” ๋กœ์ง ์•ˆ์— ์‚ฌ์šฉ๋˜๋Š” ๋ฉ”์„œ๋“œ๋“ค์€ ์•„๋ž˜์™€ ๊ฐ™์ด ์ž‘์„ฑํ•ด ๋‘์—ˆ์—ˆ๋‹ค. ์ด ์ค‘์—์„œ 'ํƒ€๊ฒŸ ์•ˆ์— ํŠน์ • ์š”์†Œ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๋ฉ”์„œ๋“œ'๊ฐ€ ๋ฌธ์ œ์˜€๋‹ค. ๋ฌด์—‡์ด ๋ฌธ์ œ์˜€์„๊นŒ?

 

// ํƒ€๊ฒŸ ์•ˆ์— ํŠน์ • ์š”์†Œ๊ฐ€ ํฌํ•จ(์ค‘๋ณต)๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๋ฉ”์„œ๋“œ
const isElementInTarget = (target, element) => target.includes(element);

// ์–‘์˜ ์ •์ˆ˜์ธ์ง€ ํ™•์ธํ•˜๋Š” ๋ฉ”์„œ๋“œ (์Œ์ˆ˜, ์†Œ์ˆ˜, ๊ณต๋ฐฑ, ํŠน์ˆ˜๋ฌธ์ž, ๋ฌธ์ž์—ด, 0์œผ๋กœ ์‹œ์ž‘ํ•˜๋Š” ์ˆซ์ž ๋ถˆ๊ฐ€)
const isNumeric = (input) => UTILS.positive_integer.test(input);

// ํŠน์ • ๋ฒ”์œ„ ์•ˆ์— ๊ฐ’์ด ํฌํ•จ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๋ฉ”์„œ๋“œ
const isInRange = (input, min, max) => input >= min && input <= max;

 

์•Œ๊ณ  ๋ณด๋‹ˆ, ์ค‘๋ณต ์—ฌ๋ถ€๋ฅผ ๊ฒ€์‚ฌํ•˜๋Š” isElementInTarget ๋ฉ”์„œ๋“œ์˜ true / false ์ˆœ์„œ๋ฅผ ๋ฐ”๊พธ์–ด ๋‘์—ˆ๊ธฐ ๋•Œ๋ฌธ์ด์—ˆ๋‹ค. 

 

// ์ˆ˜์ • ์ „
test('๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ์™€ ๋‹น์ฒจ ๋ฒˆํ˜ธ ๊ฐ„์˜ ์ค‘๋ณต ์—ฌ๋ถ€', () => {
    const winningNumber = '1,2,3,4,5,6';
    const uniqueBonusNumber = '7';
    const duplicateBonusNumber = '6';

    expect(isElementInTarget(winningNumber.split(','), uniqueBonusNumber)).toBe(true);
    expect(isElementInTarget(winningNumber.split(','), duplicateBonusNumber)).toBe(false);
  });

 

 

์•„๋ž˜์™€ ๊ฐ™์ด isNumeric์ด๋‚˜ isInRange ๋ฉ”์„œ๋“œ์™€๋Š” ๋‹ค๋ฅด๊ฒŒ isElementInTarget๋Š” ์ค‘๋ณต์ด ์žˆ์œผ๋ฉด false๋ฅผ ๋ฑ‰์–ด๋‚ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

 

isElementInTarget ๐Ÿ‘‰ ์ค‘๋ณต๋œ ๊ฐ’์ด ์žˆ๋Š”๊ฐ€? ๐Ÿ‘‰ ์žˆ๋‹ค(true) ๐Ÿ‘‰ ์‹คํŒจ
isNumeric ๐Ÿ‘‰ ์–‘์˜ ์ •์ˆ˜์ธ๊ฐ€? ๐Ÿ‘‰ ๋งž๋‹ค(true) ๐Ÿ‘‰ ํ†ต๊ณผ
isInRange ๐Ÿ‘‰ ๋ฒ”์œ„ ๋‚ด์— ์žˆ๋Š”๊ฐ€? ๐Ÿ‘‰ ๋งž๋‹ค(true) ๐Ÿ‘‰ ํ†ต๊ณผ

 

์•„๋ž˜์™€ ๊ฐ™์ด ์ˆ˜์ •ํ•ด ์ฃผ์—ˆ๋”๋‹ˆ ํ…Œ์ŠคํŠธ ํ†ต๊ณผ๊ฐ€ ๋˜์—ˆ๋‹ค. 

 

// ์ˆ˜์ • ํ›„ : true & false ์ˆœ์„œ ๋ณ€๊ฒฝ
test('๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ์™€ ๋‹น์ฒจ ๋ฒˆํ˜ธ ๊ฐ„์˜ ์ค‘๋ณต ์—ฌ๋ถ€', () => {
    const winningNumber = '1,2,3,4,5,6';
    const uniqueBonusNumber = '7';
    const duplicateBonusNumber = '6';

    expect(isElementInTarget(winningNumber.split(','), uniqueBonusNumber)).toBe(false);
    expect(isElementInTarget(winningNumber.split(','), duplicateBonusNumber)).toBe(true);
  });

 

์ด๋ฒˆ์—๋„ ์‚ฌ์†Œํ•œ ์‹ค์ˆ˜๋กœ ์ธํ•ด ์—๋Ÿฌ๊ฐ€ ๋‚ฌ๋‹ค. ํ•˜์ง€๋งŒ ์ด๋Ÿฐ ์‚ฌ์†Œํ•œ ์‹ค์ˆ˜์ผ์ˆ˜๋ก ๋‹ค์‹œ ๋ฐ˜๋ณตํ•˜์ง€ ์•Š๊ณ ์ž ๊ธฐ๋กํ•ด ๋‘”๋‹ค.

 

 

๐Ÿงน ๋ฆฌํŒฉํ† ๋ง

1๏ธโƒฃ while์—์„œ ์žฌ๊ท€๋กœ

์ด๋ฒˆ ๋ฏธ์…˜๋ถ€ํ„ฐ ๋‹ฌ๋ผ์ง„ ๋ถ€๋ถ„์€ ์—๋Ÿฌ๊ฐ€ ๋‚˜๋ฉด ์ฆ‰์‹œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์ข…๋ฃŒ๋˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, ํ•ด๋‹น ๋ถ€๋ถ„๋ถ€ํ„ฐ ๋‹ค์‹œ ์ž…๋ ฅ๋ฐ›๋Š” ๊ฒƒ์ด์—ˆ๋‹ค. ์ฒ˜์Œ์—๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด while ๋ฃจํ”„๋ฅผ ์‚ฌ์šฉํ•ด ๋ฉ”์„œ๋“œ๋“ค์„ ์„ฑ๊ณต์ ์œผ๋กœ ํ†ต๊ณผํ•  ๋•Œ๊นŒ์ง€ ๊ณ„์† ์‹œ๋„ํ•˜๊ฒŒ ๋งŒ๋“ค์—ˆ๋‹ค. ์ฆ‰, ๋‘ ๋ฉ”์„œ๋“œ๊ฐ€ ์—๋Ÿฌ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค์ง€ ์•Š๊ณ  ์ •์ƒ์ ์œผ๋กœ ์™„๋ฃŒ๋˜๋ฉด, break ๋ฌธ์ด ์‹คํ–‰๋˜์–ด while (true) ๋ฃจํ”„๋ฅผ ์ข…๋ฃŒํ•˜๊ณ  start ํ•จ์ˆ˜๊ฐ€ ์™„๋ฃŒ๋˜๋„๋ก ํ–ˆ๋‹ค.

 

// ๋ฆฌํŒฉํ† ๋ง ์ „: while ๋ฃจํ”„ ์‚ฌ์šฉ

async start() {
    while (true) {
      try {
        await this.#initGame();
        await this.#runGame();
        break;
      } catch (error) {
        printMessage(error.message);
      }
    }
  };

 

๊ทธ๋Ÿฌ๋‹ค while๋ฌธ์˜ ๊ฐ€๋…์„ฑ์ด ๋–จ์–ด์งˆ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ, ์œ„์™€ ๊ฐ™์ด ์ž‘์„ฑํ–ˆ์„ ๋•Œ ESLint์˜ no-constant-condition๊ณผ no-await-in-loop ์กฐ๊ฑด์„ ์œ„๋ฐ˜ํ•˜๊ณ  ์žˆ์–ด์„œ ์•„๋ž˜์™€ ๊ฐ™์ด ์žฌ๊ท€๋กœ ๋ฐ”๊พธ์—ˆ๋‹ค.

 

// ๋ฆฌํŒฉํ† ๋ง ํ›„: catch ๋ธ”๋ก ๋‚ด์—์„œ startGame ํ•จ์ˆ˜๋Š” ์ž๊ธฐ ์ž์‹ ์„ ๋‹ค์‹œ ํ˜ธ์ถœ
// ์žฌ๊ท€ ํ˜ธ์ถœ์„ ํ†ตํ•ด ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•  ๋•Œ๋งˆ๋‹ค ๊ณ„์†ํ•ด์„œ ์ž๊ธฐ ์ž์‹ ์„ ํ˜ธ์ถœํ•˜์—ฌ ๊ฒŒ์ž„์„ ์ดˆ๊ธฐํ™”ํ•˜๊ณ  ์‹คํ–‰ํ•˜๋Š” ๊ณผ์ •์„ ๋ฐ˜๋ณต

async start() {
    const startGame = async () => {
      try {
        await this.#initGame();
        await this.#runGame();
      } catch (error) {
        printMessage(error.message);
        await startGame(); // ์žฌ๊ท€ ํ˜ธ์ถœ
      }
    }
    await startGame();
  };

 

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

 

2๏ธโƒฃ ๋ ˆ์ด์–ด๋“œ ์•„ํ‚คํ…์ฒ˜ ๋„์ž…

์ง€๋‚œ 2์ฃผ ์ฐจ์— ์ด์–ด ์ด๋ฒˆ์—๋„ MVC ํŒจํ„ด์„ ์ ์šฉํ•ด ๊ตฌํ˜„ํ•˜๊ณ  ์žˆ์—ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์–ด๋Š ์ •๋„ ๊ตฌํ˜„์„ ๋‹ค ํ•˜๊ณ  ๋ณด๋‹ˆ ์ปจํŠธ๋กค๋Ÿฌ์— ๋„ˆ๋ฌด ๋งŽ์ด ์—ญํ• ์ด ๋ถ€์—ฌ๋˜๊ณ , ๋ ˆ์ด์–ด๋ณ„ ์—ญํ•  ๊ตฌ๋ถ„์ด ๋ช…ํ™•ํ•˜์ง€ ์•Š์€ ๋Š๋‚Œ์ด์—ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์ค‘๊ฐ„์— ํ•˜๋‚˜์˜ ๋ ˆ์ด์–ด๋ฅผ ๋‘์–ด ์ผ๋ถ€ ์—ญํ• ์„ ๋ถ„๋ฆฌํ•ด๋„ ์ข‹์ง€ ์•Š์„๊นŒ ์ƒ๊ฐํ–ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‹ค ์ด๋Ÿฌํ•œ ๊ณ ๋ฏผ์— ์–ด๋Š ์ •๋„ ์‹ค๋งˆ๋ฆฌ๊ฐ€ ๋˜์–ด ์ค€ ๊ฒƒ์ด ๋ฐ”๋กœ ๋ ˆ์ด์–ด๋“œ ์•„ํ‚คํ…์ฒ˜(Layered Architecture)๋ผ๋Š” ๊ฒƒ์ด์—ˆ๋‹ค. (์ฐธ๊ณ : Layered Architecture @hgraca

 

Layered Architecture @herbertograca

 

 

๋ง์ด ๊ฑฐ์ฐฝํ•ด ๋ณด์ด์ง€๋งŒ, ์‰ฝ๊ฒŒ ๋งํ•˜์ž๋ฉด ๊ฐ ๊ณ„์ธต์„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋‚ด์—์„œ์˜ ํŠน์ • ์—ญํ• ๊ณผ ๊ด€์‹ฌ์‚ฌ(UI, ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ์ˆ˜ํ–‰, DB ์ž‘์—… ๋“ฑ) ๋ณ„๋กœ ๊ตฌ๋ถ„ํ•œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ๊ฐ€์žฅ ํฐ ํŠน์ง•์€ ๋ช…ํ™•ํ•˜๊ฒŒ ๊ด€์‹ฌ์‚ฌ๋ฅผ ๋ถ„๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์žฅ์ ์ด ์žˆ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

 

์ฆ‰, ํŠน์ • ๊ณ„์ธต์˜ ๊ตฌ์„ฑ ์š”์†Œ๋Š” ํ•ด๋‹น ๊ณ„์ธต์— ๊ด€๋ จ๋œ ๊ธฐ๋Šฅ๋งŒ ์ˆ˜ํ–‰ํ•˜๊ธฐ์— ๋†’์€ ์œ ์ง€๋ณด์ˆ˜์„ฑ๊ณผ ์‰ฌ์šด ํ…Œ์ŠคํŠธ๋ฅผ ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์žฅ์ ์ด ์žˆ๋‹ค. (์ฐธ๊ณ : ๊ณ„์ธตํ™” ์•„ํ‚คํ…์ฒ˜) ๊ทธ๋ž˜์„œ ์ด ์•„ํ‚คํ…์ฒ˜๋ผ๋ฉด ๊ฐ ๋ ˆ์ด์–ด๋ณ„๋กœ ์—ญํ• ๊ณผ ์ฑ…์ž„์ด ๋ช…ํ™•ํ•ด, ์ปจํŠธ๋กค๋Ÿฌ์˜ ์—ญํ• ์ด ๋„ˆ๋ฌด ๋งŽ์€ ๊ฒƒ ๊ฐ™๋‹ค๋Š” ๊ณ ๋ฏผ์„ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™์•˜๋‹ค.

 

๊ทธ๋ ‡๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด๊ฒฐํ–ˆ๋Š๋ƒ? ์•„๋ž˜์™€ ๊ฐ™์ด ์ปจํŠธ๋กค๋Ÿฌ ์ „์— ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ์ˆ˜ํ–‰ํ•˜๋Š” '์„œ๋น„์Šค ๋ชจ๋“ˆ'์„ ํ•˜๋‚˜ ๋” ๋‘๊ธฐ๋กœ ํ–ˆ๋‹ค.

๐Ÿ“‚ ์ปจํŠธ๋กค๋Ÿฌ ๋ชจ๋“ˆ
๐Ÿ“„ controller.js ๐Ÿ‘‰ ์ปจํŠธ๋กค๋Ÿฌ ์—ญํ• 

๐Ÿ“‚ ์„œ๋น„์Šค ๋ชจ๋“ˆ
๐Ÿ“„ LottoService.js ๐Ÿ‘‰ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง (๋‹น์ฒจ ํ†ต๊ณ„, ์ˆ˜์ต๋ฅ  ๊ณ„์‚ฐ ๋“ฑ) ์ˆ˜ํ–‰
๐Ÿ“„ BonusNumberValidator.js ๐Ÿ‘‰ ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ
๐Ÿ“„ LottoValidator.js ๐Ÿ‘‰ ๋กœ๋˜ ๋ฒˆํ˜ธ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ
๐Ÿ“„ MoneyValidator.js ๐Ÿ‘‰ ๊ตฌ์ž… ๊ธˆ์•ก ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ
๐Ÿ“„ WinningNumberValidator.js ๐Ÿ‘‰ ๋‹น์ฒจ ๋ฒˆํ˜ธ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ

 

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

 

ํ™•์ •๋œ ๊ตฌ์กฐ

 

์‚ฌ์‹ค ๋‚ด๊ฐ€ ์ ์šฉํ•œ Layered Architecture ์™ธ์—๋„ ์–ด๋‹ˆ์–ธ ์•„ํ‚คํ…์ฒ˜(Onion Architecture), ๋ผ์ž๋ƒ ์•„ํ‚คํ…์ฒ˜(Lasagna Architecture) ๋“ฑ๋“ฑ ์—ฌ๋Ÿฌ ์•„ํ‚คํ…์ฒ˜๊ฐ€ ์žˆ์—ˆ์ง€๋งŒ, ์ด๋ฒˆ ๋ฏธ์…˜์—์„œ๋Š” ์–ด๋–ค ์•„ํ‚คํ…์ฒ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ƒ๋Š” ๊ฒƒ์€ ๋ณธ์งˆ์ด ์•„๋‹ˆ์—ˆ๋‹ค. ๊ธฐ์กด MVC ํŒจํ„ด์„ ์‚ฌ์šฉํ•˜๋ฉฐ ์ปจํŠธ๋กค๋Ÿฌ๊ฐ€ ๊ฐ€์ง€๊ณ  ์žˆ๋˜ ํ•„์š” ์ด์ƒ์˜ ์—ญํ• ์„ ์—ฌ๋Ÿฌ ๋ ˆ์ด์–ด๋กœ ๋‚˜๋ˆ„๊ณ , ๊ฐ ๋ ˆ์ด์–ด๋ณ„๋กœ ๊ด€์‹ฌ์‚ฌ์™€ ์—ญํ• ์„ ๋ถ„๋ฆฌํ•˜๋Š” ๊ฒƒ์ด์—ˆ๋‹ค.

 

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

 

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

 

 

๐Ÿค” 3์ฃผ ์ฐจ ์•„์‰ฌ์šด ์ 

1๏ธโƒฃ ์‹œ๊ฐ„ ๋ถ„๋ฐฐ

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

 

2๏ธโƒฃ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ

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

 

 

โ˜•๏ธ 3์ฃผ ์ฐจ ์†Œ๊ฐ

1๏ธโƒฃ ์–ด๋ ต๊ณ , ํž˜๋“ค์—ˆ๋‹ค.

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

 

2๏ธโƒฃ ์œ„๊ธฐ๋ฅผ ๊ธฐํšŒ๋กœ

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

 

3๏ธโƒฃ  ์•„์‰ฌ์›€์€ ์„ฑ์žฅ์˜ ๊ธฐํšŒ๋กœ

์†Œ๊ฐ๋ฌธ์„ ์“ฐ๋ฉฐ ํ•œ ์ฃผ๋ฅผ ๋Œ์•„๋ณด๋‹ˆ, ์ด๊ฒƒ ๋˜ํ•œ ๊ณผ์ •์ด๊ณ  ์Šค์Šค๋กœ ํ•ด๋‚ธ ๊ฒƒ์— ํฐ ์„ฑ์ทจ๋ฅผ ๋Š๋‚€๋‹ค. ํŠนํžˆ ์ง€๋‚œ 2์ฃผ ์ฐจ ๋•Œ ์•„์‰ฌ์› ๋˜ ์ ์„ 3์ฃผ ์ฐจ์— ๋งŒํšŒํ•˜๊ฒ ๋‹ค๊ณ  ๋‹ค์งํ–ˆ๊ณ , ์ด๋ฅผ ์‹ค์ฒœํ•œ ๊ฒƒ์— ๋ฟŒ๋“ฏํ•จ์„ ๋Š๋ผ๊ณ  ์žˆ๋‹ค. ํ•˜์ง€๋งŒ 3์ฃผ ์ฐจ ํ”ผ๋“œ๋ฐฑ์„ ๋ฐ›์œผ๋ฉด ๋ถ„๋ช… ์•„์‰ฌ์šด ์ ์ด ๋งˆ๊ตฌ๋งˆ๊ตฌ ์ƒ๊ธธ ๊ฒƒ์ด๊ณ , ๋‚˜๋Š” ๋˜ ์„ฑ์žฅ์˜ ๊ธฐํšŒ๋ฅผ ์–ป์„ ๊ฒƒ์ด๋‹ค. ์ด๋ ‡๋“ฏ ์•ž์œผ๋กœ ์•„์‰ฌ์›€์„ ๋Š๋ผ๋ฉฐ ๋งค์ผ๋งค์ผ ์„ฑ์žฅํ•˜๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ ๋˜์ž. 

 

 

 

๋Œ“๊ธ€