ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์€ ์ง€๋‚œ ๋ช‡ ๋…„ ๋™์•ˆ ๋ˆˆ๋ถ€์‹œ๊ฒŒ ๋ฐœ์ „ํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ณผ๊ฑฐ์—๋Š” ๋‹จ์ˆœํžˆ <script> ํƒœ๊ทธ๋กœ JS ํŒŒ์ผ์„ ๋ถˆ๋Ÿฌ์˜ค๋ฉด ๋˜์—ˆ์ง€๋งŒ, ๊ทœ๋ชจ๊ฐ€ ์ปค์ง€๊ณ  ๋ชจ๋“ˆ ๋‹จ์œ„ ๊ฐœ๋ฐœ์ด ๋ณดํŽธํ™”๋˜๋ฉด์„œ โ€œ๋ชจ๋“ˆ ๋ฒˆ๋“ค๋Ÿฌ(Module Bundler)โ€๊ฐ€ ํ•„์ˆ˜ ๋„๊ตฌ๊ฐ€ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฒˆ ๊ธ€์—์„œ๋Š” ๋Œ€ํ‘œ์ ์ธ ๋ชจ๋“ˆ ๋ฒˆ๋“ค๋Ÿฌ์ธ Webpack, Rollup.js, ๊ทธ๋ฆฌ๊ณ  ์ฐจ์„ธ๋Œ€ ๋ฒˆ๋“ค๋ง ๋„๊ตฌ๋กœ ๊ฐ๊ด‘๋ฐ›๋Š” Vite์— ๋Œ€ํ•ด ๋น„๊ตํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.


1. ๋ชจ๋“ˆ ๋ฒˆ๋“ค๋Ÿฌ๋ž€

๋ชจ๋“ˆ ๋ฒˆ๋“ค๋Ÿฌ๋Š” ์—ฌ๋Ÿฌ ๊ฐœ์˜ JavaScript, CSS, ์ด๋ฏธ์ง€ ๋“ฑ์˜ ํŒŒ์ผ์„ ์˜์กด์„ฑ ๊ทธ๋ž˜ํ”„(Dependency Graph)๋กœ ๋ถ„์„ํ•ด ํ•˜๋‚˜์˜ ํŒŒ์ผ(๋˜๋Š” ์ตœ์ ํ™”๋œ ์—ฌ๋Ÿฌ ํŒŒ์ผ)๋กœ ๋ฌถ์–ด์ฃผ๋Š” ๋„๊ตฌ์ž…๋‹ˆ๋‹ค.

๋ชฉ์ : ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ํšจ์œจ์ ์œผ๋กœ ๋กœ๋“œํ•  ์ˆ˜ ์žˆ๋„๋ก ์ตœ์ ํ™”๋œ ๋ฒˆ๋“ค์„ ๋งŒ๋“ค์–ด์ฃผ๋Š” ๊ฒƒ.

์™œ ํ•„์š”ํ•œ๊ฐ€?

๐Ÿ‘€์†๋„ ๊ฐœ์„ : ํŒŒ์ผ์ด ๋งŽ์œผ๋ฉด ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ํ•˜๋‚˜์”ฉ ์š”์ฒญํ•ด์•ผ ํ•ด์„œ ๋А๋ ค์š”. ๋ฒˆ๋“ค๋Ÿฌ๊ฐ€ ํŒŒ์ผ์„ ํ•ฉ์ณ์„œ ์š”์ฒญ์„ ์ค„์—ฌ์ค๋‹ˆ๋‹ค.
๐Ÿ‘€์ตœ์ ํ™”: ์“ฐ์ด์ง€ ์•Š๋Š” ์ฝ”๋“œ๋ฅผ ์ œ๊ฑฐ(ํŠธ๋ฆฌ ์‰์ดํ‚น)ํ•˜๊ฑฐ๋‚˜, ์ฝ”๋“œ๋ฅผ ์••์ถ•ํ•ด ์šฉ๋Ÿ‰์„ ์ค„์—ฌ์ค๋‹ˆ๋‹ค.
๐Ÿ‘€๊ฐœ๋ฐœ ํŽธ์˜์„ฑ: ์ตœ์‹  ๋ฌธ๋ฒ•(ES6, TypeScript ๋“ฑ)์„ ๊ตฌ๋ฒ„์ „ ๋ธŒ๋ผ์šฐ์ €์—์„œ๋„ ์“ธ ์ˆ˜ ์žˆ๋„๋ก ๋ณ€ํ™˜ํ•ด ์ค๋‹ˆ๋‹ค.


2. ์ฃผ์š” ๋ชจ๋“ˆ ๋ฒˆ๋“ค๋Ÿฌ

์ด์ œ ๋งŽ์ด ์“ฐ์ด๋Š” 3๊ฐ€์ง€ ๋„๊ตฌ๋ฅผ ๋น„๊ตํ•ด๋ณผ๊ฒŒ์š”

Webpack

๊ฐ€์žฅ ์œ ๋ช…ํ•˜๊ณ  ์˜ค๋ž˜๋œ ๋ฒˆ๋“ค๋Ÿฌ
์„ค์ •์ด ๊ฐ•๋ ฅํ•˜์ง€๋งŒ ๋ณต์žกํ•˜๋‹ค๋Š” ๋‹จ์ ์ด ์žˆ๋‹ค
entry โ†’ loader โ†’ plugin โ†’ output ๊ตฌ์กฐ๋กœ ๋™์ž‘.

๋Œ€๊ทœ๋ชจ ํ”„๋กœ์ ํŠธ์—์„œ ์•ˆ์ •์ ์ด๊ณ  ํ™•์žฅ์„ฑ์ด ๋†’์Šต๋‹ˆ๋‹ค.

์˜ˆ์‹œ
React, Vue ๊ฐ™์€ ํ”„๋ ˆ์ž„์›Œํฌ์˜ ๊ธฐ๋ณธ ๋ฒˆ๋“ค๋Ÿฌ๋กœ ๋งŽ์ด ์“ฐ์˜€์Šต๋‹ˆ๋‹ค.
๋ณต์žกํ•œ ๋นŒ๋“œ(์ด๋ฏธ์ง€, CSS, JS, TS ๋‹ค ํ•ฉ์น˜๊ธฐ)์— ์œ ๋ฆฌ.

Rollup.js

๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ œ์ž‘์— ๊ฐ•์ .
Webpack๋ณด๋‹ค ๋‹จ์ˆœํ•˜๊ณ  ๊ฐ€๋ณ์Šต๋‹ˆ๋‹ค.
ํŠธ๋ฆฌ ์‰์ดํ‚น(tree shaking) ๊ธฐ๋Šฅ์ด ๊ฐ•๋ ฅํ•ด์„œ, ์“ฐ์ง€ ์•Š๋Š” ์ฝ”๋“œ๊ฐ€ ๊ฑฐ์˜ ๋‚จ์ง€ ์•Š์•„์š”.

์˜ˆ์‹œ:
Lodash, D3.js ๊ฐ™์€ ์œ ๋ช…ํ•œ JS ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋„ Rollup์œผ๋กœ ๋นŒ๋“œ๋ฉ๋‹ˆ๋‹ค.
๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ œ์ž‘ํ•  ๋•Œ๋Š” Webpack๋ณด๋‹ค Rollup์ด ๋” ์„ ํ˜ธ๋ฉ๋‹ˆ๋‹ค.


Vite

์ฐจ์„ธ๋Œ€ ๋ฒˆ๋“ค๋Ÿฌ๋กœ, ์ตœ๊ทผ ๊ฐ€์žฅ ํ•ซํ•ฉ๋‹ˆ๋‹ค.

๋‚ด๋ถ€์ ์œผ๋กœ Rollup์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜์ง€๋งŒ, ๊ฐœ๋ฐœ ์„œ๋ฒ„๋Š” ESBuild(Go ์–ธ์–ด๋กœ ๋งŒ๋“  ์ดˆ๊ณ ์† ๋ฒˆ๋“ค๋Ÿฌ)๋ฅผ ์‚ฌ์šฉ


๐Ÿ”ด์žฅ์ : ๊ฐœ๋ฐœ ์„œ๋ฒ„ ์†๋„๊ฐ€ ์—„์ฒญ ๋น ๋ฆ„ (๋ณ€๊ฒฝ๋œ ๋ถ€๋ถ„๋งŒ ์ฆ‰์‹œ ๋ฐ˜์˜ โ†’ HMR)

๐Ÿ”ด๋‹จ์ : ์•„์ง์€ Webpack๋งŒํผ ํ”Œ๋Ÿฌ๊ทธ์ธ ์ƒํƒœ๊ณ„๊ฐ€ ๋ฐฉ๋Œ€ํ•˜์ง€ ์•Š์Œ


์˜ˆ์‹œ:
Vue 3, React ์ตœ์‹  ํ…œํ”Œ๋ฆฟ์—์„œ ๊ธฐ๋ณธ ๋นŒ๋“œ ๋„๊ตฌ๋กœ ์ฑ„ํƒ๋จ
์Šคํƒ€ํŠธ์—…์ด๋‚˜ ๊ฐœ์ธ ํ”„๋กœ์ ํŠธ์—์„œ ๋น ๋ฅด๊ฒŒ ๊ฐœ๋ฐœํ•  ๋•Œ ์ตœ์ 


ํšŒ์‚ฌ์—์„œ๋„ ๊ธฐ์กด์— React + Webpack ๊ธฐ๋ฐ˜์œผ๋กœ ์šด์˜ํ•˜๋˜ ์„œ๋น„์Šค๋ฅผ Vite๋กœ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ํ•œ ๊ฒฝํ—˜์ด ์žˆ์Šต๋‹ˆ๋‹ค. ํ”„๋กœ์ ํŠธ๊ฐ€ ๋ฌด๊ฑฐ์›Œ์ง€๋ฉด์„œ Webpack ํ™˜๊ฒฝ์—์„œ ๋นŒ๋“œ ์†๋„๊ฐ€ ์˜ค๋ž˜๊ฑธ๋ ค ์ดˆ๊ธฐ ๊ฐœ๋ฐœ ์„œ๋ฒ„๋ฅผ ์‹œ์ž‘ํ•˜๋Š”๋ฐ์— 10๋ถ„ ์ •๋„๊ฐ€ ๊ฑธ๋ฆฌ๋Š” ์•„์ฃผ ํž˜๋“  ์ƒํ™ฉ์ด ์ƒ๊ฒจ๋ฒ„๋ฆฐ๊ฑฐ์ฃ ! HMR ์†๋„๋„ ๊ฐœ์„ ํ•˜๊ธฐ ์œ„ํ•จ๊ณผ ์ตœ์‹  ์ƒํƒœ๊ณ„์™€ ํ˜ธํ™˜์„ฑ์„ ๊ณ ๋ คํ•ด์„œ ๋…ผ์˜ ๊ฒฐ๊ณผ vite๋กœ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ํ•˜๊ธฐ๋กœ ๊ฒฐ์ •์„ ํ–ˆ์Šต๋‹ˆ๋‹ค



๊ทธ ๊ฒฐ๊ณผ, ๊ฐœ๋ฐœ ์„œ๋ฒ„ ๊ตฌ๋™ ์†๋„๊ฐ€ 1๋ถ„ ๋ฏธ๋งŒ์œผ๋กœ ๋‹จ์ถ•, HMR์†๋„๋Š” ๋งํ•  ๊ฒƒ๋„ ์—†์ด ํ˜„์ €ํžˆ ๋นจ๋ผ์กŒ์Šต๋‹ˆ๋‹ค.

๊ฒฐ๋ก ์ ์œผ๋กœ, Vite๋Š” Webpack ๋Œ€๋น„ ํ›จ์”ฌ ๊ฐ€๋ณ๊ณ  ๋น ๋ฅธ ๊ฐœ๋ฐœ ๊ฒฝํ—˜์„ ์ œ๊ณตํ–ˆ๊ณ , ํŒ€์˜ ์ƒ์‚ฐ์„ฑ์—๋„ ๊ธ์ •์ ์ธ ํšจ๊ณผ๋ฅผ ์คฌ์Šต๋‹ˆ๋‹ค.


https://www.felgus.dev/blog/future-spa



์ตœ๊ทผ ํ”„๋ก ํŠธ์—”๋“œ ์ƒํƒœ๊ณ„์—์„œ ๊ฐ€์žฅ ๋œจ๊ฑฐ์šด ์ฃผ์ œ ์ค‘ ํ•˜๋‚˜๋Š” ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ(Server Components) ์™€ ์„œ๋ฒ„ ๋ Œ๋”๋ง์ž…๋‹ˆ๋‹ค. Next.js์™€ ๊ฐ™์€ ๋ฉ”ํƒ€ ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ๊ฐ๊ด‘๋ฐ›์œผ๋ฉด์„œ โ€œSPA๋Š” ์ด์ œ ๋’ค์ณ์ง€๋Š” ๊ฒŒ ์•„๋‹๊นŒ?โ€๋ผ๋Š” ๋…ผ์˜๋„ ์ž์ฃผ ๋“ฑ์žฅํ•˜์ฃ .


ํ•˜์ง€๋งŒ ๋‹จ์ˆœํ•œ SPA(Single Page Application), ์ฆ‰ ์ •์  HTML๊ณผ JS ํŒŒ์ผ ํ•˜๋‚˜๋กœ ์‹œ์ž‘ํ•˜๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๋„ ์—ฌ์ „ํžˆ ๊ฐ•๋ ฅํ•œ ๊ฒฝ์Ÿ๋ ฅ์„ ๊ฐ€์ง‘๋‹ˆ๋‹ค. ์˜คํžˆ๋ ค ์ƒˆ๋กœ์šด React ๊ธฐ๋Šฅ๋“ค์„ ์ ์ ˆํžˆ ํ™œ์šฉํ•˜๋ฉด ๊ธฐ์กด SPA์˜ ํ•œ๊ณ„๋ฅผ ๊ทน๋ณตํ•˜๊ณ  ํ›จ์”ฌ ๋งค๋„๋Ÿฌ์šด ์‚ฌ์šฉ์ž ๊ฒฝํ—˜(UX)์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ๊ธ€์—์„œ๋Š” SPA์—์„œ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ตœ์‹  ์ „๋žต๋“ค์„ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

1. Render-on-Fetch์—์„œ Render-as-You-Fetch๋กœ


์ „ํ†ต์ ์ธ SPA๋Š” ๋ณดํ†ต ๋‹ค์Œ ๋‹จ๊ณ„๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค:

1. HTML ์š”์ฒญ
2. JS ๋‹ค์šด๋กœ๋“œ ํ›„ React ์ดˆ๊ธฐํ™”
3. ์ปดํฌ๋„ŒํŠธ ๋ Œ๋”๋ง ์‹œ์ž‘
4. ์ปดํฌ๋„ŒํŠธ ์•ˆ์—์„œ fetch ํ˜ธ์ถœ
5. Suspense fallback UI ํ‘œ์‹œ
6. ์‘๋‹ต ๋„์ฐฉ ํ›„ ์‹ค์ œ UI ๋ Œ๋”๋ง

์ด ๋ฐฉ์‹์€ ๋‹จ์ˆœํ•˜์ง€๋งŒ ๋„คํŠธ์›Œํฌ ์›Œํ„ฐํด์ด ์ƒ๊ธฐ๋ฉฐ UI ํ‘œ์‹œ๊ฐ€ ์ง€์—ฐ๋ฉ๋‹ˆ๋‹ค.

๋ฐ˜๋ฉด Render-as-You-Fetch ํŒจํ„ด์„ ์‚ฌ์šฉํ•˜๋ฉด ์ปดํฌ๋„ŒํŠธ ๋ Œ๋”๋ง ์ง์ „์— ๋ผ์šฐํŠธ ๋กœ๋”(Route Loader) ๋ฅผ ์‹คํ–‰ํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ๋” ๋นจ๋ฆฌ ์š”์ฒญํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


์ฆ‰, ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๊ณผ์ •๊ณผ UI ๋ Œ๋”๋ง์„ ๋งž๋ฌผ๋ ค ๋™์‹œ์— ์ง„ํ–‰ํ•˜๋ฏ€๋กœ ์ดˆ๊ธฐ ๋ฐ˜์‘ ์†๋„๊ฐ€ ๊ฐœ์„ ๋ฉ๋‹ˆ๋‹ค.

โ†’ React Router v7, Tanstack Router ๊ฐ™์€ ์ตœ์‹  ๋ผ์šฐํ„ฐ๊ฐ€ ์ด ํŒจํ„ด์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

2. ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์˜ ์ •์  ํ™œ์šฉ

์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋Š” ์ด๋ฆ„ ๊ทธ๋Œ€๋กœ ์„œ๋ฒ„์—์„œ ๋ Œ๋”๋งํ•ด์•ผ ํ•  ๊ฒƒ์ฒ˜๋Ÿผ ๋“ค๋ฆฌ์ง€๋งŒ, ๊ผญ ๊ทธ๋ ‡์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค.

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

3. Concurrent Features: ๋” ๋งค๋„๋Ÿฌ์šด ์ธํ„ฐ๋ž™์…˜


React 18์—์„œ ๋„์ž…๋œ useTransition, useDeferredValue ๊ฐ™์€ ๋™์‹œ์„ฑ ๊ธฐ๋Šฅ์€ ๋‹จ์ˆœํžˆ โ€œ๋Œ€ํ˜• ์„œ๋น„์Šค ์ „์šฉโ€์ด ์•„๋‹™๋‹ˆ๋‹ค.
ํ”„๋ก ํŠธ์—”๋“œ์—์„œ์˜ ๊ทœ๋ชจ(scale) ๋Š” ์‚ฌ์šฉ์ž ์ˆ˜๊ฐ€ ์•„๋‹ˆ๋ผ โ€œํŽ˜์ด์ง€, ์ƒํ˜ธ์ž‘์šฉ, ์ •๋ณด ํ๋ฆ„์˜ ๋ณต์žก๋„โ€๋กœ ์ •์˜๋ฉ๋‹ˆ๋‹ค.
SPA์—์„œ๋„ ์‚ฌ์šฉ์ž๋Š” ์•„๋ฌด ๋•Œ๋‚˜ ๋‹ค์–‘ํ•œ ์ธํ„ฐ๋ž™์…˜์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ์—…๋ฐ์ดํŠธ์˜ ์šฐ์„ ์ˆœ์œ„๋ฅผ ๋ช…ํ™•ํžˆ ์ง€์ •ํ•˜์ง€ ์•Š์œผ๋ฉด UX๊ฐ€ ์‰ฝ๊ฒŒ ๋Š๊ธฐ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

๋™์‹œ์„ฑ ๊ธฐ๋Šฅ์„ ํ™œ์šฉํ•˜๋ฉด React๊ฐ€ ๋†’์€ ์šฐ์„ ์ˆœ์œ„ ์ž‘์—…๋ถ€ํ„ฐ ์ฒ˜๋ฆฌํ•˜๋„๋ก ์ง€์‹œํ•  ์ˆ˜ ์žˆ๊ณ , ๊ทธ ๊ฒฐ๊ณผ ๋” ๋ถ€๋“œ๋Ÿฌ์šด ํ™”๋ฉด ์ „ํ™˜๊ณผ ๋ฐ˜์‘์„ฑ์„ ํ™•๋ณดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

4. Preload๋ฅผ ํ†ตํ•œ ์„ ์ œ์  ์‚ฌ์šฉ์ž ๊ฒฝํ—˜

์ฝ”๋“œ ์Šคํ”Œ๋ฆฌํŒ…๊ณผ ์ง€์—ฐ ๋กœ๋”ฉ์€ ์ด๋ฏธ ํ”ํ•œ ๊ธฐ๋ฒ•์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์—ฌ๊ธฐ์„œ ๋” ๋‚˜์•„๊ฐ€ SPA ๋ผ์šฐํ„ฐ์˜ Link ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ™œ์šฉํ•˜๋ฉด ์„ฑ๋Šฅ์„ ๋˜ ํ•œ ๋‹จ๊ณ„ ๊ฐœ์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, ์‚ฌ์šฉ์ž๊ฐ€ ํŠน์ • ๋งํฌ ์œ„์— ๋งˆ์šฐ์Šค๋ฅผ ์˜ฌ๋ ค๋†“์€ ์ˆœ๊ฐ„, ๋ผ์šฐํ„ฐ๊ฐ€ ํ•ด๋‹น ํŽ˜์ด์ง€์˜ ๋ฐ์ดํ„ฐ์™€ ์ฝ”๋“œ ์Šคํ”Œ๋ฆฟ๋œ JS๋ฅผ ๋ฏธ๋ฆฌ ์š”์ฒญํ•˜๋„๋ก ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์‹ค์ œ ํŽ˜์ด์ง€ ์ „ํ™˜ ์‹œ ์ด๋ฏธ ์ค€๋น„๋œ ์ฝ˜ํ…์ธ ๊ฐ€ ์ฆ‰์‹œ ํ‘œ์‹œ๋˜์–ด, ๋งˆ์น˜ ๋„ค์ดํ‹ฐ๋ธŒ ์•ฑ์ฒ˜๋Ÿผ ๋ฐ˜์‘ํ•˜๋Š” UX๋ฅผ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

5. React Labs์˜ ์‹ ๊ธฐ๋Šฅ: ViewTransition & Activity

React ํŒ€์ด ๋ฐœํ‘œํ•œ ์‹คํ—˜์  ๊ธฐ๋Šฅ ์ค‘ ๋‘ ๊ฐ€์ง€๊ฐ€ SPA UX์— ํŠนํžˆ ์ฃผ๋ชฉํ•  ๋งŒํ•ฉ๋‹ˆ๋‹ค:
โ€ข ViewTransitionโ€จ์ƒˆ๋กœ์šด ์›น ํ‘œ์ค€์œผ๋กœ, ํŽ˜์ด์ง€ ์ „ํ™˜ ์‹œ ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ๋” ๋ถ€๋“œ๋Ÿฝ๊ฒŒ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก React์™€ ๋ธŒ๋ผ์šฐ์ € API ๊ฐ„์˜ ๊ฐ„๊ทน์„ ๋ฉ”์›Œ์ค๋‹ˆ๋‹ค.โ€จโ†’ ๊ฒฐ๊ณผ์ ์œผ๋กœ ํ™”๋ฉด ์ „ํ™˜ ๊ฒฝํ—˜์ด ํ›จ์”ฌ ์ž์—ฐ์Šค๋Ÿฌ์›Œ์ง‘๋‹ˆ๋‹ค.
โ€ข Activity (๊ตฌ Offscreen)โ€จ๋ Œ๋”๋ง๊ณผ ์ปค๋ฐ‹ ๊ณผ์ • ์‚ฌ์ด์— โ€œ๋ฏธ๋ฆฌ UI ์Šค๋ƒ…์ƒท์„ ์ค€๋น„ํ•ด๋‘๋Š”โ€ ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค.
โ€จ์ฆ‰, ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ณด์ด์ง€ ์•Š๋Š” ์ƒํƒœ๋กœ ๋ Œ๋”๋งํ•ด๋‘” ๋’ค, ํ•„์š”ํ•  ๋•Œ ์ฆ‰์‹œ ํ™”๋ฉด์— ์ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.โ€จโ†’ ์ „ํ™˜ ์‹œ์ ์—์„œ ๊ธฐ๋‹ค๋ฆผ ์—†์ด ๊ณง๋ฐ”๋กœ ์ƒˆ๋กœ์šด ํ™”๋ฉด์„ ๋ณด์—ฌ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ๊ธฐ๋Šฅ์„ Preload ์ „๋žต๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋ฉด, ํŽ˜์ด์ง€ ์ „ํ™˜ ์†๋„ ๋ฐ ์—ฐ์†์„ฑ์ด ๋Œ€ํญ ๊ฐœ์„ ๋ฉ๋‹ˆ๋‹ค.

๊ฒฐ๋ก : SPA๋Š” ๋” ๋ถ€๋“œ๋Ÿฝ๊ฒŒ, ๋” ๋น ๋ฅด๊ฒŒ
SPA๊ฐ€ ์„œ๋ฒ„ ๋ Œ๋”๋ง ํ”„๋ ˆ์ž„์›Œํฌ์— ๋ฐ€๋ ค ์‚ฌ๋ผ์งˆ ๊ฑฐ๋ผ๊ณ  ์ƒ๊ฐํ•˜๊ธฐ ์‰ฝ์ง€๋งŒ, ์˜คํžˆ๋ ค ๋ฐ˜๋Œ€์ž…๋‹ˆ๋‹ค.
โ€ข Render-as-you-fetch ํŒจํ„ด
โ€ข Server Component์˜ ์ •์  ํ™œ์šฉ
โ€ข Concurrent Features๋กœ ๋ถ€๋“œ๋Ÿฌ์šด ์ธํ„ฐ๋ž™์…˜
โ€ข Preload & Activity & ViewTransition์œผ๋กœ ๋„ค์ดํ‹ฐ๋ธŒ ๊ฐ™์€ ์ „ํ™˜ ๊ฒฝํ—˜

์ด ์ „๋žต๋“ค์„ ๊ฒฐํ•ฉํ•˜๋ฉด SPA๋Š” ์ง€๊ธˆ๋ณด๋‹ค ํ›จ์”ฌ ๊ฐ•๋ ฅํ•˜๊ณ  ์„ธ๋ จ๋œ UX๋ฅผ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿ“Œ ์ฆ‰, SPA์˜ ๋ฏธ๋ž˜๋Š” ์„ฑ๋Šฅ๊ณผ UX๋ฅผ ๋ชจ๋‘ ๊ฐ–์ถ˜ โ€œ๋” ๋˜‘๋˜‘ํ•œ ํด๋ผ์ด์–ธํŠธ ์‚ฌ์ด๋“œ ๋ Œ๋”๋งโ€์ž…๋‹ˆ๋‹ค.

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



์ด๋ฅผ ์œ„ํ•ด ๋‹ค์–‘ํ•œ ์ƒํƒœ๊ด€๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์กด์žฌํ•˜๋ฉฐ, ๋Œ€ํ‘œ์ ์œผ๋กœ Redux, Recoil, MobX ๋“ฑ์ด ์žˆ๋‹ค. ์ตœ๊ทผ์—๋Š” ๋ณด๋‹ค ๋‹จ์ˆœํ•˜๊ณ  ๊ฐ€๋ฒผ์šด ์ ‘๊ทผ ๋ฐฉ์‹์„ ์ œ๊ณตํ•˜๋Š” Zustand๊ฐ€ ์ฃผ๋ชฉ๋ฐ›๊ณ  ์žˆ๋‹ค.


 

1. Zustand๋ž€ ๋ฌด์—‡์ธ๊ฐ€


https://zustand-demo.pmnd.rs/

 

Zustand

 

zustand-demo.pmnd.rs

 

 

 


Zustand์˜ ๊ณต์‹๋ฌธ์„œ์ด๋‹ค.
๊ณต์‹๋ฌธ์„œ์— ๋”ฐ๋ฅด๋ฉด,

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

๊ท€์—ฝ๋‹ค๊ณ  ๋ฌด์‹œํ•˜์ง€ ๋งˆ์„ธ์š”. ๋ฐœํ†ฑ์ด ์žˆ์Šต๋‹ˆ๋‹ค!
๋งŽ์€ ์‹œ๊ฐ„์„ ๋“ค์—ฌ ํ”ํžˆ ๊ฒช๋Š” ๋ฌธ์ œ๋“ค์„ ํ•ด๊ฒฐํ–ˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์•…๋ช… ๋†’์€ ์ข€๋น„ ์ž์‹(zombie child) ๋ฌธ์ œ, React์˜ ๋™์‹œ์„ฑ(concurrency), ์„œ๋กœ ๋‹ค๋ฅธ ๋ Œ๋”๋Ÿฌ ๊ฐ„์˜ ์ปจํ…์ŠคํŠธ ์†์‹ค(context loss) ๋“ฑ์„ ๋‹ค๋ฃน๋‹ˆ๋‹ค.
React ์ƒํƒœ๊ณ„์—์„œ ์ด๋Ÿฌํ•œ ๋ชจ๋“  ๋ฌธ์ œ๋ฅผ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฑฐ์˜ ์œ ์ผํ•œ ์ƒํƒœ ๊ด€๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ผ์ง€๋„ ๋ชจ๋ฆ…๋‹ˆ๋‹ค.


๋ผ๊ณ  ํ•œ๋‹ค.

โœ”๏ธ์ข…ํ•ฉํ•ด๋ณด๋ฉด


1. Zustand๋Š” ํ•ต์‹ฌ ๊ธฐ๋Šฅ๋งŒ ์ œ๊ณตํ•˜๋Š” ๊ฐ€๋ฒผ์šด ์ƒํƒœ ๊ด€๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

2. Redux์ฒ˜๋Ÿผ ๋ณต์žกํ•œ ์„ค์ •์ด๋‚˜ ํŒŒ์ผ ๊ตฌ์กฐ ์—†์ด๋„ ์“ธ ์ˆ˜ ์žˆ๊ณ , ํ”„๋กœ์ ํŠธ ๊ทœ๋ชจ๊ฐ€ ์ปค์ ธ๋„ ๋ฌด๋ฆฌ ์—†์ด ํ™•์žฅํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์žฅ์ 

3. React์˜ useState, useEffect ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ์‰ฝ๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์˜๋ฏธ

4. ๋ณต์žกํ•œ action, reducer, dispatch ๊ฐ™์€ ๊ฐœ๋…์„ ๊ฐ•์ œ๋กœ ์“ฐ๊ฒŒ ํ•˜์ง€ ์•Š์•„์„œ ์ง„์ž… ์žฅ๋ฒฝ์ด ๋‚ฎ์Œ

5. ํŠน์ • ํŒจํ„ด์„ ๊ฐ•์ œํ•˜์ง€ ์•Š์ง€๋งŒ, Flux ์•„ํ‚คํ…์ฒ˜์ฒ˜๋Ÿผ ๋ฐ์ดํ„ฐ ํ๋ฆ„์ด ๋‹จ๋ฐฉํ–ฅ์ด๋ผ ๊ตฌ์กฐ๊ฐ€ ๋ช…ํ™•ํ•ฉ๋‹ˆ๋‹ค.

6. ์ข€๋น„ ์ž์‹ ๋ฌธ์ œ(zombie child problem)
→ ์ƒํƒœ๊ฐ€ ์—…๋ฐ์ดํŠธ๋๋Š”๋ฐ ์ด๋ฏธ ์–ธ๋งˆ์šดํŠธ๋œ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์˜› ๋ฐ์ดํ„ฐ๋ฅผ ์ฐธ์กฐํ•˜๋Š” ๋ฒ„๊ทธ๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

7. React ๋™์‹œ์„ฑ(Concurrency)
→ React 18์˜ concurrent mode์—์„œ๋„ ์ƒํƒœ ๊ด€๋ฆฌ๊ฐ€ ์•ˆ์ „ํ•˜๊ฒŒ ๋™์ž‘ํ•˜๋„๋ก ์„ค๊ณ„๋จ.

8. ์ปจํ…์ŠคํŠธ ์†์‹ค(Context loss)
→ React Native, Web, Three.js ๊ฐ™์ด ๋ Œ๋”๋Ÿฌ๊ฐ€ ํ˜ผํ•ฉ๋œ ํ™˜๊ฒฝ์—์„œ๋„ ์ƒํƒœ๋ฅผ ์•ˆ์ „ํ•˜๊ฒŒ ๊ณต์œ  ๊ฐ€๋Šฅ.


์š”์•ฝ: Zustand๋Š” ๋‹จ์ˆœํ•˜์ง€๋งŒ ๊นŠ์ด ์žˆ๋Š” ์ƒํƒœ ๊ด€๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๊ณ , React์—์„œ ๋ฐœ์ƒํ•˜๋Š” ๊นŒ๋‹ค๋กœ์šด ๋ฒ„๊ทธ ์ƒํ™ฉ๋„ ๋Œ€๋ถ€๋ถ„ ํ•ด๊ฒฐํ•ด์ฃผ๋Š” ๊ฑฐ์˜ ์œ ์ผํ•œ ์„ ํƒ์ง€์ด๋‹ค



2. ๊ธฐ๋ณธ์‚ฌ์šฉ๋ฐฉ๋ฒ•

 

import { create } from 'zustand'

const useStore = create((set) => ({
  bears: 0,
  increasePopulation: () => set((state) => ({ bears: state.bears + 1 })),
  removeAllBears: () => set({ bears: 0 }),
  updateBears: (newBears) => set({ bears: newBears }),
}))

 

function BearCounter() {
  const bears = useStore((state) => state.bears)
  return <h1>{bears} bears around here...</h1>
}

function Controls() {
  const increasePopulation = useStore((state) => state.increasePopulation)
  return <button onClick={increasePopulation}>one up</button>
}

 

1. create()
• Zustand ์Šคํ† ์–ด๋ฅผ ๋งŒ๋“œ๋Š” ์ตœ์ดˆ ํ•จ์ˆ˜.
• ์ธ์ž๋กœ ์ „๋‹ฌํ•˜๋Š” ํ•จ์ˆ˜ ์•ˆ์—์„œ ์ƒํƒœ(state)์™€ ์ƒํƒœ ๋ณ€๊ฒฝ ๋กœ์ง(setter)์„ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.


2. set()
• ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ํ•จ์ˆ˜.
• ๋ถ€๋ถ„ ์—…๋ฐ์ดํŠธ ๊ฐ€๋Šฅ(merge ๋™์ž‘).

3. get()
• ์Šคํ† ์–ด์˜ ํ˜„์žฌ ์ƒํƒœ๋ฅผ ์ฆ‰์‹œ ์ฝ๋Š” ํ•จ์ˆ˜.
• React ํ›… ์—†์ด๋„ ์™ธ๋ถ€์—์„œ ์ƒํƒœ๋ฅผ ์ฝ์„ ์ˆ˜ ์žˆ์Œ.

4. subscribe()
• ํŠน์ • ์ƒํƒœ ๋ณ€ํ™”์— ๋Œ€ํ•ด ๋ฆฌ์Šค๋„ˆ ๋“ฑ๋ก.
• React ์ปดํฌ๋„ŒํŠธ ๋ฐ”๊นฅ์—์„œ๋„ ์ƒํƒœ ๋ณ€ํ™”๋ฅผ ๊ฐ์ง€ ๊ฐ€๋Šฅ.

const unsubscribe = useStore.subscribe(state => {
  console.log('count changed:', state.count);
});

unsubscribe(); // ๊ตฌ๋… ํ•ด์ œ

 

 

 

๋‹ค๋ฅธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค๊ณผ์˜ ์ฐจ์ด์  (Zustand vs ๋‹ค๋ฅธ ์ƒํƒœ๊ด€๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋น„๊ต)

 

  Zustand Redux Recoil Jotai
์ฒ ํ•™ ์ตœ์†Œํ•œ์˜ API, ๊ฐœ๋ฐœ์ž๊ฐ€ ์ง์ ‘ ํŒจํ„ด ์„ค๊ณ„ Flux ์•„ํ‚คํ…์ฒ˜ ๊ธฐ๋ฐ˜, ๊ฐ•๋ ฅํ•œ ๊ทœ์น™๊ณผ ๋ณด์ผ๋Ÿฌํ”Œ๋ ˆ์ดํŠธ React ์ƒํƒœ๋ฅผ ์ „์—ญ์ ์œผ๋กœ ๋‹ค๋ฃจ๋Š” Declarative ๋ชจ๋ธ ์›์ž(atom) ๋‹จ์œ„๋กœ ์ƒํƒœ ๊ด€๋ฆฌ, React Hooks ์นœํ™”์ 
๋ณด์ผ๋Ÿฌํ”Œ๋ ˆ์ดํŠธ ๊ฑฐ์˜ ์—†์Œ ๋งŽ์Œ(์•ก์…˜, ๋ฆฌ๋“€์„œ, ์Šคํ† ์–ด ์„ค์ • ๋“ฑ) ์ ์Œ ๊ฑฐ์˜ ์—†์Œ
ํ•™์Šต ๊ณก์„  ๋‚ฎ์Œ ์ค‘๊ฐ„~๋†’์Œ ์ค‘๊ฐ„ ๋‚ฎ์Œ
๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ ์ž์œ ๋กญ๊ฒŒ ๊ตฌํ˜„(๋ฏธ๋“ค์›จ์–ด ํŒจํ„ด ์•„๋‹˜) ๋ฏธ๋“ค์›จ์–ด(thunk, saga ๋“ฑ) ํ•„์š” Suspense ๊ธฐ๋ฐ˜ ๋น„๋™๊ธฐ ์ง€์› Suspense ๊ธฐ๋ฐ˜ ๋น„๋™๊ธฐ ์ง€์›
๋ฆฌ๋ Œ๋”๋ง ์ œ์–ด selector ๊ธฐ๋ฐ˜์œผ๋กœ ์ปดํฌ๋„ŒํŠธ ๋ฆฌ๋ Œ๋” ์ตœ์†Œํ™” connect ๋˜๋Š” hooks์—์„œ memoization ํ•„์š” ํŒŒํŽธํ™”๋œ atom ๋‹จ์œ„๋กœ ์ตœ์†Œํ™” atom ๋‹จ์œ„๋กœ ์ตœ์†Œํ™”
React ์˜์กด์„ฑ ๋‚ฎ์Œ(React ์—†์ด๋„ ์‚ฌ์šฉ ๊ฐ€๋Šฅ) ๋†’์Œ ๋†’์Œ ๋†’์Œ
์Šคํ† ์–ด ๊ตฌ์กฐ ๋‹จ์ผ ์Šคํ† ์–ด or ๋‹ค์ค‘ ์Šคํ† ์–ด ๋ชจ๋‘ ๊ฐ€๋Šฅ ์ฃผ๋กœ ๋‹จ์ผ ์Šคํ† ์–ด atom๋“ค์˜ ์ง‘ํ•ฉ atom๋“ค์˜ ์ง‘ํ•ฉ
SSR ์ง€์› ์‰ฌ์›€ ์‰ฌ์›€ ์ผ๋ถ€ ์ผ€์ด์Šค ๊ณ ๋ ค ํ•„์š” ์‰ฌ์›€

 

์šฐ๋ฆฌ ํŒ€์€ ํ˜„์žฌ ์ƒํƒœ๊ด€๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ๊ณผ๋„๊ธฐ๋ฅผ ๊ฒช๊ณ  ์žˆ๋‹ค.
๊ณผ๊ฑฐ ํ”„๋กœ์ ํŠธ ์š”๊ตฌ์‚ฌํ•ญ๊ณผ ํŒ€์›์˜ ์„ ํ˜ธ๋„ ์ฐจ์ด๋กœ ์ธํ•ด Jotai, Redux, Recoil์ด ํ˜ผํ•ฉ๋œ ๊ตฌ์กฐ๊ฐ€ ํ˜•์„ฑ๋˜์—ˆ๊ณ , ๊ทธ ๊ฒฐ๊ณผ ์ „์—ญ ์ƒํƒœ์˜ ํ๋ฆ„์ด ๋ณต์žกํ•ด์ง€๊ณ  ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์ ์  ์–ด๋ ค์›Œ์กŒ๋‹ค.

์ด์— ๋”ฐ๋ผ ์šฐ๋ฆฌ๋Š” ์ƒํƒœ๊ด€๋ฆฌ ๋ฐฉ์‹์„ Zustand๋กœ ํ†ตํ•ฉํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ–ˆ๋‹ค.

 


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

๋‹ค๋งŒ, ํ†ตํ•ฉ ๊ณผ์ •์—์„œ ๊ณ ๋ คํ•ด์•ผ ํ•  ์ค‘์š”ํ•œ ์ ์ด ์žˆ๋‹ค.

 


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

 

 

๋‹ค์Œ ๊ธ€์—์„œ๋Š” ์–ด๋–ป๊ฒŒ ์ด๋Ÿฌํ•œ ๊ณผ์ œ๋“ค์„ ์ ์šฉ์‹œ์ผฐ๋Š”์ง€ ์จ๋ณด๋„๋ก ํ•˜๊ฒ ๋‹ค!

 

 

 

ํŒ€๋‚ด์—์„œ ๋””์ž์ธ ์‹œ์Šคํ…œ ์„ค๊ณ„์‹œ ๊ธฐ์กด ์‚ฌ์šฉํ•˜๋˜ ํด๋” ๊ตฌ์กฐ๋ฅผ ๋”ฐ๋ผ๊ฐ€๊ธฐ์—๋Š” ํ•œ๊ณ„๊ฐ€ ์žˆ์—‡๋‹ค.

 

์•„๋ž˜๋Š” ๊ธฐ์กด ํด๋” ๊ตฌ์กฐ์ด๋‹ค.

React์—์„œ ๋งŽ์ด ์“ฐ์ด๋Š” ๊ฐ„๋‹จํ•œ ํด๋” ๊ตฌ์กฐ ํ˜•ํƒœ

 

 

ํ•ด๋‹น ๊ตฌ์กฐ๋Š” ์„œ๋น„์Šค ๊ทœ๋ชจ๊ฐ€ ์ปค์ง€๋ฉด์„œ ์œ ์ง€๋ณด์ˆ˜์„ฑ์— ๋ถˆ๋ฆฌํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค.

 

์ด ๊ตฌ์กฐ์˜ ๋‹จ์ ์„ ์‚ดํŽด๋ณด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

 

1. ๊ด€์‹ฌ์‚ฌ ํ˜ผํ•ฉ

components์™€ pages ํด๋”์˜ ํŒŒ์ผ์ด ๊ฑฐ์˜ 1:1๋กœ ๋งคํ•‘๋˜๋‹ค ๋ณด๋‹ˆ, ๋งˆ์น˜ ํŠน์ • ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํ•ด๋‹น ํŽ˜์ด์ง€์—์„œ๋งŒ ์‚ฌ์šฉ๋˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ธ๋‹ค. ํ•˜์ง€๋งŒ ์˜ˆ๋ฅผ ๋“ค์–ด user๋ผ๋Š” ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋‹ค๋ฅธ ํŽ˜์ด์ง€์—์„œ๋„ ์‚ฌ์šฉ๋œ๋‹ค๋ฉด, ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•ด๋„ ๋˜๋Š”์ง€ ํŒ๋‹จํ•˜๊ธฐ ์œ„ํ•ด ๊ฒฐ๊ตญ ์ฝ”๋“œ๋ฅผ ์ง์ ‘ ์—ด์–ด ํ™•์ธํ•ด์•ผ ํ•œ๋‹ค.

 

2. ํ™•์žฅ ์‹œ ์Šค์ผ€์ผ ๋ฌธ์ œ

  • ๊ธฐ๋Šฅ๋ณ„๋กœ ํด๋”๊ฐ€ ์•„๋‹ˆ๋ผ ๋ ˆ์ด์–ด๋ณ„(components, pages, utils)๋กœ๋งŒ ๋‚˜๋ˆ ์ ธ ์žˆ์–ด์„œ,
    ํŽ˜์ด์ง€๋‚˜ ๊ธฐ๋Šฅ์ด ๋งŽ์•„์ง€๋ฉด components/ ํด๋” ์•ˆ์ด ๋„ˆ๋ฌด ์ปค์ง€๊ฒŒ ๋œ๋‹ค. ์‹ค์ œ๋กœ components๋‚ด์˜ ํŒŒ์ผ ๊ฐœ์ˆ˜๋Š” 1000๊ฐœ๋ฅผ ๋„˜์–ด๊ฐ€๋Š” ์ƒํ™ฉ์ด๋‹ค.
  • ๋”ฐ๋ผ์„œ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ ๊ฐœ๋ฐœ ํ˜น์€ ๊ธฐ์กด ๊ธฐ๋Šฅ ๊ณ ๋„ํ™” ์ž‘์—…์„ ์ง„ํ–‰ํ•˜๊ฒŒ ๋˜๋ฉด ๊ทธ ๊ธฐ๋Šฅ์—๋งŒ ๊ด€๋ จ๋œ ํŒŒ์ผ๋งŒ ๋ด์•ผํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹Œ, ์–ด๋–ค ๊ฒƒ์ด ์—ฐ๊ด€์ด ์žˆ๋Š”์ง€ ์ง์ ‘ ์ฐพ์•„๊ฐ€๋ฉฐ ์‚ฌ์ด๋“œ์ดํŽ™ํŠธ๋ฅผ ์‚ดํŽด๋ด์•ผ ํ•œ๋‹ค.

3. ํŽ˜์ด์ง€์™€ ์ปดํฌ๋„ŒํŠธ ๊ฒฐํ•ฉ๋„ ๋ฌธ์ œ

 

  • pages/์™€ components/๊ฐ€ ๋ฌผ๋ฆฌ์ ์œผ๋กœ ๋ฉ€๋ฆฌ ๋–จ์–ด์ ธ ์žˆ์Œ → ์œ ์ง€๋ณด์ˆ˜ ์‹œ ํŽ˜์ด์ง€-์ปดํฌ๋„ŒํŠธ ๊ฐ„ ๋งฅ๋ฝ ํŒŒ์•… ์–ด๋ ต๋‹ค.
  • ๊ฐ™์€ ๊ธฐ๋Šฅ์„ ์œ„ํ•œ ํŽ˜์ด์ง€์™€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์„œ๋กœ ๋‹ค๋ฅธ ํด๋”์—์„œ ์ฐพ์•„์•ผ ํ•œ๋‹ค. → ์“ฐ์ด๋Š” ๊ณณ์„ ์ฐพ์•„๊ฐ€๋ฉฐ ๊ฒฝ๋กœ๋ฅผ ์ด๋™ํ•˜๋‹ค ๊ธธ์„ ์žƒ์„ ์ˆ˜ ์žˆ๋‹ค (;;)

 

 

 

์ด๋Ÿฌํ•œ ๋‹จ์ ๋“ค๋กœ ์ธํ•ด ์šฐ๋ฆฌ ํŒ€ ๋‚ด์—์„œ๋Š” ๊ฐœ์„ ๋ฐฉํ–ฅ์œผ๋กœ ํ”„๋กœ์ ํŠธ์— FSD ์•„ํ‚คํ…์ณ๋ฅผ ์ ์šฉํ•˜๊ธฐ๋กœ ํ•˜์˜€๋‹ค.

 

๋‹จ, ํ”„๋กœ์ ํŠธ ๊ทœ๋ชจ๊ฐ€ ์›Œ๋‚™ ํฌ๋‹ค๋ณด๋‹ˆ FSD(Feature-Sliced Design) ์•„ํ‚คํ…์ณ๋ฅผ ํ•œ ๋ฒˆ์— ํ”„๋กœ์ ํŠธ์— ์ ์šฉํ•  ์ˆ˜ ์—†์—ˆ๊ณ , ๋””์ž์ธ ์‹œ์Šคํ…œ ์ •๋ฆฝ์ด ์ƒˆ๋กœ ์ง„ํ–‰๋˜๊ณ  ์žˆ์—ˆ์œผ๋ฏ€๋กœ ๋””์ž์ธ ์‹œ์Šคํ…œ์— ์ด ์•„ํ‚คํ…์ณ๋ฅผ ๋„์ž…ํ•ด ๋ณด๊ธฐ๋กœ ํ•˜์˜€๋‹ค. 

 

๊ธฐ๋ณธ ๊ณจ์ž๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

 

 

 

 

๐Ÿ“‚ shared/

ํ”„๋กœ์ ํŠธ ์ „์—ญ์—์„œ ๊ณต์šฉ์œผ๋กœ ์“ฐ์ด๋Š” ์š”์†Œ ๋ชจ์Œ

  • tokens/
    • ์ƒ‰์ƒ, ํฐํŠธ, spacing, z-index ๋“ฑ ๋””์ž์ธ ํ† ํฐ
    • ex) colors.ts, typography.ts, spacing.ts
  • hooks/
    • ํ”„๋กœ์ ํŠธ ์ „์—ญ ๊ณต์šฉ ํ›…
    • ex) useMediaQuery, useTheme
  • utils/
    • ํฌ๋งทํ„ฐ, ํ—ฌํผ ํ•จ์ˆ˜ ๋“ฑ ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅ ๋กœ์ง
    • ex) formatDate, debounce, clsx

 

๐Ÿ“‚ entities/

ํ•˜๋‚˜์˜ ๋…๋ฆฝ์ ์ธ UI ์—”ํ‹ฐํ‹ฐ(์ปดํฌ๋„ŒํŠธ) ๋‹จ์œ„

  • ex) button/, input/, avatar/
  • ๊ฐ ์—”ํ‹ฐํ‹ฐ๋Š” ์ž๊ธฐ ์™„๊ฒฐ์ 
    • ui/ → ์‹ค์ œ UI ์ปดํฌ๋„ŒํŠธ (styled-components + variant ์Šคํƒ€์ผ ์ •์˜ ํฌํ•จ)
    • model/ → ํƒ€์ž… ์ •์˜, ์ƒํƒœ ๊ด€๋ฆฌ, ๋‚ด๋ถ€ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง
    • index.ts → ํ•ด๋‹น ์—”ํ‹ฐํ‹ฐ์˜ ์ง„์ž…์  (์™ธ๋ถ€์— ๋…ธ์ถœํ•  API)

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด, ๋ฒ„ํŠผ์„ ์“ธ ๋•Œ ๋‚ด๋ถ€ ๊ตฌ์กฐ๋ฅผ ๋ชฐ๋ผ๋„ import { Button } from '@/entities/button' ์‹์œผ๋กœ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์Œ.

 

๐Ÿ“‚ widgets/ (์„ ํƒ์ )

์—”ํ‹ฐํ‹ฐ๋“ค์„ ์กฐํ•ฉํ•ด ๋งŒ๋“  ๋ณตํ•ฉ UI ์ปดํฌ๋„ŒํŠธ (๋‹จ, ์šฐ๋ฆฌ ํ”„๋กœ์ ํŠธ์—์„œ๋Š” ํด๋” ์ถ•์†Œํ™”๋ฅผ ์œ„ํ•ด entities์— ๋ณตํ•ฉ ui๋ฅผ ํฌํ•จํ•˜๊ธฐ๋„ ํ•˜์˜€๋‹ค.)

  • ์˜ˆ: Form, Navbar, Sidebar
  • ํŽ˜์ด์ง€๋‚˜ ๊ธฐ๋Šฅ์— ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์กฐํ•ฉ ๋‹จ์œ„
  • ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์ด ๊ฑฐ์˜ ์—†๊ณ  UI ๊ฒฐํ•ฉ ์ค‘์‹ฌ

 

๐Ÿ“‚ app/

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ „์—ญ ํ™˜๊ฒฝ๊ณผ ๋ฐ๋ชจ ํŽ˜์ด์ง€

  • ๋””์ž์ธ ์‹œ์Šคํ…œ Storybook, ํ…Œ์ŠคํŠธ ํŽ˜์ด์ง€ ๋“ฑ
  • ๋ผ์šฐํŒ…, ์ „์—ญ Provider, App-level ์„ค์ • ํฌํ•จ ๊ฐ€๋Šฅ
  • ex) storybook/, App.tsx, global.css

 

์ด ๊ตฌ์กฐ์˜ ํŠน์ง•์„ ์‚ดํŽด๋ณด์ž.

 

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

 

 

 

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

๋Œ€๊ทœ๋ชจ ํ”„๋กœ์ ํŠธ์—์„œ๋Š” FSD ํŒจํ„ด, ์ฆ‰ ๊ธฐ๋Šฅ๋ณ„ ๋””์ž์ธ ์•„ํ‚คํ…์ณ๊ฐ€ ํ•„์ˆ˜์ ์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜๋Š” ์š”์ฆ˜์ด๋‹ค!

 

 

 

 
 
์• ์ฆ์˜ DFS์™€ BFS.. ์ดํ•ด์•ˆ ๋˜๋Š” ์ค„ ์•Œ์•˜๋Š”๋ฐ ๋์–ด์š”
 
๋ฅผ ๊ธฐ๋…ํ•˜๋ฉฐ DFS์™€ BFS์— ๋Œ€ํ•ด ์„ค๋ช…ํ•ด๋ณด๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

์ €๋Š” ์ฝ”๋“œ๋ฅผ ๋ณด๊ธฐ ๋ณด๋‹ค ๋จผ์ € ๋จธ๋ฆฌ๋กœ ์ดํ•ดํ•˜๋Š” ๊ฒƒ์ด ๋‚˜์ค‘์„ ์œ„ํ•ด์„œ ์ข‹๋”๋ผ๊ณ ์š”

์ฝ”๋“œ๋ฅผ ์™ธ์šฐ๊ธฐ ๋ณด๋‹ค๋Š” ์›๋ฆฌ๋ฅผ ์ดํ•ดํ•˜๊ณ  ์ ‘๊ทผํ•˜๋Š” ๊ฒƒ์ด ์‘์šฉ ๋ฌธ์ œ ํ˜น์€ ์‹ค์ œ ๋ฌธ์ œ ์ƒํ™ฉ์„ ๋Œ€๋น„ํ•˜๊ธฐ์— ์ ํ•ฉํ•œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค

๊ทธ๋Ÿผ ์‹œ์ž‘!


 
 
 



 
DFS๋Š” ์•ฝ์ž์ž…๋‹ˆ๋‹ค.

Depth-First Search์˜ ์•ฝ์ž์ž…๋‹ˆ๋‹ค.

 

'๊นŠ์ด ์šฐ์„  ํƒ์ƒ‰'์ด๋ผ๊ณ  ํ•˜์ฃ 

 


DFS๋Š” ํ•œ ๊ฒฝ๋กœ๋ฅผ ๋๊นŒ์ง€ ํŒŒ๊ณ ๋“ค์–ด์„œ ํƒ์ƒ‰ํ•œ ๋‹ค์Œ, ๋” ์ด์ƒ ๊ฐˆ ๊ณณ์ด ์—†์œผ๋ฉด ๋’ค๋กœ ๋Œ์•„์™€์„œ ๋‹ค๋ฅธ ๊ฒฝ๋กœ๋ฅผ ํƒ์ƒ‰ํ•˜๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค.
'๊นŠ์ด'๋ฅผ ์šฐ์„ ํ•ด์„œ ํƒ์ƒ‰ํ•œ๋‹ค๋Š” ์˜๋ฏธ์ž…๋‹ˆ๋‹ค
 
 

๐Ÿ›  ๋™์ž‘ ๊ณผ์ •

  1. ์‹œ์ž‘ ๋…ธ๋“œ ๋ฐฉ๋ฌธ
    • ์ถœ๋ฐœ ์ง€์ ์—์„œ ํƒ์ƒ‰์„ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.
    • ์ด ๋…ธ๋“œ๋ฅผ ๋ฐฉ๋ฌธ ์ฒ˜๋ฆฌ(visited ํ‘œ์‹œ)ํ•ฉ๋‹ˆ๋‹ค.
  2. ์—ฐ๊ฒฐ๋œ ๋…ธ๋“œ ์ค‘ ๋ฐฉ๋ฌธํ•˜์ง€ ์•Š์€ ๋…ธ๋“œ๋กœ ์ด๋™
    • ํ˜„์žฌ ๋…ธ๋“œ์™€ ์—ฐ๊ฒฐ๋œ ๋…ธ๋“œ๋“ค ์ค‘์—์„œ ๋ฐฉ๋ฌธํ•˜์ง€ ์•Š์€ ๋…ธ๋“œ๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.
    • ์„ ํƒ๋œ ๋…ธ๋“œ๋กœ ์ด๋™ํ•ด์„œ ๋‹ค์‹œ ๊ฐ™์€ ๊ณผ์ •์„ ๋ฐ˜๋ณตํ•ฉ๋‹ˆ๋‹ค.
  3. ๋” ์ด์ƒ ๊ฐˆ ๊ณณ์ด ์—†์œผ๋ฉด ๋’ค๋กœ(backtrack)
    • ํ˜„์žฌ ๋…ธ๋“œ์—์„œ ๋” ์ด์ƒ ๋ฐฉ๋ฌธํ•  ์ˆ˜ ์žˆ๋Š” ์ƒˆ๋กœ์šด ๋…ธ๋“œ๊ฐ€ ์—†๋‹ค๋ฉด,
      ์ด์ „ ๋‹จ๊ณ„(๋ฐ”๋กœ ์ „ ๋…ธ๋“œ)๋กœ ๋Œ์•„๊ฐ‘๋‹ˆ๋‹ค.
    • ๊ทธ๋ฆฌ๊ณ  ๋‹ค๋ฅธ ๋ฐฉ๋ฌธํ•˜์ง€ ์•Š์€ ๊ฒฝ๋กœ๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
  4. ๋ชจ๋“  ๋…ธ๋“œ ๋ฐฉ๋ฌธํ•  ๋•Œ๊นŒ์ง€ ๋ฐ˜๋ณต
    • ๋ชจ๋“  ๊ฒฝ๋กœ๋ฅผ ํƒ์ƒ‰ํ•˜๋ฉด ์ข…๋ฃŒํ•ฉ๋‹ˆ๋‹ค.

DFS์˜ ๊ตฌํ˜„ ๋ฐฉ์‹

DFS๋Š” ํฌ๊ฒŒ ๋‘ ๊ฐ€์ง€ ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„๋ฉ๋‹ˆ๋‹ค.
 
 

1. ์žฌ๊ท€ ๋ฐฉ์‹

function dfs(node) {
    visited.add(node);
    for (let next of graph[node]) {
        if (!visited.has(next)) {
            dfs(next);
        }
    }
}

 
์ด ๋ฐฉ์‹์€ ์ฝ”๋“œ๊ฐ€ ๊ฐ„๊ฒฐํ•˜์ง€๋งŒ, ๋„ˆ๋ฌด ๊นŠ์€ ๊ทธ๋ž˜ํ”„์—์„œ๋Š” ์žฌ๊ท€ ํ˜ธ์ถœ์ด ๋งŽ์•„์ ธ์„œ ์Šคํƒ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ ์œ„ํ—˜์ด ์žˆ์Œ.
 
 

2. ์Šคํƒ ๋ฐฉ์‹

function dfsStack(start) {
    let stack = [start];
    while (stack.length) {
        let node = stack.pop();
        if (!visited.has(node)) {
            visited.add(node);
            stack.push(...graph[node]);
        }
    }
}

 
์žฌ๊ท€ ๋Œ€์‹  ๋ช…์‹œ์ ์œผ๋กœ ์Šคํƒ ์ž๋ฃŒ๊ตฌ์กฐ๋ฅผ ์‚ฌ์šฉ.
 

DFS ํŠน์ง•?

 

  • ๊นŠ์ด ์šฐ์„  โ†’ ํ•œ ๊ฒฝ๋กœ๋ฅผ ๋๊นŒ์ง€ ํƒ์ƒ‰ ํ›„ ๋Œ์•„์˜ด.
  • ์žฌ๊ท€๋‚˜ ์Šคํƒ์„ ์ด์šฉํ•ด ๊ตฌํ˜„.
  • ๋ชจ๋“  ๊ฒฝ์šฐ์˜ ์ˆ˜ ํƒ์ƒ‰์ด๋‚˜ ๋ฐฑํŠธ๋ž˜ํ‚น์—์„œ ์ž์ฃผ ์“ฐ์ž„.
  • ์ตœ๋‹จ ๊ฑฐ๋ฆฌ ๋ณด์žฅ X โ†’ BFS์™€ ๋‹ฌ๋ฆฌ, ๋จผ์ € ์ฐพ์€ ํ•ด๋‹ต์ด ์ตœ๋‹จ ๊ฒฝ๋กœ๊ฐ€ ์•„๋‹ ์ˆ˜ ์žˆ์Œ.

 
 
 

์‰ฝ๊ฒŒ ์ƒ๊ฐํ•˜๋ฉด,,

ํ•œ ๊ฒฝ๋กœ๋ฅผ ๋๊นŒ์ง€ ๋”ฐ๋ผ๊ฐ€๋ฉฐ ํƒ์ƒ‰ํ•œ ๋’ค, ๋˜๋Œ์•„์™€ ๋‹ค๋ฅธ ๊ฒฝ๋กœ๋ฅผ ํƒ์ƒ‰ํ•˜๋Š” ๋ฐฉ์‹
์ด๋ผ๊ณ  ์ดํ•ดํ•˜์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค


๐Ÿ‘€DFS์˜ ์ „ํ˜•์  ํ•จ์ˆ˜ ์˜ˆ์‹œ

function dfs(node, depth) {
    // node: ํ˜„์žฌ ํƒ์ƒ‰ ์ค‘์ธ ๋…ธ๋“œ(๋˜๋Š” ์‹œ์ž‘์ )
    // depth: ํ˜„์žฌ๊นŒ์ง€ ๋‚ด๋ ค์˜จ ๊นŠ์ด(๋˜๋Š” ๊ฒฝ๋กœ ๊ธธ์ด)
}

1. node
โ€ข ์ง€๊ธˆ ๋ฐฉ๋ฌธํ•˜๊ณ  ์žˆ๋Š” ์œ„์น˜๋‚˜ ๊ฐ’.
โ€ข ๊ทธ๋ž˜ํ”„ ๋ฌธ์ œ๋ผ๋ฉด ์ •์  ๋ฒˆํ˜ธ,
โ€ข ๋ฌธ์ž์—ด ๋ณ€ํ™˜ ๋ฌธ์ œ๋ผ๋ฉด ํ˜„์žฌ ๋‹จ์–ด,
โ€ข ํŠธ๋ฆฌ ํƒ์ƒ‰์ด๋ผ๋ฉด ํ˜„์žฌ ๋…ธ๋“œ ๊ฐ์ฒด.

2. depth / step / count (๋ฌธ์ œ์— ๋”ฐ๋ผ ์„ ํƒ์ ์œผ๋กœ ์‚ฌ์šฉ)
โ€ข ํ˜„์žฌ๊นŒ์ง€ ์ด๋™ํ•œ ๋‹จ๊ณ„ ์ˆ˜, ์žฌ๊ท€ ๊นŠ์ด, ํ˜น์€ ๋ณ€ํ™˜ ํšŸ์ˆ˜.
โ€ข ์ตœ์†Œ ๊ฒฝ๋กœ, ์ตœ์†Œ ๋ณ€ํ™˜ ํšŸ์ˆ˜ ๊ฐ™์€ ๋ฌธ์ œ์—์„œ ์ค‘์š”.

3. visited (๋ณดํ†ต ์ „์—ญ ๋˜๋Š” ์™ธ๋ถ€ ๋ณ€์ˆ˜๋กœ ์ „๋‹ฌ)
โ€ข ์ด๋ฏธ ๋ฐฉ๋ฌธํ•œ ๋…ธ๋“œ๋ฅผ ๊ธฐ๋กํ•˜๋Š” ๋ฐฐ์—ด/Set/๊ฐ์ฒด.
โ€ข ๊ฐ™์€ ๋…ธ๋“œ๋ฅผ ์ค‘๋ณต ํƒ์ƒ‰ํ•˜์ง€ ์•Š๊ฒŒ ํ•จ.

4. target (์„ ํƒ์ )
โ€ข ์–ด๋–ค ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋Š”์ง€ ์ฒดํฌํ•  ๋Œ€์ƒ ๊ฐ’.
โ€ข ์˜ˆ: ์ฐพ๊ณ  ์‹ถ์€ ์ˆซ์ž, ๋‹จ์–ด, ํ˜น์€ ๋„์ฐฉ์  ๋…ธ๋“œ.


โœ”๏ธDFS์—์„œ ํ•ต์‹ฌ ํŒŒ๋ผ๋ฏธํ„ฐ ์กฐํ•ฉ์€ ๋ณดํ†ต
dfs(ํ˜„์žฌ ์œ„์น˜, ํ˜„์žฌ ๊นŠ์ด, ๋ฐฉ๋ฌธ ๊ธฐ๋ก, ๋ชฉํ‘œ ๊ฐ’)
์ด๋ ‡๊ฒŒ ๊ตฌ์„ฑ๋ผ์š”.


 



BFS๋Š” ๊ทธ๋Ÿผ ๋ญ˜๊นŒ์š”


BFS(๋„ˆ๋น„ ์šฐ์„  ํƒ์ƒ‰)๋Š” ๊ฐ€๊นŒ์šด ๊ณณ๋ถ€ํ„ฐ ์ฐจ๋ก€๋Œ€๋กœ ํƒ์ƒ‰ํ•˜๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค

์ข€ ๋” ์‰ฝ๊ฒŒ ๋งํ•˜๋ฉด,
๐Ÿšถ โ€œ์ถœ๋ฐœ์ ์—์„œ ํ•œ ๊ฑธ์Œ์”ฉ ์ฃผ๋ณ€์„ ์ „๋ถ€ ์‚ดํŽด๋ณธ ๋‹ค์Œ, ๊ทธ ๋‹ค์Œ ๊ฑฐ๋ฆฌ๋กœ ์ด๋™ํ•˜๋Š” ํƒ์ƒ‰โ€
๊ฐ™์€ ๊ฐœ๋…์ด์ฃ .


BFS์˜ ํŠน์ง•์€

ํ(Queue) ์ž๋ฃŒ๊ตฌ์กฐ ์‚ฌ์šฉ โ†’ ๋จผ์ € ๋“ค์–ด์˜จ ๋…ธ๋“œ๋ถ€ํ„ฐ ์ฒ˜๋ฆฌ(FIFO).

์ตœ๋‹จ ๊ฑฐ๋ฆฌ ํƒ์ƒ‰์— ์œ ๋ฆฌ โ†’ ๊ฐ€์ค‘์น˜๊ฐ€ ์—†๋Š”(์ด๋™๋งˆ๋‹ค ์—ฐ์‚ฐ์ด ๋“œ๋Š”) ๊ทธ๋ž˜ํ”„์—์„œ ๊ฐ€์žฅ ์งง์€ ๊ฒฝ๋กœ ๋ณด์žฅ.

ํ•œ ๋ฒˆ ๋ฐฉ๋ฌธํ•œ ๋…ธ๋“œ๋Š” ๋‹ค์‹œ ๋ฐฉ๋ฌธํ•˜์ง€ ์•Š๋„๋ก visited ์ฒดํฌ ํ•„์ˆ˜.


๊ฐ„๋‹จ ์˜ˆ์‹œ ์ฝ”๋“œ

function bfs(start) {
    const queue = [start];
    const visited = new Set([start]);

    while (queue.length > 0) {
        const node = queue.shift();
        // node ์ฒ˜๋ฆฌ
        for (let next of node.์ธ์ ‘๋…ธ๋“œ๋“ค) {
            if (!visited.has(next)) {
                visited.add(next);
                queue.push(next);
            }
        }
    }
}


1. start / node
โ€ข ํƒ์ƒ‰ ์‹œ์ž‘์  ๋˜๋Š” ํ˜„์žฌ ํƒ์ƒ‰ ์ค‘์ธ ๋…ธ๋“œ.
โ€ข ๊ทธ๋ž˜ํ”„/ํŠธ๋ฆฌ ๋ฌธ์ œ๋ฉด ์ •์  ๋ฒˆํ˜ธ๋‚˜ ๊ฐ์ฒด, ๋ฌธ์ž์—ด ๋ณ€ํ™˜ ๋ฌธ์ œ๋ฉด ํ˜„์žฌ ๋‹จ์–ด.


2. depth / level / count
โ€ข ํ˜„์žฌ๊นŒ์ง€ ์ด๋™ํ•œ ๊ฑฐ๋ฆฌ(๋‹จ๊ณ„ ์ˆ˜).
โ€ข ์ตœ๋‹จ ๊ฒฝ๋กœ ๋ฌธ์ œ์—์„œ ๋งค์šฐ ์ค‘์š”.
โ€ข BFS๋Š” ๊ฐ€๊นŒ์šด ๊ณณ๋ถ€ํ„ฐ ํƒ์ƒ‰ํ•˜๋‹ˆ๊นŒ, ์ด ๊ฐ’์ด ๊ทธ๋Œ€๋กœ ์ตœ๋‹จ ๊ฑฐ๋ฆฌ์ž„.



3. visited
โ€ข ์ด๋ฏธ ๋ฐฉ๋ฌธํ•œ ๋…ธ๋“œ๋ฅผ ์ €์žฅํ•˜๋Š” ๊ตฌ์กฐ(Set, ๋ฐฐ์—ด, ๊ฐ์ฒด).
โ€ข ์ค‘๋ณต ๋ฐฉ๋ฌธ ๋ฐฉ์ง€ โ†’ ๋ฌดํ•œ ๋ฃจํ”„ ์˜ˆ๋ฐฉ.
โ€ข BFS์—์„œ๋Š” ๋ฐฉ๋ฌธ ์ฒดํฌ๋ฅผ ํ์— ๋„ฃ์„ ๋•Œ ํ•˜๋Š” ๊ฒŒ ๋ณดํ†ต.



4. queue
โ€ข ๋‹ค์Œ์— ํƒ์ƒ‰ํ•  ๋…ธ๋“œ๋“ค์„ ๋‹ด๋Š” ์ž๋ฃŒ๊ตฌ์กฐ(FIFO).
โ€ข ๊ฐ ์š”์†Œ๋Š” ๋ณดํ†ต [node, depth] ๊ฐ™์ด ํ˜„์žฌ ์œ„์น˜์™€ ๋‹จ๊ณ„ ์ˆ˜๋ฅผ ํ•จ๊ป˜ ์ €์žฅ.


5. target (์„ ํƒ์ )
โ€ข ์ฐพ์œผ๋ ค๋Š” ๊ฐ’์ด๋‚˜ ์กฐ๊ฑด.
โ€ข BFS ๋„์ค‘ ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋ฉด ์ฆ‰์‹œ ํƒ์ƒ‰ ์ข…๋ฃŒ ๊ฐ€๋Šฅ.


์œ„ ํŒŒ๋ผ๋ฏธํ„ฐ ์‚ฌ์šฉ ์˜ˆ์‹œ

function bfs(start, target) {
    const queue = [[start, 0]]; // [ํ˜„์žฌ ๋…ธ๋“œ, ๋‹จ๊ณ„ ์ˆ˜]
    const visited = new Set([start]);

    while (queue.length) {
        const [node, depth] = queue.shift();
        if (node === target) return depth;

        for (let next of node.์ธ์ ‘๋…ธ๋“œ๋“ค) {
            if (!visited.has(next)) {
                visited.add(next);
                queue.push([next, depth + 1]);
            }
        }
    }
    return -1; // ์ฐพ์ง€ ๋ชปํ•œ ๊ฒฝ์šฐ
}



์‹ค๋ฌด์—์„œ๋Š” ์–ด๋–ป๊ฒŒ ํ™œ์šฉํ• ๊นŒ?


DFS

DOM ํƒ์ƒ‰

HTML ํŠธ๋ฆฌ๋ฅผ ๊นŠ์ด ์šฐ์„ ์œผ๋กœ ํƒ์ƒ‰ํ•ด ํŠน์ • ๋…ธ๋“œ ์ฐพ๊ธฐ. ์˜ˆ: ์ด๋ฒคํŠธ ์œ„์ž„ ์‹œ ๋ถ€๋ชจ/์ž์‹ ๊ด€๊ณ„ ๊ฒ€์ƒ‰

์ปดํฌ๋„ŒํŠธ ๊ตฌ์กฐ ๋ถ„์„

React/Vue ์ปดํฌ๋„ŒํŠธ ํŠธ๋ฆฌ์—์„œ props/state ์ „ํŒŒ ๊ฒฝ๋กœ ๋ถ„์„

์ค‘์ฒฉ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ

๊ณ„์ธตํ˜• ๋ฐ์ดํ„ฐ(ํด๋” ๊ตฌ์กฐ, ๋ฉ”๋‰ด, ๋Œ“๊ธ€ ์Šค๋ ˆ๋“œ ๋“ฑ)๋ฅผ ๊นŠ๊ฒŒ ๋‚ด๋ ค๊ฐ€๋ฉฐ ์ฒ˜๋ฆฌ

๋ฐฑํŠธ๋ž˜ํ‚น ๊ธฐ๋ฐ˜ ๊ธฐ๋Šฅ

์˜ˆ: ํผ ์ž…๋ ฅ ์‹œ ๊ฐ€๋Šฅํ•œ ๋ชจ๋“  ์กฐํ•ฉ ํƒ์ƒ‰, ํผ์ฆํ˜• ๊ธฐ๋Šฅ(์Šค๋„์ฟ , ๊ฒฝ๋กœ ์ฐพ๊ธฐ)



BFS

์ตœ๋‹จ ๊ฒฝ๋กœ ํƒ์ƒ‰

์˜ˆ: ์ง€๋„ ์„œ๋น„์Šค(์ตœ๋‹จ ๊ฒฝ๋กœ), UI ๋‚ด ์š”์†Œ ๊ฐ„ ์ตœ์†Œ ์ด๋™ ํšŸ์ˆ˜ ๊ณ„์‚ฐ

๊ทผ์ ‘ ํƒ์ƒ‰ ๊ธฐ๋Šฅ

์˜ˆ: ์ถ”์ฒœ ์‹œ์Šคํ…œ์—์„œ ๊ฐ€๊นŒ์šด ๊ด€๋ จ ํ•ญ๋ชฉ๋ถ€ํ„ฐ ์ฐพ๊ธฐ

์ƒํƒœ ์ „ํŒŒ

์‹ค์‹œ๊ฐ„ ์ฑ„ํŒ…๋ฐฉ, ์•Œ๋ฆผ ์‹œ์Šคํ…œ์—์„œ ์ด๋ฒคํŠธ๋ฅผ ๊ฐ€๊นŒ์šด ๊ณณ๋ถ€ํ„ฐ ์ „๋‹ฌ

ํŠธ๋ฆฌ/๊ทธ๋ž˜ํ”„์—์„œ ๋ ˆ๋ฒจ๋ณ„ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ

์˜ˆ: UI ๋ฉ”๋‰ด์˜ ๊นŠ์ด๋ณ„ ํ‘œ์‹œ, ๊ณ„์ธตํ˜• ๋ฐ์ดํ„ฐ์˜ ๋‹จ๊ณ„๋ณ„ ๋กœ๋”ฉ


์ด๋ ‡๊ฒŒ DFS์™€ BFS์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์•˜์Šต๋‹ˆ๋‹ค!
๋ณต์Šต ๋ฐ˜๋ณต๋งŒ์ด ์‚ด ๊ธธ!




 
 

๋ฅ๋‹ค๋”์›Œ

 

์˜ค๋Š˜์€ ์‹ฑ๊ธ€ํ„ดํŒจํ„ด์— ๋Œ€ํ•ด ์•Œ์•„๋ณผ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

 

 

 

ํ”„๋ก ํŠธ์—”๋“œ์—์„œ ๋””์ž์ธ ํŒจํ„ด์ด๋ž€ ๋ฐ˜๋ณต์ ์œผ๋กœ ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ๋ฅผ ํšจ๊ณผ์ ์œผ๋กœ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ "๊ฒ€์ฆ๋œ ์ฝ”๋“œ ๊ตฌ์กฐ๋‚˜ ์„ค๊ณ„ ๋ฐฉ์‹"์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

 

์ฆ‰, ์–ด๋–ค ๊ธฐ๋Šฅ์ด๋‚˜ ๊ตฌ์กฐ๋ฅผ ๋งŒ๋“ค ๋•Œ ์ข€ ๋” ๋‚˜์€ ์„ค๊ณ„์™€ ์œ ์ง€๋ณด์ˆ˜๋ฅผ ์œ„ํ•ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š”

"์ฝ”๋”ฉ ๋ฐฉ์‹์˜ ์ •์„"์ด๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

๋ง๋กœ๋งŒ ๋“ค์–ด์„œ๋Š” ์–ด๋–ค ๊ฑธ ์˜๋ฏธํ•˜๋Š”์ง€ ์™€๋‹ฟ์ง€ ์•Š๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค.

 

์•„๋ž˜ ์„ค๋ช…๊ณผ ์˜ˆ์ œ ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉฐ 1. ์‹ฑ๊ธ€ํ„ด ํŒจํ„ด์— ๋Œ€ํ•ด ์•Œ์•„๋ด…์‹œ๋‹ค.

 

ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœ ์‹ค๋ฌด์—์„œ๋Š” ์–ด๋–ป๊ฒŒ ์ ์šฉํ•˜๋ฉด ์ข‹์„์ง€๋„ ๊ฐ™์ด ์•Œ์•„๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

 

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

์‹ฑ๊ธ€ํ„ด ํŒจํ„ด์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ๋‹จ ํ•˜๋‚˜์˜ ์ธ์Šคํ„ด์Šค๋งŒ ์กด์žฌํ•˜๋„๋ก ๋ณด์žฅํ•˜๋Š” ์ƒ์„ฑ ํŒจํ„ด(Creational Pattern)์ž…๋‹ˆ๋‹ค.

์ฃผ๋กœ *ํ™˜๊ฒฝ ์„ค์ •, ์•ฑ์˜ ์ „์—ญ ์ƒํƒœ, ๊ณต์šฉ ๋ฆฌ์†Œ์Šค ๋“ฑ์„ ํ•œ ๊ณณ์—์„œ ๊ด€๋ฆฌํ•ด์•ผ ํ•  ๋•Œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

 

์—ฌ๊ธฐ์„œ ์ž ๊น! ์™œ ํ™˜๊ฒฝ์„ค์ •, ์•ฑ ์ „์—ญ, ๊ณต์šฉ๋ฆฌ์†Œ์Šค์— ์‚ฌ์šฉํ• ๊นŒ?

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

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

3. ์ค‘์•™ ์ง‘์ค‘์‹ ๊ด€๋ฆฌ → ์œ ์ง€๋ณด์ˆ˜ ํŽธ๋ฆฌ
ํ™˜๊ฒฝ ์„ค์ •, ๊ณตํ†ต ๋กœ์ง, ์ „์—ญ ์ƒํƒœ ๋“ฑ์„ ์—ฌ๊ธฐ์ €๊ธฐ ํฉ๋ฟŒ๋ ค๋‘๋ฉด…
๋‚˜์ค‘์— ์ˆ˜์ •ํ•˜๋ ค๋ฉด ๋ชจ๋“  ํŒŒ์ผ์„ ์ฐพ์•„๋‹ค๋…€์•ผ ํ•จ์‹ค์ˆ˜๋กœ ๋‹ค๋ฅธ ๊ณณ์—์„œ ์„ค์ •์„ ๋ฎ์–ด์“ธ ์ˆ˜ ์žˆ์Œ
๐Ÿ“Œ ์ „์—ญ์—์„œ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•œ ๋‹จ ํ•˜๋‚˜์˜ ์ธ์Šคํ„ด์Šค๋กœ ํ†ต์ œํ•˜๋ฉด,์ค‘์•™์—์„œ ์‰ฝ๊ฒŒ ๊ด€๋ฆฌํ•˜๊ณ  ์ˆ˜์ • ์‚ฌํ•ญ๋„ ํ•œ ๊ตฐ๋ฐ๋งŒ ๋ณ€๊ฒฝํ•˜๋ฉด ๋์ž…๋‹ˆ๋‹ค.

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

 

 

๊ทธ๋Ÿผ ๋‹ค์‹œ ๋ณธ๋ก ์œผ๋กœ ๋Œ์•„์™€์„œ!

 

 

์‹ฑ๊ธ€ํ„ด ํŒจํ„ด์˜ ํ•ต์‹ฌ ๊ฐœ๋…์€

1. ์ธ์Šคํ„ด์Šค๋Š” ๋‹จ ํ•˜๋‚˜๋งŒ ์ƒ์„ฑ๋œ๋‹ค.
2. ์™ธ๋ถ€์—์„œ ์ง์ ‘ ์ƒ์„ฑ์ž๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์—†๋‹ค.
3. ํ•ญ์ƒ ๋™์ผํ•œ ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ •์ (static) ๋ฉ”์„œ๋“œ๋ฅผ ์ œ๊ณตํ•œ๋‹ค.

 

 

์ผ๋‹จ ์ฝ”๋“œ๋ถ€ํ„ฐ ๋ณด๋ฉด์„œ ์ดํ•ดํ•ด๋ณผ๊ฒŒ์š”.

 

์•„๋ž˜ ์ฝ”๋“œ๋Š” ์‹ฑ๊ธ€ํ„ดํŒจํ„ด์˜ Javascript ์˜ˆ์ œ ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค.

class Singleton {
  constructor() {
    if (Singleton.instance) {
      return console.warn(
        'Warning: Singleton class already instantiated'
      );
    }
    Singleton.instance = this;
    this.version = Date.now();
    this.config = 'test';
  }

  static getInstance() {
    if (!this.instance) {
      this.instance = new Singleton();
    }
    return this.instance;
  }
}

 

๊ตฌ์กฐ ์„ค๋ช…

  • ์ƒ์„ฑ์ž(private or ์ œํ•œ์  ์ ‘๊ทผ)
    • ์ธ์Šคํ„ด์Šค๋ฅผ ์™ธ๋ถ€์—์„œ ์ƒˆ๋กœ ๋งŒ๋“ค์ง€ ๋ชปํ•˜๋„๋ก ๋ง‰์Šต๋‹ˆ๋‹ค.
  • ์ •์  ํ”„๋กœํผํ‹ฐ(static instance)
    • ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฉ”๋ชจ๋ฆฌ์— ํ•œ ๋ฒˆ๋งŒ ์ƒ์„ฑํ•˜๊ณ  ์žฌ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • ์ •์  ๋ฉ”์„œ๋“œ(static getInstance)
    • ์ธ์Šคํ„ด์Šค๋ฅผ ์™ธ๋ถ€์—์„œ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค. ์ƒˆ๋กœ์šด ์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“ค์ง€ ์•Š๊ณ  ๊ธฐ์กด ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค

 

๊ทธ๋Ÿผ ์œ„ ์ž‘์„ฑ๋œ ์ฝ”๋“œ๋ฅผ ํ˜ธ์ถœํ•ด๋ณผ๊นŒ์š”?

const s1 = new Singleton();
const s2 = new Singleton();

 

์ด๋ ‡๊ฒŒ ํ˜ธ์ถœํ•˜๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ์š”?

 

๊ฒฐ๊ณผ๋Š”..

const s1 = new Singleton(); // ์ •์ƒ ์ƒ์„ฑ
const s2 = new Singleton(); // ๊ฒฝ๊ณ  ๋ฐœ์ƒ

 

Singleton { version: 1754567722799, config: 'test' }
Warning: Singleton class already instantiated
Singleton {}

 

์ฒซ๋ฒˆ์งธ ๊ฒฐ๊ณผ์—๋Š” Singleton์˜ instance๊ฐ€ ๋‚˜์™”์ง€๋งŒ, ๋‘๋ฒˆ์งธ ๊ฒฐ๊ณผ๋Š” Warning์„ ๋ฑ‰์œผ๋ฉฐ,

์ธ์Šคํ„ด์Šค๋ฅผ ์ฐพ์ง€ ๋ชปํ•˜๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

๊ทธ ์ด์œ ๋Š”

โŒ constructor๋ฅผ ์ง์ ‘ ํ˜ธ์ถœํ•˜๋ฉด ์‹ฑ๊ธ€ํ„ด์˜ ๊ทœ์น™์ด ๊นจ์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ์˜ˆ์ œ์—์„œ๋Š” ๊ฒฝ๊ณ ๋งŒ ๋„์šฐ์ง€๋งŒ, ์‹ค์ œ๋กœ๋Š” constructor๋ฅผ private ๋˜๋Š” protected๋กœ ๋งŒ๋“ค์–ด ์™„์ „ํžˆ ์ฐจ๋‹จํ•˜๋Š” ๊ฒƒ์ด ๋” ์•ˆ์ „ํ•ฉ๋‹ˆ๋‹ค. (TypeScript ๋“ฑ์—์„œ๋Š” private constructor ์‚ฌ์šฉ ๊ฐ€๋Šฅ)

 

๊ทธ๋Ÿผ ์ด์ œ ์ œ๋Œ€๋กœ ํ˜ธ์ถœ์„ ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

const s1 = Singleton.getInstance();
const s2 = Singleton.getInstance();

console.log(s1); // Singleton { version: ..., config: 'test' }
console.log(s2); // Singleton { version: ..., config: 'test' }
console.log(s1 === s2); // true

 

์œ„ ์ฝ”๋“œ์ฒ˜๋Ÿผ s1๊ณผ s2์˜ ๊ฒฐ๊ณผ๊ฐ’์ด ๊ฐ™์œผ๋ฉฐ, ๋™๋“ฑ๋น„๊ต๋ฅผ ํ•ด๋„ true๊ฐ’์ด ๋‚˜์˜ค๋ฉฐ ๋™์ผํ•œ ์ธ์Šคํ„ด์Šค๋ฅผ

๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋„ค์š”!

* ํ•ญ์ƒ getInstance()๋ฅผ ํ†ตํ•ด ๋™์ผํ•œ ์ธ์Šคํ„ด์Šค์— ์ ‘๊ทผํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

 

 

๋ณด์™„ ์‚ฌํ•ญ

1. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ ์ƒ์„ฑ์ž ์ฐจ๋‹จํ•˜๋ ค๋ฉด?

  • ์™„๋ฒฝํžˆ ์ฐจ๋‹จ์€ ๋ถˆ๊ฐ€๋Šฅํ•˜์ง€๋งŒ, ๊ด€๋ก€์ ์œผ๋กœ ์ง์ ‘ ํ˜ธ์ถœ์„ ๊ธˆ์ง€ํ•˜๋Š” ๊ตฌ์กฐ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • TypeScript์—์„œ๋Š” private constructor๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๋ช…ํ™•ํ•˜๊ฒŒ ์ œ์–ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜๋Š” ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ ์˜ˆ์ œ ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค.
class Singleton {
  private static instance: Singleton;

  private constructor() {
    // ์™ธ๋ถ€์—์„œ new Singleton()์„ ์ ˆ๋Œ€ ๋ชป ์”€
  }

  static getInstance(): Singleton {
    if (!Singleton.instance) {
      Singleton.instance = new Singleton();
    }
    return Singleton.instance;
  }
}

 

 

  • private constructor: ์™ธ๋ถ€์—์„œ new Singleton() ์ง์ ‘ ํ˜ธ์ถœ ๋ถˆ๊ฐ€
  • Java, C# ๋“ฑ ํด๋ž˜์Šค ๊ธฐ๋ฐ˜ ์–ธ์–ด์˜ ์‹ฑ๊ธ€ํ„ด๊ณผ ๊ฑฐ์˜ ์œ ์‚ฌํ•œ ๋ฐฉ์‹์œผ๋กœ ์•ˆ์ „ํ•˜๊ฒŒ ๊ตฌํ˜„ ๊ฐ€๋Šฅ

 

2. ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์ด๋ผ๋ฉด?

  • Java, C++ ๊ฐ™์€ ์–ธ์–ด์—์„œ๋Š” ๋™๊ธฐํ™”(Synchronized)๋ฅผ ๊ณ ๋ คํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • JS๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์‹ฑ๊ธ€ ์Šค๋ ˆ๋“œ์ด์ง€๋งŒ, WebWorker๋‚˜ Node.js์—์„œ ๋ฉ€ํ‹ฐ ํ”„๋กœ์„ธ์Šค๋ฅผ ์“ธ ๊ฒฝ์šฐ ์ฃผ์˜๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
  • -> ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ์—์„œ๋Š” ์—ฌ๋Ÿฌ ์“ฐ๋ ˆ๋“œ๊ฐ€ ๋™์‹œ์— getInstance()๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๊ณ  ๋‘ ๊ฐœ ์ด์ƒ์˜ ์ธ์Šคํ„ด์Šค๊ฐ€ ์ƒ์„ฑ๋  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.
  • Java, C++ ๋“ฑ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ์–ธ์–ด์—์„  ๋™๊ธฐํ™”(Synchronization) ํ•„์š”
public class Singleton {
  private static Singleton instance;

  public static synchronized Singleton getInstance() {
    if (instance == null) {
      instance = new Singleton();
    }
    return instance;
  }
}

 

  • synchronized: ํ•œ ๋ฒˆ์— ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๋งŒ ์ ‘๊ทผ ํ—ˆ์šฉ
  • Double-checked locking ๋“ฑ์˜ ์ตœ์ ํ™”๋„ ์‚ฌ์šฉํ•จ

 

๊ทธ๋Ÿผ ์‹ฑ๊ธ€ํ„ดํŒจํ„ด์€ ์—ฌ๊ธฐ๊นŒ์ง€ ์•Œ์•„๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค!

 

์ฐธ๊ณ ์˜์ƒ: Youtube ์ฝ”๋”ฉ๋ฌธ

 

์žฌ๊ท€์™€ ์Šคํƒ์€ ์ดˆ๋ณด์ž๋ถ€ํ„ฐ ๊ณ ๊ธ‰ ๊ฐœ๋ฐœ์ž๊นŒ์ง€ ๊ผญ ์ดํ•ดํ•˜๊ณ  ๋„˜์–ด๊ฐ€์•ผ ํ•  ํ•ต์‹ฌ ๊ฐœ๋…์ž…๋‹ˆ๋‹ค.
์‰ฝ๊ณ  ์ง๊ด€์ ์œผ๋กœ ์ฐจ๊ทผ์ฐจ๊ทผ ์„ค๋ช…ํ•ด๋“œ๋ฆด๊ฒŒ์š”.

โœ… 1. ์žฌ๊ท€(Recursion)๋ž€?

ํ•จ์ˆ˜ ์•ˆ์—์„œ ์ž๊ธฐ ์ž์‹ ์„ ๋‹ค์‹œ ํ˜ธ์ถœํ•˜๋Š” ํ•จ์ˆ˜

๐Ÿ” ์˜ˆ์‹œ: 1๋ถ€ํ„ฐ n๊นŒ์ง€ ๋”ํ•˜๊ธฐ (์žฌ๊ท€ ๋ฒ„์ „)

function sum(n) {
  if (n === 1) return 1;     // ์ข…๋ฃŒ ์กฐ๊ฑด (base case)
  return n + sum(n - 1);     // ์ž๊ธฐ ์ž์‹ ์„ ํ˜ธ์ถœ (์žฌ๊ท€ ํ˜ธ์ถœ)
}

console.log(sum(5)); // ์ถœ๋ ฅ: 15

์ž‘๋™ ์ˆœ์„œ:

sum(5)
โ†’ 5 + sum(4)
     โ†’ 4 + sum(3)
          โ†’ 3 + sum(2)
               โ†’ 2 + sum(1)
                    โ†’ 1

โœ… 2. ์Šคํƒ(Stack)๊ณผ ์žฌ๊ท€์˜ ๊ด€๊ณ„

๐Ÿ”ธ ์Šคํƒ์ด๋ž€?

๋‚˜์ค‘์— ๋“ค์–ด๊ฐ„ ๊ฒŒ ๋จผ์ € ๋‚˜์˜ค๋Š” ์ž๋ฃŒ๊ตฌ์กฐ (LIFO: Last In, First Out)
const stack = [];
stack.push(1);  // [1]
stack.push(2);  // [1, 2]
stack.pop();    // โ†’ 2 (๋จผ์ € ๋‚˜๊ฐ)

๐Ÿ”ธ ์žฌ๊ท€ ํ•จ์ˆ˜๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ ์Šคํƒ ๊ตฌ์กฐ๋ฅผ ์‚ฌ์šฉํ•ด์š”!

  • ํ•จ์ˆ˜ ํ˜ธ์ถœ ์‹œ "ํ˜ธ์ถœ ์ •๋ณด"๊ฐ€ ์ฝœ ์Šคํƒ(Call Stack)์— ์Œ“์ž„
  • ์ข…๋ฃŒ ์กฐ๊ฑด์„ ๋งŒ๋‚˜๋ฉด ๋งˆ์ง€๋ง‰ ํ˜ธ์ถœ๋ถ€ํ„ฐ ์ฐจ๋ก€๋กœ ์Šคํƒ์—์„œ ๋น ์ ธ๋‚˜์˜ค๋ฉฐ ์—ฐ์‚ฐ ์ˆ˜ํ–‰

๐Ÿ“Œ sum(3) ์žฌ๊ท€ ํ˜ธ์ถœ ์˜ˆ์‹œ

sum(3) ํ˜ธ์ถœ โ†’ stack: [sum(3)]
sum(2) ํ˜ธ์ถœ โ†’ stack: [sum(3), sum(2)]
sum(1) ํ˜ธ์ถœ โ†’ stack: [sum(3), sum(2), sum(1)]
sum(1) ์ข…๋ฃŒ โ†’ stack: [sum(3), sum(2)]
sum(2) ์ข…๋ฃŒ โ†’ stack: [sum(3)]
sum(3) ์ข…๋ฃŒ โ†’ stack: []

โœ… 3. ์žฌ๊ท€ ํ•จ์ˆ˜ ๊ตฌ์„ฑ 2๊ฐ€์ง€ ํ•ต์‹ฌ ์š”์†Œ

  1. Base Case (์ข…๋ฃŒ ์กฐ๊ฑด)
    โ†’ ๋ฌดํ•œ ๋ฃจํ”„ ๋ฐฉ์ง€๋ฅผ ์œ„ํ•ด ํ•„์ˆ˜
  2. Recursive Case (์ž๊ธฐ ์ž์‹  ํ˜ธ์ถœ)
    โ†’ ๋ฌธ์ œ๋ฅผ ๋‹จ์ˆœํ™”ํ•˜๋ฉฐ ์žฌํ˜ธ์ถœ

โœ… 4. ์žฌ๊ท€ vs ๋ฐ˜๋ณต๋ฌธ

ํ•ญ๋ชฉ์žฌ๊ท€๋ฐ˜๋ณต๋ฌธ (for/while)
์ฝ”๋“œ ๊ตฌ์กฐ์งง๊ณ  ์ง๊ด€์ ์ผ ์ˆ˜ ์žˆ์Œํ๋ฆ„ ์ œ์–ด์— ๊ฐ•ํ•จ
์„ฑ๋Šฅ์ฝœ ์Šคํƒ ๋งŽ์ด ์“ฐ๋ฉด ๋А๋ฆผ์ผ๋ฐ˜์ ์œผ๋กœ ๋” ๋น ๋ฆ„
์ข…๋ฃŒ ์กฐ๊ฑดBase case ํ•„์š”์กฐ๊ฑด์‹์œผ๋กœ ๋ช…ํ™•
์‚ฌ์šฉ ์˜ˆ์‹œํŠธ๋ฆฌ, ๋ฐฑํŠธ๋ž˜ํ‚น, DFS ๋“ฑ๋‹จ์ˆœ ๋ฐ˜๋ณต ๊ณ„์‚ฐ

โœ… 5. ์‹ค์ „์—์„œ ๋งŽ์ด ์“ฐ์ด๋Š” ์žฌ๊ท€ ์˜ˆ

๋ฌธ์ œ ์œ ํ˜•์„ค๋ช…
ํŒฉํ† ๋ฆฌ์–ผn! = n * (n-1)!
ํ”ผ๋ณด๋‚˜์น˜f(n) = f(n-1) + f(n-2)
ํŠธ๋ฆฌ ํƒ์ƒ‰์ž์‹ ๋…ธ๋“œ ์žฌ๊ท€ ํ˜ธ์ถœ
DFS๊ทธ๋ž˜ํ”„ ๊นŠ์ด ์šฐ์„  ํƒ์ƒ‰
๋ฐฑํŠธ๋ž˜ํ‚น๋ชจ๋“  ์กฐํ•ฉ ํƒ์ƒ‰

โœ… 6. ์žฌ๊ท€ โ†’ ๋ฐ˜๋ณต๋ฌธ์œผ๋กœ ๋ฐ”๊พธ๊ธฐ

function factorial(n) {
  let result = 1;
  for(let i = 1; i <= n; i++) {
    result *= i;
  }
  return result;
}

โ†’ ๊ผญ ์žฌ๊ท€๋งŒ ์จ์•ผ ํ•˜๋Š” ๊ฑด ์•„๋‹ˆ๊ณ , ๋ณต์žกํ•œ ๋ฌธ์ œ ๊ตฌ์กฐ๋ฅผ ๊ฐ„๊ฒฐํ•˜๊ฒŒ ํ‘œํ˜„ํ•  ๋•Œ ์œ ์šฉํ•ด์š”.

โœ… 7. ๋งˆ๋ฌด๋ฆฌ ์š”์•ฝ

๊ฐœ๋…์„ค๋ช…
์žฌ๊ท€ํ•จ์ˆ˜๊ฐ€ ์ž๊ธฐ ์ž์‹ ์„ ํ˜ธ์ถœํ•˜๋Š” ๊ตฌ์กฐ
์Šคํƒํ›„์ž…์„ ์ถœ ๊ตฌ์กฐ๋กœ ์žฌ๊ท€ ํ˜ธ์ถœ์„ ๊ด€๋ฆฌ
๊ด€๊ณ„์žฌ๊ท€ ํ˜ธ์ถœ ์‹œ ์ฝœ ์Šคํƒ์— ์Œ“์˜€๋‹ค๊ฐ€ ์ˆœ์„œ๋Œ€๋กœ ๋น ์ ธ๋‚˜์˜ด
์ฃผ์˜์ข…๋ฃŒ ์กฐ๊ฑด์ด ์—†์œผ๋ฉด ๋ฌดํ•œ ๋ฃจํ”„
โ†’ Maximum call stack size exceeded ์—๋Ÿฌ
์ด ๊ธ€์€ static ํ‚ค์›Œ๋“œ์˜ ๊ธฐ๋ณธ ๊ฐœ๋…๊ณผ ์šฉ๋„, ๊ทธ๋ฆฌ๊ณ  ๋‹ค์–‘ํ•œ ์˜ˆ์‹œ๋ฅผ ํ†ตํ•ด
ํด๋ž˜์Šค ์ •์  ๋ฉ”์„œ๋“œ์™€ ์†์„ฑ ์‚ฌ์šฉ๋ฒ•์„ ์‰ฝ๊ฒŒ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.

1. ์œ ํ‹ธ๋ฆฌํ‹ฐ ํ•จ์ˆ˜ ๋ชจ์Œ (Helper Class)

์ƒํ™ฉ

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

 

์˜ˆ์‹œ ์ฝ”๋“œ

class StringUtils {
  static capitalize(str) {
    return str.charAt(0).toUpperCase() + str.slice(1);
  }

  static toKebabCase(str) {
    return str.toLowerCase().replace(/\s+/g, '-');
  }
}

// ์‚ฌ์šฉ ๋ฐฉ๋ฒ•
console.log(StringUtils.capitalize('hello'));     // Hello
console.log(StringUtils.toKebabCase('Hello World')); // hello-world

์™œ static?

  • StringUtils๋Š” ์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“ค ํ•„์š”๊ฐ€ ์—†์–ด์š”.
  • ๊ทธ๋ƒฅ StringUtils.methodName()์œผ๋กœ ํ˜ธ์ถœ๋งŒ ํ•˜๋ฉด ๋ผ์š”.

2. ์„ค์ • ๊ฐ’ ๊ด€๋ฆฌ (Config Object)

์ƒํ™ฉ

์—ฌ๋Ÿฌ ์ปดํฌ๋„ŒํŠธ๋‚˜ ๋ชจ๋“ˆ์—์„œ ๊ณตํ†ต์œผ๋กœ ์ฐธ์กฐํ•ด์•ผ ํ•˜๋Š” ์„ค์ •๊ฐ’, ๋ฒ„์ „ ์ •๋ณด, API URL ๊ฐ™์€ ๊ฑธ ๊ด€๋ฆฌํ•  ๋•Œ๋„ static์„ ์“ฐ๋ฉด ์ข‹์•„์š”.

์˜ˆ์‹œ ์ฝ”๋“œ

class AppConfig {
  static API_BASE_URL = 'https://api.example.com';
  static VERSION = '1.2.3';

  static printInfo() {
    console.log(`API: ${this.API_BASE_URL}, Version: ${this.VERSION}`);
  }
}

// ์‚ฌ์šฉ ์˜ˆ์‹œ
console.log(AppConfig.API_BASE_URL);  // https://api.example.com
AppConfig.printInfo(); // API: https://api.example.com, Version: 1.2.3

์žฅ์ 

  • ์„ค์ • ๊ฐ’์„ ์ „์—ญ ๋ณ€์ˆ˜๋กœ ํฉ๋ฟŒ๋ฆฌ์ง€ ์•Š๊ณ , ํ•œ ๊ณณ์—์„œ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด์š”.
  • ํ•„์š”ํ•  ๋• AppConfig.API_BASE_URL์ฒ˜๋Ÿผ ์‰ฝ๊ฒŒ ๊บผ๋‚ด ์“ธ ์ˆ˜ ์žˆ์–ด์š”.

3. ๊ฐ์ฒด๋ฅผ ๋งŒ๋“œ๋Š” ๊ณต์žฅ ํ•จ์ˆ˜ (Factory Method)

์ƒํ™ฉ

์–ด๋–ค ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์„œ ํด๋ž˜์Šค ์ธ์Šคํ„ด์Šค๋ฅผ ์‰ฝ๊ฒŒ ๋งŒ๋“ค์–ด์ฃผ๋Š” ๋ฉ”์„œ๋“œ๊ฐ€ ํ•„์š”ํ•  ๋•Œ๊ฐ€ ์žˆ์–ด์š”. ์ด๋Ÿด ๋•Œ static์œผ๋กœ ํŒฉํ† ๋ฆฌ ๋ฉ”์„œ๋“œ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์–ด์š”.

์˜ˆ์‹œ ์ฝ”๋“œ

class User {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }

  static fromJson(json) {
    const data = JSON.parse(json);
    return new User(data.name, data.age);
  }
}

// ์‚ฌ์šฉ ์˜ˆ์‹œ
const jsonStr = '{"name": "Sally", "age": 30}';
const user = User.fromJson(jsonStr);
console.log(user); // User { name: 'Sally', age: 30 }

์žฅ์ 

  • ์™ธ๋ถ€ ๋ฐ์ดํ„ฐ(JSON ๋“ฑ)๋ฅผ ๋ฐ›์•„์„œ ๊น”๋”ํ•˜๊ฒŒ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑ
  • new๋ฅผ ์™ธ๋ถ€์—์„œ ์ผ์ผ์ด ์‚ฌ์šฉํ•˜์ง€ ์•Š์•„๋„ ๋ผ์š”

๐Ÿ’ก ์–ธ์ œ static์„ ์“ฐ๋ฉด ์ข‹์„๊นŒ?

์ƒํ™ฉ ์™œ static์ด ์ข‹์€๊ฐ€์š”?

๋„์šฐ๋ฏธ ํ•จ์ˆ˜ ๋ชจ์Œ ๊ฐ์ฒด ๋งŒ๋“ค์ง€ ์•Š๊ณ  ๋ฐ”๋กœ ์“ธ ์ˆ˜ ์žˆ์–ด์„œ
๊ณตํ†ต ์„ค์ • ๊ฐ’ ๊ด€๋ฆฌ ์ „์—ญ ์˜ค์—ผ ์—†์ด ๊ณต์œ  ๊ฐ€๋Šฅ
์ธ์Šคํ„ด์Šค ์ƒ์„ฑ ๋ณด์กฐ ๋ฐ์ดํ„ฐ ๊ฐ€๊ณต ํ›„ ๊ฐ์ฒด ์ƒ์„ฑ๊นŒ์ง€ ํ•œ ๋ฒˆ์— ์ฒ˜๋ฆฌ

"์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“ค ํ•„์š” ์—†์ด, ํด๋ž˜์Šค ์ž์ฒด์— ๋ถ™์—ฌ์„œ ๊ณตํ†ต ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๊ณ  ์‹ถ์„ ๋•Œ" static์„ ์‚ฌ์šฉํ•˜์„ธ์š”.

 

 

 

+ Recent posts