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



์ด๋ฅผ ์œ„ํ•ด ๋‹ค์–‘ํ•œ ์ƒํƒœ๊ด€๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์กด์žฌํ•˜๋ฉฐ, ๋Œ€ํ‘œ์ ์œผ๋กœ 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์„ ์‚ฌ์šฉํ•˜์„ธ์š”.

 

 

 

์ด ๊ธ€์€ static ํ‚ค์›Œ๋“œ์˜ ๊ธฐ๋ณธ ๊ฐœ๋…๊ณผ ์šฉ๋„, ๊ทธ๋ฆฌ๊ณ  ์‹ค์ œ ์˜ˆ์‹œ๋ฅผ ํ†ตํ•ด
ํด๋ž˜์Šค์˜ ์ •์  ๋ฉ”์„œ๋“œ์™€ ์†์„ฑ์„ ์ดํ•ดํ•˜๊ธฐ ์‰ฝ๊ฒŒ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ”๋ชฉ์ฐจ

โœ… static์ด๋ž€?

static ํ‚ค์›Œ๋“œ๋Š” ํด๋ž˜์Šค์˜ ์ •์ (static) ๋ฉ”์„œ๋“œ๋‚˜ ์†์„ฑ์„ ์ •์˜ํ•  ๋•Œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
์ด๋Ÿฐ ๋ฉ”์„œ๋“œ/์†์„ฑ์€ ํด๋ž˜์Šค ์ธ์Šคํ„ด์Šค์—์„œ ํ˜ธ์ถœํ•  ์ˆ˜ ์—†๊ณ , ํด๋ž˜์Šค ์ž์ฒด์—์„œ๋งŒ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


๊ธฐ๋ณธ ๋ฌธ๋ฒ•

class MyClass {
  static staticMethod() {
    console.log('๋‚˜๋Š” ํด๋ž˜์Šค์—์„œ ์ง์ ‘ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.');
  }

  instanceMethod() {
    console.log('๋‚˜๋Š” ์ธ์Šคํ„ด์Šค์—์„œ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.');
  }
}

MyClass.staticMethod();     // โœ… OK
const obj = new MyClass();
obj.instanceMethod();       // โœ… OK
obj.staticMethod();         // โŒ ์—๋Ÿฌ! ์ธ์Šคํ„ด์Šค์—์„œ๋Š” static ํ˜ธ์ถœ ๋ถˆ๊ฐ€

 

static์˜ ์šฉ๋„

 

์šฉ๋„ ์„ค๋ช… ์˜ˆ์‹œ

์œ ํ‹ธ๋ฆฌํ‹ฐ ๋ฉ”์„œ๋“œ ์ธ์Šคํ„ด์Šค์™€ ๋ฌด๊ด€ํ•œ ๋„์šฐ๋ฏธ ํ•จ์ˆ˜ Math.random(), Array.isArray()
๊ณต์šฉ ์„ค์ •/์ƒ์ˆ˜ ํด๋ž˜์Šค ์ˆ˜์ค€์—์„œ ๊ด€๋ฆฌํ•˜๋Š” ๊ฐ’ MyClass.defaultOptions
ํŒฉํ† ๋ฆฌ ๋ฉ”์„œ๋“œ ๊ฐ์ฒด ์ƒ์„ฑ์„ ๋„์™€์ฃผ๋Š” ํด๋ž˜์Šค ๋ฉ”์„œ๋“œ User.createFromJson()

๐Ÿ”ธ ์˜ˆ์‹œ 1: ์œ ํ‹ธ๋ฆฌํ‹ฐ ๋ฉ”์„œ๋“œ

class MathUtils {
  static add(a, b) {
    return a + b;
  }
}

console.log(MathUtils.add(3, 4)); // 7
  • ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ ์—†์ด ๋ฐ”๋กœ MathUtils.add() ํ˜ธ์ถœ ๊ฐ€๋Šฅ
  • Math.add()๋‚˜ Array.isArray()๋„ ์ด๋Ÿฐ static ๋ฐฉ์‹

๐Ÿ”ธ ์˜ˆ์‹œ 2: ํŒฉํ† ๋ฆฌ ๋ฉ”์„œ๋“œ (๊ฐ์ฒด ์ƒ์„ฑ ๋„์šฐ๋ฏธ)

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

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

const json = '{"name": "sally"}';
const user = User.fromJson(json);
console.log(user); // User { name: 'sally' }

๐Ÿ”ธ ์˜ˆ์‹œ 3: ์ •์  ์†์„ฑ (class-level ์ƒ์ˆ˜ ๋“ฑ)

class Config {
  static version = '1.0.0';

  static printVersion() {
    console.log(`๋ฒ„์ „: ${Config.version}`);
  }
}

Config.printVersion(); // ๋ฒ„์ „: 1.0.0

 

โ€ป ์ •์  ์†์„ฑ์€ ์ตœ์‹  JS(ES2022+) ๋ฌธ๋ฒ•์ด๋ฉฐ, Babel/webpack ์—†์ด ์“ฐ๋ ค๋ฉด ํ™˜๊ฒฝ ํ™•์ธ ํ•„์š”


static vs instance

ํ˜ธ์ถœ ๋Œ€์ƒ ํด๋ž˜์Šค ์ธ์Šคํ„ด์Šค
์ƒํƒœ ์ €์žฅ ์œ„์น˜ ํด๋ž˜์Šค์— ๊ท€์† ๊ฐ ์ธ์Šคํ„ด์Šค๋งˆ๋‹ค ๋ณ„๋„
์˜ˆ์‹œ Array.isArray(), Math.random() arr.push(), user.name

 


์ฐธ๊ณ : static์€ ์ƒ์†๋จ

class Parent {
  static hello() {
    console.log('hello');
  }
}
class Child extends Parent {}

Child.hello(); // โœ… hello (์ƒ์†๋จ)

 

ํŠน์ง• ์„ค๋ช…

์ •์˜ ์œ„์น˜ ํด๋ž˜์Šค ๋‚ด๋ถ€์—์„œ static ํ‚ค์›Œ๋“œ ์‚ฌ์šฉ
ํ˜ธ์ถœ ๋ฐฉ์‹ ํด๋ž˜์Šค๋ช….static๋ฉ”์„œ๋“œ()
๋ชฉ์  ์ธ์Šคํ„ด์Šค ์ƒํƒœ์™€ ๋ฌด๊ด€ํ•œ ํ•จ์ˆ˜๋‚˜ ์†์„ฑ ์ •์˜
์˜ˆ์‹œ Math, Array, Object, Date ๋“ฑ์˜ ์œ ํ‹ธ ๋ฉ”์„œ๋“œ

 

 

 

 

Javascript๋Š” ๋ณธ์งˆ์ ์œผ๋กœ ๊ฐ์ฒด ๊ธฐ๋ฐ˜ ์–ธ์–ด์ž…๋‹ˆ๋‹ค.

 

OOP(Object-Oriented Programming)์˜ ํ•ต์‹ฌ์€ ๋‹ค์Œ ๋„ค ๊ฐ€์ง€์ž…๋‹ˆ๋‹ค

  1. ์ถ”์ƒํ™” (Abstraction)
  2. ์บก์Аํ™” (Encapsulation)
  3. ์ƒ์† (Inheritance)
  4. ๋‹คํ˜•์„ฑ (Polymorphism)

 


1๏ธโƒฃ ์ถ”์ƒํ™” (Abstraction)

๋ถˆํ•„์š”ํ•œ ์„ธ๋ถ€ ์ •๋ณด๋ฅผ ์ˆจ๊ธฐ๊ณ , ์ค‘์š”ํ•œ ๋ถ€๋ถ„๋งŒ ๋…ธ์ถœํ•˜๋Š” ๊ฒƒ

์˜ˆ์‹œ:

class CoffeeMachine {
  constructor(brand) {
    this.brand = brand;
  }

  makeEspresso() {
    this.#boilWater();
    console.log(`${this.brand} ๋จธ์‹ : ์—์Šคํ”„๋ ˆ์†Œ ์™„์„ฑ!`);
  }

  #boilWater() {
    console.log('๋ฌผ์„ ๋“์ด๋Š” ์ค‘...');
  }
}

const cm = new CoffeeMachine('Nespresso');
cm.makeEspresso(); // ์—์Šคํ”„๋ ˆ์†Œ ์™„์„ฑ!
  • ๋‚ด๋ถ€ ๋™์ž‘(boilWater())์€ ์ˆจ๊ฒจ์ง
  • ์‚ฌ์šฉ์ž ์ž…์žฅ์—์„  ๋‹จ์ˆœํžˆ makeEspresso()๋งŒ ์•Œ๋ฉด ๋จ

2๏ธโƒฃ ์บก์Аํ™” (Encapsulation)

๊ฐ์ฒด ๋‚ด๋ถ€ ์ƒํƒœ๋ฅผ ์ˆจ๊ธฐ๊ณ , ํ•„์š”ํ•œ ์ธํ„ฐํŽ˜์ด์Šค๋งŒ ๊ณต๊ฐœํ•˜๋Š” ๊ฒƒ

โœ… ์˜ˆ์‹œ (Private ํ•„๋“œ):

class BankAccount {
  #balance = 0;

  deposit(amount) {
    if (amount > 0) this.#balance += amount;
  }

  getBalance() {
    return this.#balance;
  }
}

const myAccount = new BankAccount();
myAccount.deposit(1000);
console.log(myAccount.getBalance()); // 1000
// myAccount.#balance → โŒ ์—๋Ÿฌ
  • #balance๋Š” ์™ธ๋ถ€์—์„œ ์ง์ ‘ ์ ‘๊ทผ ๋ถˆ๊ฐ€ (์บก์Аํ™”)

3๏ธโƒฃ ์ƒ์† (Inheritance)

๊ธฐ์กด ํด๋ž˜์Šค์˜ ์†์„ฑ๊ณผ ๋ฉ”์„œ๋“œ๋ฅผ ์ž์‹ ํด๋ž˜์Šค๊ฐ€ ๋ฌผ๋ ค๋ฐ›๋Š” ๊ฒƒ

โœ… ์˜ˆ์‹œ:

class Animal {
  constructor(name) {
    this.name = name;
  }

  speak() {
    console.log(`${this.name} makes a sound`);
  }
}

class Dog extends Animal {
  speak() {
    console.log(`${this.name} barks`);
  }
}

const dog = new Dog('Buddy');
dog.speak(); // Buddy barks
  • Dog๋Š” Animal์˜ ์†์„ฑ ๋ฐ ๋ฉ”์„œ๋“œ๋ฅผ ์ƒ์†๋ฐ›๊ณ , speak()๋Š” ์˜ค๋ฒ„๋ผ์ด๋”ฉ

4๏ธโƒฃ ๋‹คํ˜•์„ฑ (Polymorphism)

๊ฐ™์€ ๋ฉ”์„œ๋“œ๋ช…์ด ์ƒํ™ฉ์— ๋”ฐ๋ผ ๋‹ค๋ฅด๊ฒŒ ๋™์ž‘ํ•˜๋Š” ๊ฒƒ

โœ… ์˜ˆ์‹œ (์˜ค๋ฒ„๋ผ์ด๋”ฉ):

const animals = [
  new Dog('Max'),
  new Animal('Generic')
];

animals.forEach(animal => animal.speak());

 

๊ฒฐ๊ณผ:

Max barks
Generic makes a sound
  • speak()๋Š” ๊ฐ ํด๋ž˜์Šค์— ๋”ฐ๋ผ ๋‹ค๋ฅด๊ฒŒ ๊ตฌํ˜„๋จ
  • ํ•˜๋‚˜์˜ animal.speak() ํ˜ธ์ถœ์ด ์—ฌ๋Ÿฌ ํ˜•ํƒœ๋กœ ๋™์ž‘ → ๋‹คํ˜•์„ฑ

๐Ÿ”ท React ์ปดํฌ๋„ŒํŠธ์™€ OOP ๊ฐœ๋…

React๋Š” ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ ๊ธฐ๋ฐ˜์ด์ง€๋งŒ, OOP์˜ ์‚ฌ๊ณ ๋ฐฉ์‹์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ทธ๋Œ€๋กœ ์ ์šฉ๋ฉ๋‹ˆ๋‹ค.

 

OOP ํŠน์„ฑ React์—์„œ์˜ ์˜ˆ

์ถ”์ƒํ™” ์ปดํฌ๋„ŒํŠธ๋กœ UI ๋‹จ์œ„ ์ถ”์ƒํ™” (<Button />)
์บก์Аํ™” props/state๋Š” ์™ธ๋ถ€์—์„œ ์ง์ ‘ ์ ‘๊ทผ ๋ถˆ๊ฐ€
์ƒ์† HOC, ํด๋ž˜์Šคํ˜• ์ปดํฌ๋„ŒํŠธ์—์„œ extends React.Component
๋‹คํ˜•์„ฑ ๋™์ผํ•œ ์ปดํฌ๋„ŒํŠธ ์ด๋ฆ„์ด๋ผ๋„ props์— ๋”ฐ๋ผ ๋‹ค๋ฅด๊ฒŒ ๋ Œ๋”๋ง
const Button = ({ type }) => {
  return <button>{type === 'submit' ? '์ œ์ถœ' : '์ทจ์†Œ'}</button>;
};
  • ๊ฐ™์€ <Button /> ์ปดํฌ๋„ŒํŠธ๋„ props์— ๋”ฐ๋ผ ๋‹ค๋ฅด๊ฒŒ ๋™์ž‘ → ๋‹คํ˜•์„ฑ ๊ฐœ๋… ์ ์šฉ

๊ฒฐ๋ก 

ํŠน์„ฑ ์„ค๋ช… JS ์˜ˆ์‹œ ํ‚ค์›Œ๋“œ

์ถ”์ƒํ™” ์ค‘์š”ํ•œ ๊ฒƒ๋งŒ ๋ณด์ด๊ฒŒ private ๋ฉ”์„œ๋“œ, interface ์—ญํ• 
์บก์Аํ™” ๋‚ด๋ถ€ ์ˆจ๊ธฐ๊ธฐ #ํ•„๋“œ, getter/setter
์ƒ์† ์ฝ”๋“œ ์žฌ์‚ฌ์šฉ class A extends B
๋‹คํ˜•์„ฑ ๋™์ผ ์ธํ„ฐํŽ˜์ด์Šค, ๋‹ค๋ฅธ ๊ตฌํ˜„ ๋ฉ”์„œ๋“œ ์˜ค๋ฒ„๋ผ์ด๋”ฉ

 

+ Recent posts