ํจ์ํ ํ๋ก๊ทธ๋๋ฐ์ ๋ํ ์ค์ฉ ์ค์ฌ ์๋ด์. ๋๋ฌด ์ด๋ ค์ด ์ด๋ก (lambda calculus) ๋๋ ๋๋ฌด ๋จ์ํ ์ ์ธ ("side effect๋ฅผ ์์ ๋ผ!!!")์ ์ ์ณ๋๊ณ , ์ค์ํ์ ์์๋ก๋ถํฐ ์์. ์ข ๊ตญ์๋ ํจ์ํ ํ๋ก๊ทธ๋๋ฐ์ ์ค์ฉ์ ์ธ ๋์์ผ๋ก ์ ํํ๋๋ก ํ๊ธฐ ์ํจ.
์ถ์ฒ์ฌ์ ๋ด๊ธด ์ ๋ฆฌ
structured programming - organizing control flow
์ฌ๋ก๊ฑด : 'go to๋ฅผ ์์ ์'
๋ชฉํ : ํ๋ฆ ์ ์ด๋ฅผ ๋จ์ํ ํจํด์ผ๋ก ๋ง๋ค์.(if-then-else, switch, for, while)
โฌ๏ธ
object-oriented programming - organizing access to data
์ฌ๋ก๊ฑด : '์ ์ญ ๋ณ์๋ฅผ ์์ ์'
๋ชฉํ : ๊ฐ์ฒด๋ฅผ ํตํด ๋ณ์๋ฅผ ๊ด๋ฆฌํ์. (์บก์ํ, ์์)
โฌ๏ธ
functional programming - organizing side effect
์ฌ๋ก๊ฑด : '๋ถ์ ํจ๊ณผ๋ฅผ ์์ ์'
๋ชฉํ : ๋ถ์ํจ๊ณผ๋ฅผ ์ ๊ด๋ฆฌํด ์ฝ๋์ ์๋ฌด ๊ณณ์๋ ์์ง ์๋๋ก ํ์.
์์ ์ฝ๋ ๊นํ๋ธ ๋งํฌ ๐ https://github.com/ericnormand/grokking-simplicity-code
์ ๊ธ ๋๊ธฐ ํ ์ค์ ์ด ํจ์ํ ํ๋ก๊ทธ๋๋ฐ์ ๋ฏธ์น(?) ์ฌ๋์ด ํ๋ช ์์ด์ ์ฌ๋ฌ๋ฒ ์ด์ผ๊ธฐ๋ ๋ค์์ง๋ง, ์ด๋ ๊ฒ ๋นจ๋ฆฌ ํจ์ํ ํ๋ก๊ทธ๋๋ฐ์ ๋ง๋๊ฒ ๋ ์ค ๋ชฐ๋๋ค. ๋น์์๋ ๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ๊ณผ ํจ์ํ ํ๋ก๊ทธ๋๋ฐ์ด ๋ฌด์จ ์ ๋ฌผ๋ก ๊ณผ ๊ด๋ ๋ก ์ฒ๋ผ ์ฒ ํ์ ์ธ ๋ ผ์์ธ์ค๋ง ์์๋๋ฐ, ์ค์ฌ๊ฐ ์์๋ค. ๊ธฐ๋๊ฐ ๋๋ค. ์ ์ฌ ์ด๊ธฐ์ ํ ์ผ์ด ๋๋ฌด ๋ง์ ๊ฑฑ์ ์ด ๋์ง๋ง ๋ถ๋ ๋ฌด์ฌํ ์์ฃผํ ์ ์์์ผ๋ฉด ์ข๊ฒ ๋ค.
<์์ฝ>
ํจ์ํ ํ๋ก๊ทธ๋๋ฐ ์ ์ -> ํจ์ํ ์ฌ๊ณ
์ผ๋ฐ์ ์ธ ํจ์ํ ํ๋ก๊ทธ๋๋ฐ์ ์ ์๋ ์ค์ฉ์ ์ธ ์ธก๋ฉด์์ ๋ฌธ์ ์ ์ ๊ฐ๋๋ค. ์ฌ์ค ๋ถ์ ํจ๊ณผ๋ ์ํํธ์จ์ด๋ฅผ ์คํํ๋ ์ด์ ์ด๋ค. ํ์ํ ๋๋ ์จ์ผํ๋ค. ๋ค๋ง, ๋ถ์ํจ๊ณผ๊ฐ ์ฌ๋ฌ๊ฐ์ง ๋ฌธ์ ๋ฅผ ์ผ์ผํฌ ์ ์์ผ๋ฏ๋ก ์ด๋ฅผ ์ ๊ด๋ฆฌํด์ผ ํ๋ค.
๊ฒฐ๊ตญ ์ด ์ฑ
์ ํจ์ํ ํ๋ก๊ทธ๋๋ฐ์ ์ ์๊ฐ ์๋, 'ํจ์ํ ์ฌ๊ณ '์ ๋ํด ์ค๋ช
ํ๋ค.
ํจ์ํ ์ฌ๊ณ ์๋ ๋ ๊ฐ์ง ์ค์ํ ๊ฐ๋
์ด ์๋ค.
์ก์ / ๊ณ์ฐ / ๋ฐ์ดํฐ
์ ์ง ๋ณด์๋ฅผ ์ํ์ฌ
์ฝ๋๋ ์ฝ๊ฒ ๋ณ๊ฒฝ์ด ๊ฐ๋ฅํ ์๋ก ์ข๋ค. ์ฌ์ ์ด๋๊ฒ ๊ทธ๋์ ๊ทธ๋ฐ๋ฏ.
๊ณ์ธตํ ์ค๊ณ : ์ ์ง ๋ณด์ํ๊ธฐ ์ข์ ์ฝ๋ (๋ณ๊ฒฝ ๋น์ฉ์ด ๋ฎ์ ์ฝ๋)๋ฅผ ์ํด, ๋ณ๊ฒฝ ๊ฐ๋ฅ์ฑ์ ๋ฐ๋ผ ์ฝ๋๋ฅผ ๊ณ์ธต์ผ๋ก ๋๋๋ ๊ฒ. ์ฃผ๋ก ๋น์ฆ๋์ค ๊ท์น, ๋๋ฉ์ธ ๊ท์น, ๊ธฐ์ ์คํ ๊ณ์ธต์ผ๋ก ๋๋๋ค.
๋ถ์ฐ ์์คํ ์ ์ํ์ฌ
์๊ฐ์ด ์ง๋๋ฉด์ ๋ณต์กํ ๋คํธ์ํฌ ํต์ ์ ํ๋ ์ํํธ์จ์ด๊ฐ ํ์ํด์ง. ์ฒ๋ฆฌ๋์ด์ผ ํ ๋ฉ์์ง๋ ์์๊ฐ ์์ด๊ฑฐ๋, ์ค๋ณต๋๊ฑฐ๋ ์ ์ค๋ ์ ์๋ค. ์ด๋ฐ ๋ฌธ์ ๊ฐ ์ ์ ์ํํธ์จ์ด๋ฅผ ๋ง๋ค์ด์ผ ํ๋ค. ์ก์ ์ ์ ๊ด๋ฆฌํ๊ณ , ๋๋๋ก ๋ฐ์ดํฐ์ ๊ณ์ฐ์ผ๋ก ๋ฐ๊ฟ์ผ ํ๋ค.
ํ์๋ผ์ธ ๋ค์ด์ด๊ทธ๋จ : ์๊ฐ์ ๋ฐ๋ผ ๋ณํ๋ ์ก์ ์ ์๊ฐํ ํ๋ ๋ฐฉ๋ฒ. ์ก์ ์ด ๋ค๋ฅธ ์ก์ ๊ณผ ์ด๋ป๊ฒ ์ฐ๊ฒฐ ๋๋์ง (์ด๋ค ์์๋ฅผ ์ง๋๋ ์ง) ๋ณผ ์ ์๋ค. ๋ถ์ฐ ์์คํ ์์, ์ปคํ ์ ํตํด ์ฌ๋ฌ ํ์๋ผ์ธ์ ์๊ฐ์ ๋ง์ถ ์ ์๋ค.
<๋ฐ์ท>
์คํ ์์ ์ด๋ ํ์์ ์์กดํ๋ ์ฝ๋๋ฅผ ์์ ๋ฉด, ์ฝ๋๋ฅผ ๋ ์ฝ๊ฒ ์ดํดํ ์ ์๊ณ ์ฌ๊ฐํ ๋ฒ๊ทธ๋ฅผ ๋ง์ ์ ์์ต๋๋ค.
๋ถ์ฐ ์์คํ ์์.
๊ณ์ฐ์ ์ด๋ค ๊ฒ์ ๊ฒฐ์ ํ๊ฑฐ๋ ๊ณํํ๋ ๊ฒ.
์ก์
, ๊ณ์ฐ, ๋ฐ์ดํฐ ๋ผ๋ ๊ด์ ์์ ๋ดค์ ๋.
<๋ฉ๋ชจ>
๋ถ์ ํจ๊ณผ (side effect) : ํจ์๊ฐ ๋ฆฌํด๊ฐ ์ด์ธ์ ํ๋ ๋ชจ๋ ์ผ.
์์ ํจ์ (pure function) : ์ธ์์๋ง ์์กดํ๊ณ (๊ฐ์ ์ธ์๋ฉด ๊ฐ์ ๊ฒฐ๊ณผ), ๋ถ์ ํจ๊ณผ๊ฐ ์๋ ํจ์.
<์์ฝ>
์ก์
, ๊ณ์ฐ, ๋ฐ์ดํฐ๋ฅผ ์ผ์ ๋๋ ์๋กญ๊ฒ ์ง๋ ์ฝ๋์ ์ค์ ๋ก ์ ์ฉํด๋ณด๊ธฐ.
๊ฐ์ฅ ๋จ์ํ๊ฒ ์๊ฐํด์ ์ ์ฉํ๋ฉด, ๋๋ถ๋ถ ์ก์
์ผ๋ก ์ด๋ฃจ์ด์ง๋ค.
์ก์
์์์ '๋๋ ๋ชจ๋ฅด๊ฒ ์ผ์ด๋๊ณ ์๋' ๊ณ์ฐ๊ณผ,
๊ทธ ๊ณ์ฐ์ ์ํด ์ฌ์ฉ๋๊ณ ์๋ ๋ฐ์ดํฐ๋ฅผ ์ฐพ์๋ด ๋ถ๋ฆฌํ๋ฉด ๋๋ค.
ํํธ๋ ๋ฌด์์ธ๊ฐ ๊ฒฐ์ ํ๊ฑฐ๋ ๊ณํํ๋ ๋จ๊ณ๊ฐ ์๋์ง๋ฅผ ์๊ฐํด ๋ณด๋ฉด ๋๋ค.
๊ฒฐ์ ๊ณผ ๊ณํ์ ๊ณ์ฐ์ด ๋ ๊ฐ๋ฅ์ฑ์ด ๋๋ค.
<๋ฐ์ท>
ํจ์ํ ํ๋ก๊ทธ๋๋ฐ์์๋ ์ก์ ์ ๋ ์์ ์ก์ ๊ณผ ๊ณ์ฐ, ๋ฐ์ดํฐ๋ก ๋๋๊ณ
๋๋๋ ๊ฒ์ ์ธ์ ๋ฉ์ถฐ์ผ ํ ์ง ์๋ ๊ฒ์ด ์ค์ํฉ๋๋ค.
์ถฉ๋ถํ ๊ตฌํํ๊ธฐ ์ฝ๋ค๊ณ ์๊ฐ๋๋ ์์ ์์ ๋ ๋๋๋ ๊ฒ์ ๋ฉ์ถ๊ธฐ.
๋ฐ์ดํฐ๋ฅผ ๋จผ์ ๊ตฌํํ๊ณ , ๊ณ์ฐ์ ๊ตฌํํ ํ์, ๋ง์ง๋ง์ผ๋ก ์ก์ ์ ๊ตฌํํ๋ ๊ฒ์ด
ํจ์ํ ํ๋ก๊ทธ๋๋ฐ์ ์ผ๋ฐ์ ์ธ ๊ตฌํ ์์์ ๋๋ค.
์ฝ๋ ์์ฑ์ ์์
<๋ฉ๋ชจ>
๋ฐ์ดํฐ
๊ณ์ฐ
<์์ฝ>
๐
์ก์
์ ํธ์ถํ๋ ํจ์๋, ๊ทธ ํจ์๋ฅผ ํธ์ถํ๋ ๋ชจ๋ ํจ์๋ค์ ์ก์
์ผ๋ก ๋ง๋ ๋ค.
์์ ๋ค์ด์๋ ์ก์
๋๋ฌธ์ ๊ฒฐ๊ตญ ์์์ ํธ์ถ๋ ํธ์ถ ์์ ๊ณผ ํ์์ ์์กดํ๊ธฐ ๋๋ฌธ.
์ก์
์ ๋ค๋ฅธ๋ง๋ก ์์ํ์ง ์์ ํจ์, ๋ถ์ ํจ๊ณผ๊ฐ ์๋ ํจ์.
์ธ๋ถ ์ธ๊ณ์ ์ํฅ์ ์ฃผ๊ฑฐ๋ ๋ฐ๋ ๊ฒ์ ๋งํ๋ค.
๐
in ํจ์ํ ํ๋ก๊ทธ๋๋ฐ,
๊ณ์ฐ์ ๊ณํ์ด๋ ๊ฒฐ์ ์ ํ ๋ ์ ์ฉํ๋ ๊ฒ.
๋ฐ์ดํฐ๋ ๊ณํํ๊ฑฐ๋ ๊ฒฐ์ ํ ๊ฒฐ๊ณผ.
์ก์
์ ๊ณ์ฐ์ผ๋ก ๋ง๋ ๊ณํ์ ์คํํ๋ ๊ฒ.
๐
ํ
์คํธ์ ์ฌ์ฌ์ฉ์ฑ์ ์
์ถ๋ ฅ๊ณผ ๊ด๋ จ์๋ค.
์๋ฌต์ ์ ์ถ๋ ฅ์ด ์๋ ํจ์๋ฅผ,
ํ ์คํธ ํ๊ธฐ ์ด๋ ค์ด ์ด์ :
์ฌ์ฌ์ฉํ๊ธฐ ์ด๋ ค์ด ์ด์ :
๐
๊ฒฐ๊ตญ ์๋ฌต์ ์
์ถ๋ ฅ์ ์ค์ด๊ธฐ ์ํด์ , DOM ์ ๋ํ ์ํฅ๊ณผ ์์กด์ ์ค์ฌ์ผ ํ๋ค.
<๋ฐ์ท>
์ก์ ์ ๋ค๋ฃจ๊ธฐ ํ๋ญ๋๋ค.
์ก์ ์ ์ฐ๋ฆฌ๊ฐ ์ํํธ์จ์ด๋ฅผ ์คํํ๋ ค๋ ๊ฐ์ฅ ์ค์ํ ์ด์ ์ ๋๋ค.
<๋ฉ๋ชจ>
์ฝ์ผ๋ฉด ์ฝ์ ์๋ก ๋ฌ๊ตฌ๋ฆ ์ก๋ ์๋ฆฌ ๊ฐ์ผ๋ฉด์๋, ๊ทธ๊ฑธ ์ด๋ป๊ฒ ์คํํ๋ค๋ ๊ฑด์ง ๊ถ๊ธํด์ง๋ค.
<์์ฝ>
๐
์ก์
์์ ๊ณ์ฐ ๋นผ๋ด๊ธฐ
// ์๋ ์ฝ๋
function update_tax_dom() {
set_tax_dom(shopping_cart_total * 0.10); // shopping_cart_total์ ์ ์ญ๋ณ์
}
// ์๋ธ ๋ฃจํด ์ถ์ถ
function update_tax_dom() {
set_tax_dom(calc_tax());
}
function calc_tax() {
return shopping_cart_total * 0.10;
}
// ์๋ฌต์ ์
๋ ฅ ์์ ๊ธฐ
function update_tax_dom() {
set_tax_dom(calc_tax(shopping_cart_total));
}
function calc_tax(total) {
return total * 0.10;
}
์ ๋ ฅ
- ํจ์ ์ธ์
- ํจ์ ๋ฐ ๋ณ์ ์ฝ๊ธฐ
- ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ๊ฐ์ ๊ฐ์ ธ์ค๊ธฐ์ถ๋ ฅ
- ํจ์ ๋ฆฌํด๊ฐ
- ์ ์ญ ๋ณ์๊ฐ ๋ฐ๊พธ๊ธฐ
- ๊ณต์ ๊ฐ์ฒด ๋ฐ๊พธ๊ธฐ
- ์น ์์ฒญ ๋ณด๋ด๊ธฐ
๐
์ด๋ฅผ ํตํด ์ฌ์ฌ์ฉํ๊ธฐ ์ข๊ณ ํ
์คํธํ๊ธฐ ์ฌ์ด ์ฝ๋๋ฅผ ๋ง๋ค ์ ์๋ค.
ํจ์ํ ํ๋ก๊ทธ๋๋ฐ์ ์ด ๋ฟ๋ง ์๋๋ผ, ๋์์ฑ, ์ค๊ณ, ๋ฐ์ดํฐ ๋ชจ๋ธ๋ง ์ธก๋ฉด์์๋ ์ข์ ์ ์ ๋ง์ด ๊ฐ์ง๊ณ ์๋ค.
<๋ฐ์ท>
์ด๋ค ๊ฐ์ ๋ฐ๊ฟ ๋ ๊ทธ ๊ฐ์ ๋ณต์ฌํด์ ๋ฐ๊พธ๋ ๋ฐฉ๋ฒ์ ๋ถ๋ณ์ฑ์ ๊ตฌํํ๋ ๋ฐฉ๋ฒ ์ค ํ๋์ ๋๋ค. ์ด ๋ฐฉ๋ฒ์ copy-on-write ๋ผ๊ณ ํฉ๋๋ค.
<๋ฉ๋ชจ>
[์๊ฐํด๋ณด๊ธฐ]
๋ง์ฝ ์ธ์๋ก ์ ๋ฌํ ๋ฐฐ์ด์ ์ง์ ๋ณ๊ฒฝํ๋ค๋ฉด ๊ทธ ํจ์๋ ๊ณ์ฐ์ผ๊น์?
๊ณ์ฐ์ด ์๋๋ผ๋ฉด ์ ์๋๊ฐ์?
A. ๊ณ์ฐ์ด ์๋ ๊ฒ ๊ฐ๋ค. ์ผ๋จ ๋ฐฐ์ด์ ์ธ์๋ก ์ ๋ฌํ ๋ ๊ฒฐ๊ตญ ํด๋น ๋ฐฐ์ด์ ์ฃผ์๋ฅผ ์ฐธ์กฐํ ์ ์๋ ๋ณ์๋ฅผ ๋๊ธธ ๊ฒ์ด๊ธฐ ๋๋ฌธ์, ํจ์ ์์์ ๊ทธ ๋ฐฐ์ด์ ์ง์ ๋ณ๊ฒฝํ๋ฉด ํจ์ ์ธ๋ถ์ ์๋ ๋ณ์๋ฅผ ๋ณ๊ฒฝํ๋ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ ๊ณ์ฐ์ด ์๋๊ฒ ๋๋ค.
<์์ฝ>
๐
๋ชจ๋ ์ก์
์ ์์จ ์ ์๋ค. ์ก์
์ ํ๋ก๊ทธ๋จ์ ์กด์ฌ ์ด์ .
์ก์
์์ ๋ ์ด์ ๋นผ๋ผ ๊ณ์ฐ์ด ๋ ์์ ๋์ ๊ฐ์ ๋ฐฉ๋ฒ.
๐
์ต์ข
์ ์ผ๋ก ์ฝ๋๋ ๊ตฌ๋ถ๋ ๊ทธ๋ฃน๊ณผ ๋ถ๋ฆฌ๋ ๊ณ์ธต์ผ๋ก ๊ตฌ์ฑํ ๊ฒ์.
์ด๋ฅผ ์ฐ์ตํ๊ธฐ ์ํด, ๊ณ์ฐ์ ๋๋์ด ๊ณ์ธต์ ๋ง๋ค์ด ๋ณธ๋ค.
<๋ฐ์ท>
copy-on-write
function add_item (cart, item) {
var new_cart = cart.slice(); // copy
new_cart.push(item); // write
return new_cart;
}
copy-on-write โก๏ธ ๋ณต์ฌ์ ๋ํ ๋น์ฉ์ด ํฌ์ง๋ ์์๊น?
<๋ฉ๋ชจ>
๋ ์ฝ์ด ๋ณด๊ณ ์ถ๋ค๋ ์๊ฐ์ด ๋ ๋ค.
๊ณ์ ์ด๋ฐ ๊ธฐ๋ถ์ด ๋ค๋ค๊ฐ ๋๋๋ ๊ฒ ์๋๊ฐ ํ๋ ๊ฑฑ์ ์ด ๋ ๋ค.
<์์ฝ>
๐
๋ถ๋ณ์ฑ์ ์ ์งํ๋ฉด์ ๊ฐ์ ๋ฐ๊พธ๊ธฐ ์ํด copy-on-write๋ฅผ ํ์ฉํ๋ค.
์์๋ ๋ค์๊ณผ ๊ฐ๋ค.
๋ณต์ฌ๋ณธ์ ๋ง๋ ๋ค๋ ๊ฒ์ ๊ณง ์ง์ญ๋ณ์๋ฅผ ์ฌ์ฉํ๋ ๊ฒ.
์ง์ญ๋ณ์๋ฅผ ๋ณ๊ฒฝํ๋ ๊ฒ์ ๊ทธ ํจ์์ ์ธ๋ถ์์ ๋ดค์ ๋, ๋ฐ์ดํฐ๋ฅผ ๋ฐ๊พธ๋ ๊ฒ์ด ์๋๋ค. (์๋ฌต์ ์
๋ ฅ์ด ์๋ค๋ฉด) ํจ์๋ฅผ ํธ์ถํ ๋ ๋ง๋ค ํญ์ ๊ฐ์ ๊ฒฐ๊ณผ๋ฅผ ์ฃผ๋ ๊ณ์ฐ์ผ ๋ฟ์ด๊ธฐ ๋๋ฌธ์ด๋ค.
'์ฝ๊ธฐ'๋ผ๋ ๊ฒ์ ๋ฐ์ดํฐ๋ฅผ ๋ฐ๊พธ์ง ์๊ณ ๊ฐ์ ๋ฆฌํดํ๋ ๊ฒ.
๐
'์ฐ๊ธฐ'๋ง ํ๋ ๋์์ ์์ ๊ฐ์ ๋ฐฉ๋ฒ์ผ๋ก copy-on-write ์ ์ฉํ๋ฉด ๋๋ค.
'์ฐ๊ธฐ์ ์ฝ๊ธฐ'๋ฅผ ๋์์ ํ๋ ๋์์,
<๋ฐ์ท>
copy-on-write ๋ ์ฐ๊ธฐ๋ฅผ ์ฝ๊ธฐ๋ก ๋ฐ๊ฟ๋๋ค.
<๋ฉ๋ชจ>
๊ฒฐ๊ตญ '๋ณ๊ฒฝ๋ ๋ณต์ฌ๋ณธ' ์ ์๋ณธ์ ํ ๋นํ๊ธฐ๋ ํ๋ค.
๋ค๋ง ๋ณ๊ฒฝ๋ ๋ณต์ฌ๋ณธ์ ๋ฆฌํดํ๋ ํจ์๊ฐ, '๊ณ์ฐ'์ผ๋ก์ ๊ทธ ํจ์ ์ธ๋ถ์์ ์ํฅ์ ์ ํ ์ฃผ๊ณ ๋ฐ์ง ์๊ธฐ ๋๋ฌธ์, ๋ถ๋ณ์ฑ์ ์ ์งํ๋ฉด์ ๊ฐ์ ๋ฐ๊ฟ ์ ์๋ค๊ณ ํ๋ ๊ฒ ๊ฐ๋ค.
์ฐ๊ธฐ๋ ์ก์ , ์ฝ๊ธฐ๋ ๊ณ์ฐ๊ณผ ๋ฐ์ดํฐ์ ๊ฐ๊น๋ค.
copy-on-write๋ฅผ ์ ์ฉํ ํจ์๋ฅผ ํธ์ถํ๋ ๊ฒ์ด, ๋ฐ์ดํฐ๋ฅผ ์์ํ๊ฒ '์ฝ์' ๊ฒ๊ณผ ๋ง์ฐฌ๊ฐ์ง๊ฐ ๋๋ ๊ฒ์ด๋ค.
<์์ฝ>
๐
๋ฐ์ดํฐ๊ฐ ์ ๋ถ ๋ถ๋ณํ์ด๋ฉด ์๊ฐ์ ๋ฐ๋ผ ๋ณํ๋ ์ํ (e.g. ์ฅ๋ฐ๊ตฌ๋ ์ํ) ๋ฅผ ์ด๋ป๊ฒ ๋ค๋ฃฐ ์ ์๋?
-> ๊ทธ๋ด ๋๋ '๊ต์ฒด(swapping)'๋ฅผ ํ๋ค.
๋ถ๋ณ ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ฅผ ์ฌ์ฉํ๋ฉด ๋น์ฐํ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋ ๋ง์ด ์ฐ๊ณ ๋ ๋๋ฆฌ๋ค.
ํ์ง๋ง,
๐
๊ฐ์ฒด์ ๋ํ copy-on-write
-> ๋ฐฐ์ด๊ณผ ๋์ผํ ๋ฐฉ์
1. ๋ณต์ฌ๋ณธ ๋ง๋ค๊ธฐ 2. ๋ณต์ฌ๋ณธ ๋ณ๊ฒฝํ๊ธฐ 3. ๋ณต์ฌ๋ณธ ๋ฆฌํดํ๊ธฐ.
๋ค๋ง, ์๋ฐ์คํฌ๋ฆฝํธ์์ ๊ฐ์ฒด๋ฅผ ๋ณต์ฌํ๊ธฐ ์ํด์๋ Object.assign()
๋ฉ์๋๋ฅผ ํ์ฉํ๋ค.
<๋ฐ์ท>
์์ ๋ณต์ฌ (shallow copy)
์ค์ฒฉ๋ ๋ฐ์ดํฐ ๊ตฌ์กฐ์ ์ต์์ ๋ฐ์ดํฐ๋ง ๋ณต์ฌ. ์๋ฅผ ๋ค์ด, ๊ฐ์ฒด๋ฅผ ์์๋ก ๊ฐ์ง๋ ๋ฐฐ์ด์ '์์ ๋ณต์ฌ' ํ๋ฉด, ๋ฐฐ์ด๋ง ๋ณต์ฌํ๊ณ ์์ ์๋ ๊ฐ์ฒด๋ ์ฐธ์กฐ๋ก ๊ณต์ .
๊ตฌ์กฐ์ ๊ณต์ (structural sharing)
๋ ๊ฐ์ ์ค์ฒฉ๋ ๋ฐ์ดํฐ ๊ตฌ์กฐ๊ฐ ์ด๋ค ์ฐธ์กฐ๋ฅผ ๊ณต์ ํ๋ค๋ฉด, '๊ตฌ์กฐ์ ๊ณต์ ' ๋ผ๊ณ ํ๋ค.
<๋ฉ๋ชจ>
140p ~ 161p
<์์ฝ>
๐
์์ ๋ณต์ฌ๋ ๋ฐ๋ ๋ถ๋ถ๋ง ๋ณต์ฌํ๊ณ , ๋๋จธ์ง๋ ์ฐธ์กฐ๋ฅผ ํตํด ๊ณต์ ํ๋ค. ๊ตฌ์กฐ์ ๊ณต์ .
๊ทธ๋์ ์์ ๋ณต์ฌ๊ฐ ๊น์ ๋ณต์ฌ๋ณด๋ค ๋น์ฉ์ด ๋ ๋ ๋ค.
๐
๋ฐฉ์ด์ ๋ณต์ฌ : ๋ ๊ฑฐ์ ์ฝ๋, ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ฑ ์ ๋ขฐํ ์ ์๋ ์ฝ๋์ ๋ฐ์ดํฐ๋ฅผ ์ฃผ๊ณ ๋ฐ์์ผ ํ ๋, ๊น์ ๋ณต์ฌ๋ฅผ ์ฌ์ฉํ์ฌ ๋ถ๋ณ์ฑ์ ์งํฌ ์ ์๋ ๋ฐฉ๋ฒ
<๋ฐ์ท>
copy-on-write๋ ์ด๋์ ์ฐ๋์?
-> ์์ ์ง๋ ์ด๋์๋ . ์ฌ์ค copy-on-write๊ฐ ๋ถ๋ณ์ฑ์ ๊ฐ์ง ์์ ์ง๋๋ฅผ ๋ง๋ ๋ค.
๋น๊ณต์ ์ํคํ ์ฒ (shared nothing architecture)
์๋ฐ ์คํฌ๋ฆฝํธ์์ ๊น์ ๋ณต์ฌ๋ฅผ ๊ตฌํํ๋ ๊ฒ์ ์ด๋ ต๋ค.
162p ~ 185p
<์์ฝ>
๐
๊ณ์ธตํ ์ค๊ณ
๊ณ์ธต(layer)
๋น์ฆ๋์ค ๊ท์น
-----------------------------------
์ฃผ์ ๋์ (์ฅ๋ฐ๊ตฌ๋, ์ํ)
-----------------------------------
copy-on-write
-----------------------------------
์ธ์ด ์ง์ ๊ธฐ๋ฅ (๋ฐ๋ณต๋ฌธ, ๋ฐฐ์ด ์ธ๋ฑ์ค ๋ฑ)
์ฑ ์์๋ ๋ ์ข์ ์ค๊ณ๋ฅผ ํ ์ ์๋๋ก ๋์์ฃผ๋ ์ ํธ๋ฅผ ์ฐพ๋ ๋ฒ ๋ช๊ฐ์ง๋ฅผ ์ ์.
๐
๊ณ์ธตํ ์ค๊ณ ํจํด
4๊ฐ์ง ์ค์ํ ํจํด์ด ์กด์ฌ.
๐
Straightforward Implementation ์ ์ฉํ๊ธฐ
๋ชฉํ : ํจ์๊ฐ ํธ์ถํ๋ ํจ์ ๋๋ ๊ธฐ๋ฅ๋ค์ด ๋ชจ๋ ๋น์ทํ ๊ตฌ์ฒดํ ์์ค์์ ์๋ํ๊ณ ์์ด์ผ ํ๋ค. -> ์ด๋ฅผ ์ํด์, ๋๋ฌด ๊ตฌ์ฒด์ ์ธ ๋ถ๋ถ์ ์ถ์ํ ํ๋ค.
์ฌ๊ณ ๊ณผ์
ํจ์๊ฐ ์์์ผ ํ ํ์๊ฐ ์๋ ๊ตฌ์ฒด์ ์ธ ๋ด์ฉ์ ํจ์๊ฐ ๋ด๊ณ ์์.
(๋น์ฆ๋์ค ๊ท์น ์ฒ๋ฆฌ์ ๊ฐ๊น์ด ํจ์๊ฐ ๋ฐฐ์ด ๊ตฌ์กฐ๋ฅผ ๋ค๋ค์ผ ํ ๊น?)
ํจ์ ์์์ ์ฌ์ฉ๋๋ '์ง์ ๋ง๋ ํจ์'์ '์ธ์ด ๊ธฐ๋ฅ'์ ์ถ์ํ ์์ค์ด ๋ค๋ฆ.
์๋ก ๋ค๋ฅธ ์ถ์ํ ๋จ๊ณ๋ก ์ธํด ์ฝ๋๋ฅผ ์ดํดํ๊ธฐ ์ด๋ ค์ ์ง.
ํจ์๊ฐ ์ ํ์๊ฐ ์๋ ๊ตฌ์ฒด์ ์ธ ๋ถ๋ถ์ ํจ์๋ฅผ ๋ฐ๋ก ๋ง๋ค์ด ๊ฐ์ถฐ์ค์ผ๋ก์จ, ํจ์๊ฐ ๋ชจ๋ ๋น์ทํ ๊ณ์ธต์ ์๋ ํจ์๋ฅผ ํธ์ถํ๊ฒ ํจ.
Straightforward Implementation ์ด๋ค.
<๋ฐ์ท>
์ํํธ์จ์ด ์ค๊ณ (software design)
"์ฝ๋๋ฅผ ๋ง๋ค๊ณ , ํ ์คํธํ๊ณ , ์ ์ง๋ณด์ํ๊ธฐ ์ฌ์ด ํ๋ก๊ทธ๋๋ฐ ๋ฐฉ๋ฒ์ ์ ํํ๊ธฐ ์ํด ๋ฏธ์ ๊ฐ๊ฐ์ ์ฌ์ฉํ๋ ๊ฒ"
-> '์ ๋ฌธ๊ฐ์ ์ ์ฃผ' ๊ฐ์ ๊ฐ๋ ์ ๊ณ ๋ คํด๋ดค์ ๋, ๊ณ์ธตํ ์ค๊ณ๊ฐ ๋ถ๋ช ํ ๊ฐ๊ฐ์ ์ธ ์ธก๋ฉด์ด ์กด์ฌํ๋ค๋ ์ ์์ ๋ฏธ์ ๊ฐ๊ฐ ์ด๋ผ๋ ํํ์ ์ฌ์ฉํ ๋ฏ.
ํธ์ถ ๊ทธ๋ํ์์
"๊ฐ์ ๋ฐ์ค๋ฅผ ๊ฐ๋ฆฌํจ๋ค๋ ๊ฒ์ ๊ฐ์ ๊ณ์ธต์ ์์ด๋ ์ข๋ค๋ ์ ๋ณด์ด๋ค."
<๋ฉ๋ชจ>
๋ฒ์ญ์ด ๋๋ฌด ์์ฌ์.
186p ~ 210p
<์์ฝ>
๐
3๋จ๊ณ ์ค ๋ ๋ฒจ
์ง์ ๊ตฌํ: ๋ฆฌ๋ทฐ
์ถ์ํ ๋ฒฝ (abstraction barrier)
<๋ฐ์ท>
์ถ์ํ ๋ฒฝ์,
์ด๋ค ๊ฒ์ ์ ๊ฒฝ ์ฐ์ง ์์๋ ๋์ง? ๋ผ๋ ๋ง์ ๊ฑฐ์ฐฝํ๊ฒ ํํํ ๊ฐ๋ .
<๋ฉ๋ชจ>
๋น์ทํ ๊ฐ๋
(๊ตฌ์ฒด, ์ถ์, ๊ณ์ธต)์ ๊ฐ์ง๊ณ , ๊ด์ฌ์ ๋๋ ์ง์ ๋ง ์ด์ง์ด์ง ๋ฐ๊ฟ๊ฐ๋ฉด์ ํจํด์ ๋ถ๋ฆฌํ ๊ฒ ๊ฐ์ ๋๋์ด๋ค.
211p ~ 232p
<์์ฝ>
๐
์ถ์ํ ๋ฒฝ: ํจํด ๋ฆฌ๋ทฐ
๐
์์ ์ธํฐํ์ด์ค (minimal interface)
๐
์์ ์ธํฐํ์ด์ค: ํจํด ๋ฆฌ๋ทฐ
๐
ํธ๋ฆฌํ ๊ณ์ธต
์ค๊ณ (๊ฐ๋ฐ์๋ก์์ ํ์์ฑ) - ์๋ก์ด ๊ธฐ๋ฅ (๋น์ฆ๋์ค ์๊ตฌ์ฌํญ)
์ฌ์ด ์ด๋ ์ง์ ์ ๋จธ๋ฌผ๊ฒ ๋จ.๐
ํธ์ถ ๊ทธ๋ํ ํ์ฉ
(์๋์ ์๋ ํจ์: ๋ฎ์ ๊ณ์ธต์ ํจ์ / ์์ ์๋ ํจ์: ๋์ ๊ณ์ธต์ ํจ์)
<๋ฐ์ท>
์ฝ๋ ์ค ์๋ ์ค์ํ์ง ์์ต๋๋ค. ์ค์ํ ๊ฒ์ ์ฝ๋๊ฐ ์ ์ ํ ๊ตฌ์ฒดํ ์์ค๊ณผ ์ผ๋ฐํ๊ฐ ๋์ด ์๋์ง์ ๋๋ค.
๊ณ์ธตํ ์ค๊ณ๋ ๋ฐ๋ก ์๋ ๊ณ์ธต์ ์๋ ํจ์๋ก, ํ์ฌ ๊ณ์ธต์ ํจ์๋ฅผ ๊ตฌํํด ์ฝ๋๋ฅผ ๊ตฌ์ฑํ๋ ๊ธฐ์ ์ ๋๋ค.
<๋ฉ๋ชจ>
๊ณ์ธต, ๊ณ์ธต, ๊ณ์ธต.
'ํธ๋ฆฌํ ๊ณ์ธต' ํจํด์ด ๊ฐ์ฅ ์๋ฟ์๋ค. ์ด๋ก ์ ์ด์, ์
๋ฌด๋ ํ์ค.
233p ~ 252p
<์์ฝ>
๐
ํํธ 2 ์์ ํ ๊ฒ : "์ผ๊ธ์ด ์๋ ๊ฒ์ ์ฐพ๊ณ ๊ทธ๊ฒ์ ์ผ๊ธ์ผ๋ก ๋ฐ๊ฟ ๋ณด๊ธฐ"
๐
์ฝ๋์ ๋์ ๋งก๋ ๋ฒ (ํจ์ ์ด๋ฆ์ ์๋ ์๋ฌต์ ์ธ์๋ฅผ ํฌ์ฐฉํ๋ ๋ฒ)
๋ ๊ฐ์ง์ ๋ฆฌํฉํฐ๋ง์ผ๋ก ํด๊ฒฐ ๊ฐ๋ฅ
๐
"์๋ฌต์ ์ธ์๋ฅผ ๋๋ฌ๋ด๊ธฐ" ๋จ๊ณ
๐
๋ช
์์ ์ธ ์ธ์๋ก ์ ๋ฌํ ์ ์๋, ๋ณ์๋ ๋ฐฐ์ด์ ๋ด์ ์ ์๋, ์ฆ ์ธ์ด ์ด๋์๋ ์ฌ์ฉ๊ฐ๋ฅํ ๊ฒ -> ์ผ๊ธ
(๊ทธ ๋ฐ๋๋ ์๋ฌต์ ์ธ, ๋ด์ ์ ์๋, ์๋ฌด๋ฐ์๋ ์ฌ์ฉํ ์ ์๋.)
๊ทธ๋์ "์๋ฌต์ ์ธ์๋ฅผ ๋๋ฌ๋ด๊ธฐ" ๋ฆฌํฉํฐ๋ง๋ ๊ฒฐ๊ตญ, ์๋ฌต์ ์ธ ์ด๋ฆ์ ์ธ์๋ก ๋๊ธธ์ ์๋ ์ด๋ค๊ฒ์ผ๋ก ๋ฐ๊พธ๋ ๊ณผ์ . ์ฆ, ์ผ๊ธ์ผ๋ก ๋ฐ๊พธ๋ ๊ณผ์ .
๐
์๋ฐ์คํฌ๋ฆฝํธ์์ ์ผ๊ธ(first-class)๊ฐ ์๋ ๊ฒ
์ผ๊ธ์ผ๋ก ํ ์ ์๋ ๊ฒ
๐
e.g.
๋ฐํ์ ๊ฒ์ฌ ๋ฐฉ๋ฒ์ผ๋ก ํ๋๋ช
(์ผ๊ธ์ผ๋ก ์ ๋ฌ๋)์ด ์ฌ๋ฐ๋ฅธ์ง ํ์ธํ๋ ๋์.
API์ ๋ณ๊ฒฝ์ผ๋ก ์๋ ํ๋๋ช
์ ์๋ก์ด ํ๋๋ช
์ผ๋ก ๋ด๋ถ์์ ๋์น์์ผ์ฃผ๋ ๋์.
๐
์ด๋ค ๋ฌธ๋ฒ์ด๋ ์ผ๊ธ ํจ์๋ก ๋ฐ๊ฟ ์ ์๋ค.
<๋ฐ์ท>
๊ทธ๋ผ ์ฐ๋ฆฌ๋ ์ด๋ป๊ฒ ํด์ผ ํ ๊น์?
์ฌ๋ฌ๋ถ๊ณผ ์ฌ๋ฌ๋ถ์ ํ์ด ์ ํํ ์ธ์ด๊ฐ ํธํ๋ค๋ฉด ๊ฑฑ์ ํ์ง ๋ง๊ณ ๊ณ์ ์ฌ์ฉํ์๋ฉด ๋ฉ๋๋ค.
๊ทธ๋ฆฌ๊ณ ์ ์ ๋ ์๋ ๊ฒ์ด ์ข๊ฒ ๋ค์.
๋ฐ์ดํฐ ์งํฅ
์ด๋ฒคํธ์ ์ํฐํฐ์ ๋ํ ์ฌ์ค์ ํํํ๊ธฐ ์ํด ์ผ๋ฐ ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ฅผ ์ฌ์ฉํ๋ ํ๋ก๊ทธ๋๋ฐ ํ์.
253p ~ 278p
<์์ฝ>
๐ ๊ฐ์
์ฝ๋์ ๋์. ๋ ๊ฐ์ง์ ๋ฆฌํฉํฐ๋ง์ผ๋ก ํด๊ฒฐ ๊ฐ๋ฅ.
๐ ์ฉ์ด ์ ๋ฆฌ
์ผ๊ธ (first-class) : "์ธ์๋ก ์ ๋ฌํ ์ ์๋ค."
์ผ๊ธ ๊ฐ : '์ผ๊ธ'์ธ ๋ฐ์ดํฐ.
์ผ๊ธ ํจ์ : '์ผ๊ธ'์ธ ํจ์.
๊ณ ์ฐจ ํจ์ : ์ผ๊ธ ํจ์๋ฅผ ์ธ์๋ก ๋ฐ๊ฑฐ๋ ๋ฆฌํดํ ์ ์๋ ํจ์.
๐ "ํจ์ ๋ณธ๋ฌธ์ ์ฝ๋ฐฑ์ผ๋ก ๋ฐ๊พธ๊ธฐ"
๐ ์ฝ๋ ์์
// 1. ์๋ถ๋ถ ๋ท๋ถ๋ถ ํ์ธ
function arraySet (array, idx, value) {
var copy = array.slice(); // ์๋ถ๋ถ
copy[idx] = value; // ๋ณธ๋ฌธ
return copy; // ๋ท๋ถ๋ถ
}
// 2. ํจ์ ๋นผ๋ด๊ธฐ
function withArrayCopy(array) {
var copy = array.slice();
copy[idx] = value; // ๋ณธ๋ฌธ. ์์ง ์ ๋๋ก ์ ์๋์ง ์์ ์ํ.
return copy;
}
function arraySet(array, idx, value) {
return withArrayCopy(array);
}
// 3. ์ฝ๋ฐฑ ๋นผ๋ด๊ธฐ
function withArrayCopy(array, modify) {
var copy = array.slice();
modify(copy); // ์ฝ๋ฐฑ ํธ์ถ. ์๋์ ๋ณธ๋ฌธ์ ํด๋น.
return copy;
}
function arraySet(array, idx, value) {
return withArrayCopy(
array,
function(copy) {copy[idx] = value;} // ์ฝ๋ฐฑ ์ ๋ฌ
);
}
<๋ฐ์ท>
์๋ฐ์คํฌ๋ฆฝํธ์์ ์ธ์๋ก ์ ๋ฌํ๋ ํจ์๋ฅผ ์ฝ๋ฐฑ(callback) ๋๋ ํธ๋ค๋ฌ ํจ์(handler function) ๋ผ๊ณ ๋ถ๋ฆ ๋๋ค. ๋ฌผ๋ก ์๋ฐ์คํฌ๋ฆฝํธ ์ธ์ ๋ค๋ฅธ ์ปค๋ฎค๋ํฐ์์๋ ์ฌ์ฉํ๋ ์ฉ์ด์ ๋๋ค. ์ฝ๋ฐฑ์ผ๋ก ์ ๋ฌํ๋ ํจ์๋ "๋์ค์ ํธ์ถ๋ ๊ฒ"์ ๊ธฐ๋ํฉ๋๋ค.
<๋ฉ๋ชจ>
๊ณ ์ฐจ ํจ์์ ์ ๋ฌํ๋ ์ฝ๋ฐฑ ํจ์๋, ๊ณ ์ฐจ ํจ์ ์์์ ํธ์ถ๋๋ ๊ผด์ ๋ง๋ ์ธ์์ ๊ฒฐ๊ณผ๊ฐ์ ๊ฐ์ง๊ณ ์์ด์ผ ํจ. ํ์
์คํฌ๋ฆฝํธ๊ฐ ์ ์๊ฒผ๋์ง ์๊ฒ ๋ค.
279p ~ 302p
<์์ฝ>
๐ ๊ฐ์
ํจ์ ๋ณธ๋ฌธ์ ์ฝ๋ฐฑ์ผ๋ก ๋ฐ๊พธ๊ธฐ -> ๊ฒฐ๊ตญ, ๊ณ ์ฐจํจ์๋ฅผ ํ์ฉํ ๋ฆฌํฉํ ๋ง๊ณผ ๊ฐ์ ๋ง.
1. with ํจํด
2. wrap ํจํด
// ์) saveUserData() ํจ์ ์คํ ์๋ฌ ์ ๋ก๊ทธ๋ฅผ ๋จ๊ธฐ๊ณ ์ถ์
// ์๋ ์ฝ๋
try {
saveUserData(user);
} catch (error) {
logToSnapErrors(error);
}
// withLogging
function withLogging(f) {
try {
f();
} catch(error) {
logToSnapErrors(error);
}
}
withLogging(function() {
saveUserData(user);
});
// wrapLogging
function wrapLogging(f) {
return function (arg) {
try {
f(arg);
} catch {
logToSnapErrors(error);
}
}
}
var saveUserDataWithLogging = wrapLogging(saveUserDataNoLogging);
with ํจํด์ ๋จ์ : ๋ชจ๋ ์ฝ๋์ ์๋์ผ๋ก withLogging() ํจ์๋ฅผ ์ ์ฉํด์ผ ํจ. ์ด๋ค ๋ถ๋ถ์ ๊น๋จน๊ณ ์ ์ฉ ์ํ ์ ๋ ์์.
wrap ํจํด์ ํจ์ ํฉํ ๋ฆฌ(factory) ๋ฅผ ์ฌ์ฉํ ๊ฒ. ํจ์๋ฅผ ๋ฆฌํดํ๋ ํจ์๋ ํจ์ ํฉํ ๋ฆฌ.
๐ ๊ณ ์ฐจ ํจ์ ์ ๋ฆฌ
๐ ํจ์ํ ๋ฐ๋ณต
// ์๋ณธ ํจ์
function emailsForCustomers(customers, goods, bests) {
var emails = [];
forEach(customers, function(customer) {
var email = emailForCustomer(customer, goods, bests);
emails.push(email);
});
return emails;
}
// map ํ์ฉ
function emailsForCustomers(customers, goods, bests) {
return map(customers, function(customer) {
return emailForCustomer(customer, goods, bests);
});
}
// ์๋ณธ ํจ์
function selectBestCustomers(customers) {
var newArray = [];
forEach(customers, function(customer) {
if (customer.purchases.length >= 3)
newArray.push(customer);
});
return newArray;
}
// filter ํ์ฉ
function selectBestCustomers(customers) {
return filter(customers, function(customer) {
return customer.purchases.length >= 3;
});
}
<๋ฐ์ท>
ํจ์๋ฅผ ๋ฆฌํดํ๋ ํจ์๋ ํจ์ ํฉํ ๋ฆฌ factory ์ ๊ฐ์ต๋๋ค.
์๋์ผ๋ก ์ ํํ๋ ์ฝ๋๋ฅผ ํจ์๋ก ๋ง๋ค ์ ์์ต๋๋ค.
ํจ์ ๊ณต์ฅ.
๋ง์ ํจ์ํ ํ๋ก๊ทธ๋๋จธ๋ ๊ณผ๋ํ๊ฒ ๋ชฐ๋ํ๊ธฐ ์ฝ์ต๋๋ค.
... (์ค๋ต) ...
๊ณ ์ฐจ ํจ์๋ก ๋ง๋ ์ข์ ๋ฐฉ๋ฒ์ ์ฐพ์๋ค๋ฉด, ์ง๊ด์ ์ธ ๋ฐฉ๋ฒ๊ณผ ํญ์ ๋น๊ตํด ๋ณด์ธ์. ์ด๋ค ๋ฐฉ๋ฒ์ด ๋ ์ข์๊น์?
- ์ฝ๋๊ฐ ๋ ์ฝ๊ธฐ ์ฌ์ด๊ฐ์?
- ์ผ๋ง๋ ๋ง์ ์ค๋ณต ์ฝ๋๋ฅผ ์์จ ์ ์๋์?
- ์ฝ๋๊ฐ ํ๋ ์ผ์ด ๋ฌด์์ธ์ง ์ฝ๊ฒ ์ ์ ์๋์?
์ด๋ฐ ์ง๋ฌธ๋ค์ ๋์น๋ฉด ์ ๋ฉ๋๋ค.
๊ณผ๋ชฐ์ ์ฃผ์. ํญ์ ์ค์ ์ฃผ์, ์ค์ฉ์ฃผ์.
<๋ฉ๋ชจ>
303p ~ 326p
<์์ฝ>
๐
reduce()
: ๋ฐฐ์ด์ ํ๋์ ๊ฐ์ผ๋ก "reduce"
// origin
function countAllPurchases(customers) {
var total = 0;
forEach(customers, function(cutomer) {
total = total + customer.purchases.length;
}
);
};
});
return total;
}
// with reduce
function countAllPurchases(customers) {
return reduce (customers, 0, function(total, customer) {
return total + customer.purchases.length;
}
);
}
function reduce(array, init, f) {
var accum = init;
forEach(array, function(elem) {
accum = f(accum, elem);
});
return accum;
}
๐ reduce ์ด๊ธฐ๊ฐ ์ฃผ์ํ ์
forEach
๊ฐ ์๋ฌด๊ฒ๋ ํ์ง ์์ผ๋ฏ๋ก ์ด๊ธฐ๊ฐ์ด ๊ทธ๋๋ก ๋ฆฌํด๋ ๊ฒ.๐ ์ธ ๊ฐ์ง ํจ์ํ ๋๊ตฌ ๋น๊ต
map
: ์ด๋ค ๋ฐฐ์ด์ ๋ชจ๋ ํญ๋ชฉ์ ํจ์๋ฅผ ์ ์ฉํด, ์๋ก์ด ๋ฐฐ์ด๋ก ๋ฐ๊พผ๋ค.
filter
: ์ด๋ค ๋ฐฐ์ด์ ํ์ ์งํฉ์ ์ ํํด ์๋ก์ด ๋ฐฐ์ด๋ก ๋ง๋ ๋ค.
reduce
: ์ด๋ค ๋ฐฐ์ด์ ํญ๋ชฉ์ ์กฐํฉํด ์ต์ข
๊ฐ์ ๋ง๋ญ๋๋ค. ๋ฐ์ดํฐ ์์ฝ or ์ํ์ค๋ฅผ ํ๋์ ๊ฐ์ผ๋ก ๋ง๋ค ๋ ์ฃผ๋ก ์ฌ์ฉ.
๐ ํจ์ํ ๋๊ตฌ ์ฒด์ธ
: ๋จ๊ณ๋ค์ ์กฐํฉํด ํ๋์ ์ฟผ๋ฆฌ๋ก ๋ง๋๋ ๊ฒ. ์ด ๊ณผ์ ์์ ํจ์ํ ๋๊ตฌ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ.
๐ ์ฒด์ธ ๋ช ํํ๊ฒ ๋ง๋ค๊ธฐ โก๏ธ "์ฝ๋ฐฑ์ ์ด๋ฆ ๋ถ์ด๊ธฐ" ๋ฅผ ์ ํธ.
// ์๋ ์ฝ๋
function biggestPurchasesBestCustomers(customers) {
var bestCustomers = filter(customers, function(customer) { // 1๋จ๊ณ
return customer.purchases.length >= 3;
});
var biggestPurchases = map(bestCustomers, function(customer) { // 2๋จ๊ณ
return maxKey(customer.purchases, {total: 0}, function(purchase) {
return purchase.total;
});
});
return biggestPurchases;
}
// 1. ๋จ๊ณ์ ์ด๋ฆ ๋ถ์ด๊ธฐ
function biggestPurchasesBestCustomers(customers) {
var bestCustomers = selectBestCustomers(customers); // 1๋จ๊ณ
var biggestPurchases = getBiggestPurchases(bestCustomers); // 2๋จ๊ณ
return biggestPurchases;
}
function selectBestCustomers(customers) {
return filter(customers, function(customer) { // ๊ทธ๋๋ก ๋ถ๋ฆฌ
return customer.purchases.length >= 3;
});
}
function getBiggestPurchases(customers) { // ๊ทธ๋๋ก ๋ถ๋ฆฌ
return map(customers, getBiggestPurchase);
}
function getBiggestPurchase(customer) { // ๊ทธ๋๋ก ๋ถ๋ฆฌ
return maxKey(customer.purchases, {total: 0}, function(purchase) { // ์ค์ฒฉ
return purchase.total; // ์ค์ฒฉ
});
}
// 2. ์ฝ๋ฐฑ์ ์ด๋ฆ ๋ถ์ด๊ธฐ
/// extracted and named callbacks
function biggestPurchasesBestCustomers(customers) {
var bestCustomers = filter(customers, isGoodCustomer); // ์ด๋ฆ๋ถ์ธ ์ฝ๋ฐฑ ์ ๋ฌ
var biggestPurchases = map(bestCustomers, getBiggestPurchase); // ์ด๋ฆ๋ถ์ธ ์ฝ๋ฐฑ ์ ๋ฌ
return biggestPurchases;
}
function isGoodCustomer(customer) {
return customer.purchases.length >= 3;
}
function getBiggestPurchase(customer) {
return maxKey(customer.purchases, {total: 0}, getPurchaseTotal);
}
function getPurchaseTotal(purchase) {
return purchase.total;
}
<๋ฐ์ท>
<๋ฉ๋ชจ>
327p ~ 346p
<์์ฝ>
๐ ์คํธ๋ฆผ ๊ฒฐํฉ (stream fusion)
map(), filter(), reduce() ์ฒด์ธ์ ์ต์ ํ ํ๋ ๊ฒ.
์ต์ ํ์ผ ๋ฟ์ด๊ณ ๋ณ๋ชฉ์ด ๋ฐ์ํ์ ๋๋ง ์ฌ์ฉํ๋ ๊ฒ์ด ์ข๋ค.
๋๋ถ๋ถ์ ๊ฒฝ์ฐ ์ฌ๋ฌ ๋จ๊ณ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ๋ ๋ช
ํํ๊ณ ์ฝ๊ธฐ ์ฝ๋ค.
/// Two map() steps in a row
var names = map(customers, getFullName);
var nameLengths = map(names, stringLength);
/// Equivalent as a single map() step
var nameLengths = map(customers, function(customer) {
return stringLength(getFullName(customer));
});
/// Two filter() steps in a row
var goodCustomers = filter(customers, isGoodCustomer);
var withAddresses = filter(goodCustomers, hasAddress);
/// Equivalent as a single filter() step
var withAddresses = filter(customers, function(customer) {
return isGoodCustomer(customer) && hasAddress(customer);
});
/// map() step followed by reduce() step
var purchaseTotals = map(purchases, getPurchaseTotal);
var purchaseSum = reduce(purchaseTotals, 0, plus);
/// Equivalent as a single reduce() step
var purchaseSum = reduce(purchases, 0, function(total, purchase) {
return total + getPurchaseTotal(purchase);
});
๐ ๋ฐ๋ณต๋ฌธ์ ํจ์ํ ๋๊ตฌ๋ก ๋ฆฌํฉํฐ๋ง ํ๊ธฐ
๋ฆฌํฉํฐ๋ง ํ ์ฝ๋.
๋ฐฐ์ด ํน์ ๋ถ๋ถ์ ์ฐ์๋ ๋ฐ์ดํฐ์ธ window
์ ํ๊ท ์ ๊ตฌํ๊ณ , ๊ฒฐ๊ณผ์ ์ถ๊ฐํ๋ค.
์ด๋ฅผ ๋ฐฐ์ด์ ์์๋ถํฐ ๋๊น์ง ๋ฐ๋ณต.
var answer = [];
var window = 5;
for(var i = 0; i < array.length; i++) {
var sum = 0;
var count = 0;
for(var w = 0; w < window; w++) { // 1
var idx = i + w; // 2
if(idx < array.length) {
sum += array[idx]; // 3
count += 1;
}
}
answer.push(sum/count);
}
Tip 1. ๋ฐ์ดํฐ๋ฅผ ๋ฐฐ์ด์ ๋ด๊ธฐ
์ฃผ์ 1, 2, 3 ์ ๋ณด๋ฉด, ๊ฐ์ด ๊ณ์ ๋ฐ๋์ง๋ง ๋ฐฐ์ด๋ก ๋ง๋ค์ง๋ ์๊ณ ์๋ค.
๋ฐ์ดํฐ๋ฅผ ๋ฐฐ์ด์ ๋ฃ์ผ๋ฉด ํจ์ํ ๋๊ตฌ๋ฅผ ์ธ ์ ์๋ค.
์ฝ๋๋ฅผ ๋ณด๋ฉด ๋ฐ๋ณต๋ฌธ์ ํตํด์ window
๋ผ๋ ๋ฒ์๋ฅผ ์ถ์์ ์ผ๋ก ์ฌ์ฉํ๋๋ฐ, ์ด๋ฅผ ๋ช
์์ ์ธ ๋ฐฐ์ด๋ก ์ถ์ถํ๋ฉด ํจ์ํ ๋๊ตฌ๋ฅผ ์ธ ์ ์๊ฒ๋๋ค.
/// make subarray
var answer = [];
var window = 5;
for(var i = 0; i < array.length; i++) {
var sum = 0;
var count = 0;
var subarray = array.slice(i, i + window); //here
for(var w = 0; w < subarray.length; w++) {
sum += subarray[w];
count += 1;
}
answer.push(sum/count);
}
Tip 2. ํ ๋ฒ์ ์ ์ฒด ๋ฐฐ์ด์ ์กฐ์ํ๊ธฐ
์์์ ๋ฐ์ดํฐ๋ฅผ ๋ฐฐ์ด๋ก ๋ง๋ ๊ฒ์, ํจ์ํ ๋๊ตฌ๋ฅผ ์ด์ฉํด 'ํ ๋ฒ์' ์กฐ์ํ๋ค.
/// Using average
var answer = [];
var window = 5;
for(var i = 0; i < array.length; i++) {
var subarray = array.slice(i, i + window);
answer.push(average(subarray));
}
๊ฐ์ฅ ์์์ for
๋ฌธ ์์๋, i
๊ฐ์ด ๊ณ์ ๋ฐ๋๋ฉด์ ์ฌ์ฉ๋๊ณ ์์ง๋ง, ๋ฐฐ์ด๋ก ๋ง๋ค์ด์ง์ง๋ ์๊ณ ์๋ค.
์ด ๋ํ 1) ๋ฐ์ดํฐ๋ฅผ ๋ฐฐ์ด์ ๋ฃ๊ณ , 2) ํ ๋ฒ์ ์กฐ์ํ๋๋ก ๊ฐ์ ํ๋ค.
// make range (set of indices)
function range(start, end) {
var ret = [];
for(var i = start; i < end; i++)
ret.push(i);
return ret;
}
var indices = range(0, array.length);
var window = 5;
var answer = map(indices, function(i) {
var subarray = array.slice(i, i + window);
return average(subarray);
});
Tip 3. ์์ ๋จ๊ณ๋ก ๋๋๊ธฐ
ํ์ฌ map()
์ ๋๊ธฐ๋ ์ฝ๋ฐฑ์์ ๋ ๊ฐ์ง์ ์ผ์ ํ๊ณ ์๋ค.
์ด๋ฅผ ์์ ๋จ๊ณ๋ก ๋๋์ด ์์ ์ด ๋ ๋ช ํํ๊ฒ ๋ณด์ด๋๋ก ํ๋ค.
/// in two steps
var indices = range(0, array.length);
var window = 5;
var windows = map(indices, function(i) { // make subset
return array.slice(i, i + window);
});
var answer = map(windows, average); // calculate average
๐ ๊ฒฐ๊ณผ
๋ฐฐ์ด์ ์ด๋ํ๋ฉฐ ํ๊ท ๊ตฌํ๊ธฐ
1. ์ซ์ ๋ฆฌ์คํธ๊ฐ ์์ ๋ ๊ฐ ์ซ์์ ๋ํ window๋ฅผ ๋ง๋ญ๋๋ค.
2. ๊ทธ๋ฆฌ๊ณ ๊ฐ window์ ํ๊ท ์ ๊ตฌํฉ๋๋ค.
๐ ์ฒด์ด๋ ํ ์์ฝ
map()
, filter()
, reduce()
๋ ํจ์ํ ๋๊ตฌ์ ์ ๋ถ๊ฐ ์๋๋ค. ํจ์๋ฅผ ์ถ์ถํ๊ณ ์ข์ ์ด๋ฆ์ ๋ถ์ฌ ์ฌ์ฉํ์!์ฒด์ด๋ ๋๋ฒ๊น ์ ์ํ ํ
print
๋ฌธ. ๊ฐ ๋จ๊ณ๋ฅผ ์ถ๋ ฅํด ๋ณด๋ฉด์ ํ์ธ.
map()
์ด ๋ฆฌํดํ๋ ์๋ก์ด ๋ฐฐ์ด์๋, ์ฝ๋ฐฑ์ด ๋ฆฌํดํ๋ ํ์ ์ ๊ฐ.reduce()
์ ๊ฒฐ๊ณผ๊ฐ์ ํ์ ์, ์ด๊ธฐ๊ฐ์ ํ์ ๊ทธ๋ฆฌ๊ณ ์ฝ๋ฐฑ์ด ๋ฆฌํดํ๋ ๊ฐ์ ํ์ ๊ณผ ๊ฐ๋ค.
<๋ฉ๋ชจ>
๋ฆฌํฉํ ๋ง ๋ ๋ชจ์ต์ ๋ณด๋ ๊น๋ํ๊ธด ํ๋ค...
347p ~ 370p
<์์ฝ>
๐ reduce()
๋ ๊ฐ์ ์์ฝํ๊ธฐ๋ ํ์ง๋ง, ๊ฐ์ ๋ง๋ค ์๋ ์๋ค.
์ ์ ๊ฐ ์ฅ๋ฐ๊ตฌ๋๋ฅผ ์์ด๋ฒ๋ ธ์ง๋ง ์ฅ๋ฐ๊ตฌ๋์ ์ถ๊ฐํ ์ ํ์ ๋ชจ๋ ๋ฐฐ์ด๋ก ๋ก๊น
ํ๊ณ ์์์ ๋,
reduce()
๋ฅผ ํ์ฉํด ์๋์ ๊ฐ์ด ์ฅ๋ฐ๊ตฌ๋๋ฅผ ๋ค์ ๋ง๋ค ์๋ ์๊ณ ,
var itemsAdded = ["shirt", "shoes", "shirt", "socks", "...."];
var shoppingCart = reduce(itemsAdded, {}, addOne);
function addOne(cart, item) {
if(!cart[item])
return add_item(cart, {name: item, quantity: 1, price: priceLookup(item)});
else {
var quantity = cart[item].quantity;
return setFieldByName(cart, item, 'quantity', quantity + 1)
}
}
์๋์ ๊ฐ์ด ๊ตฌ์ฒด์ ์ธ ๋์๋ ์ถ๊ฐํด ๋ณผ ์ ์๋ค.
var itemOps = [['add', "shirt"],
['add', "shoes"],
['remove', "shirt"],
['add', "socks"],
['remove', "hat"],
];
var shoppingCart = reduce(itemOps, {}, function(cart, itemOp) {
var op = itemOp[0];
var item = itemOp[1];
if(op === 'add') return addOne(cart, item);
if(op === 'remove') return removeOne(cart, item);
});
function removeOne(cart, item) {
if(!cart[item])
return cart;
else {
var quantity = cart[item].quantity;
if(quantity === 1)
return remove_item_by_name(cart, item);
else
return setFieldByName(cart, item, 'quantity', quantity - 1)
}
}
์ด๋ ๊ฒ ๋ฐ์ดํฐ๋ฅผ ์ธ์์ฒ๋ผ ํ์ฉํ์ฌ ์ฝ๋๋ฅผ ์์ฑํ ์๋ ์๋ค. ์ ์ฉํ๋ค.
๐ ๊ฐ์ฒด๋ฅผ ๋ค๋ฃจ๊ธฐ ์ํ ๊ณ ์ฐจํจ์ : update()
์ด์ ๊น์ง์ map()
, filter()
, reduce()
๋ ๋ฐฐ์ด์ ๋ค๋ฃจ๋ ๊ณ ์ฐจํจ์.
๊ฐ์ฒด๋ฅผ ๋ค๋ฃจ๋ ํจ์๋ฅผ ๋ฆฌํฉํ ๋ง ํด๋ณด๋ฉด์ update()
๋ฅผ ๋์ถํด๋ณด์.
// ์๋ ์ฝ๋
function incrementSize(item) {
var size = item['size'];
var newSize = size + 1;
var newItem = objectSet(item, 'size', newSize);
return newItem;
}
/// After expressing argument
function incrementField(item, field) {
var value = item[field];
var newValue = value + 1;
var newItem = objectSet(item, field, newValue);
return newItem;
}
/// Extracted
function incrementField(item, field) {
return updateField(item, field, function(value) {
return value + 1;
});
}
function updateField(item, field, modify) {
var value = item[field];
var newValue = modify(value);
var newItem = objectSet(item, field, newValue);
return newItem;
}
// ์ข ๋ ์ผ๋ฐ์ ์ธ ํจ์ ์๊ทธ๋์ฒ๋ก ๋ณ๊ฒฝ
/// Called update()
function update(object, key, modify) {
var value = object[key];
var newValue = modify(value);
var newObject = objectSet(object, key, newValue);
return newObject;
}
๐ ํจ์ํ ๋๊ตฌ update()
function update(object, key, modify) {
var value = object[key];
var newValue = modify(value);
var newObject = objectSet(object, key, newValue);
return newObject;
}
๊ฐ์ฒด์ ํ๋์ ํค์ ํ๋์ ๊ฐ์ ๋ณ๊ฒฝํ๋ค. like ์ธ๊ณผ ์์
{
key1: X1,
key2: Y1,
key3: Z1,
}
โฌ๏ธ
modifyY()
โฌ๏ธ
{
key1: X1,
key2: Y2, // here
key3: Z1,
}
<๋ฐ์ท>
<๋ฉ๋ชจ>
๋ค์ ์๊ฐ์ update()
๋ฅผ ํ์ฉํด์,
์กฐํํ๊ณ ๋ณ๊ฒฝํ๊ณ ์ค์ ํ๋ ๊ฒ์ update()
๋ก ๊ต์ฒดํ๊ธฐ ๋ฆฌํฉํฐ๋ง์ ํด๋ณด์.
371p ~ 394p
<์์ฝ>
๐ "์กฐํํ๊ณ ๋ณ๊ฒฝํ๊ณ ์ค์ ํ๋ ๊ฒ์ update()
๋ก ๊ต์ฒดํ๊ธฐ" ๋ฆฌํฉํฐ๋ง
/// Step 1: Identify get, modify, set
function halveField(item, field) {
var value = item[field]; // get
var newValue = value / 2; // modify
var newItem = objectSet(item, field, newValue); // set
return newItem;
}
/// Step 2: Replace with call to update()
function halveField(item, field) {
return update(item, field, function(value) {
return value / 2;
});
}
๐ ์ค์ฒฉ๋ ๋ฐ์ดํฐ์ update() ์ฌ์ฉํ๊ธฐ
function incrementSize(item) {
var options = item.options; // 1. ์กฐํ
var size = options.size; // 2. ์กฐํ
var newSize = size + 1; // 2. ๋ณ๊ฒฝ
var newOptions = objectSet(options, 'size', newSize); // 2. ์ค์ // 1. ๋ณ๊ฒฝ
var newItem = objectSet(item, 'options', newOptions); // 1. ์ค์
return newItem;
}
/// Refactored
function incrementSize(item) {
var options = item.options; // 1. ์กฐํ
var newOptions = update(options, 'size', increment); // here // 1. ๋ณ๊ฒฝ
var newItem = objectSet(item, 'options', newOptions); // 1. ์ค์
return newItem;
}
/// Refactored twice
function incrementSize(item) {
return update(item, 'options', function(options) { // here
return update(options, 'size', increment);
});
}
๐ update2()
๋์ถํ๊ธฐ
update2()
๋ฅผ ๋์ถํ ์ ์๋ค.function incrementSize(item) { // 1. "Size" -> (option)
return update(item, 'options', function(options) {
return update(options, 'size', increment); // 1. "'size'" -> (option)
});
}
/// 1. With explicit option argument
function incrementOption(item, option) { // 2. "increment" -> (modify)
return update(item, 'options', function(options) {
return update(options, option, increment); // 2. "increment" -> (modify)
});
}
/// 2. With explicit modify argument
function updateOption(item, option, modify) { // 3-1. "Option" -> (key1) // 3-2. "option" -> (key2)
return update(item, 'options', function(options) { // 3-1. "'options'" -> (key1)
return update(options, option, modify); // 3-2. "option" -> (key2)
});
}
/// 3. With explicit argument
function update2(object, key1, key2, modify) {
return update(object, key1, function(value1) {
return update(value1, key2, modify);
});
}
/// cc. Original
function incrementSize(item) {
var options = item.options;
var size = options.size;
var newSize = size + 1;
var newOptions = objectSet(options, 'size', newSize);
var newItem = objectSet(item, 'options', newOptions);
return newItem;
}
๐ update3()
๋์ถํ๊ธฐ
function update3(object, key1, key2, key3, modify) {
return update(object, key1, function(object2) {
return update2(object2, key2, key3, modify);
});
}
๐ nestedUpdate()
๋์ถํ๊ธฐ
function nestedUpdate(object, keys, modify) {
if(keys.length === 0) // base case
return modify(object);
var key1 = keys[0];
var restOfKeys = drop_first(keys);
return update(object, key1, function(value1) {
return nestedUpdate(value1, restOfKeys, modify);
});
}
๐ ๊น์ด ์ค์ฒฉ๋ ๋ฐ์ดํฐ์ ์ถ์ํ ๋ฒฝ ์ฌ์ฉํ๊ธฐ
๊น์ด ์ค์ฒฉ๋ ๊ตฌ์กฐ์ nestedUpdate()
๋ฅผ ์ฐ๋ ค๋ฉด ๊ธด key ๊ฒฝ๋ก ๋ฐฐ์ด์ด ํ์ํ๋ค.
์ด๊ฒ์ด ๋๋ฌด ๊ธธ๋ฉด ์ค๊ฐ์ ์๋ ๊ฐ์ฒด๋ค์ด ์ด๋ค ํค๋ฅผ ๊ฐ์ก๋์ง, ๊ตฌ์กฐ๋ฅผ ๊ธฐ์ตํ๊ธฐ ์ด๋ ต๋ค.
์๋ฅผ ๋ค์ด, ์๋์ ๊ฐ์ ์ฝ๋๊ฐ ์๋ค.
httpGet("http://my-blog.com/api/category/blog", function(blogCategory) {
renderCategory(nestedUpdate(blogCategory, ['posts', '12', 'author', 'name'], capitalize));
});
api๋ก ๊ฐ์ ธ์จ ๊ฐ blogCategory
๋ฅผ ์ฝ๋ฐฑ์ ํตํด ์ฒ๋ฆฌํ๋ ์ฝ๋์ด๋ค.
์ด ์ฝ๋๋ ๋ค์๊ณผ ๊ฐ์ ์ดํด๋ฅผ ํจ์ถํ๊ณ ์๋ค.
blogCategory
๋ posts
key ์๋ "๋ธ๋ก๊ทธ ๊ธ"์ ๋ด๊ณ ์๋ ๊ตฌ์กฐ์ด๋ค.ID
(12) ๋ฅผ ํตํด ์ ๊ทผํ ์ ์๋ค.author
key ์๋ "๊ธ์ด์ด"๋ฅผ ๋ด๊ณ ์๋ ๊ตฌ์กฐ์ด๋ค.name
key ์๋ "์ฌ์ฉ์ ์ด๋ฆ"์ ๋ด๊ณ ์๋ ๊ตฌ์กฐ์ด๋ค.๊ฒฝ๋ก๋ง ๋ณด๊ณ , ์ด ๋ชจ๋ ์ ๋ณด๋ฅผ ๊ธฐ์ตํ๊ธฐ๋ ์ฝ์ง ์๋ค.
๊ทธ๋์, ์ถ์ํ ๋ฒฝ์ ๋ง๋ค๊ณ ์๋ฏธ์๋ ์ด๋ฆ์ ๋ถ์ฌ, ๊ตฌํ์ ๊ฐ์ถ๊ณ ๊ธฐ์ตํด์ผ ํ ์ ์ ์ค์ผ ์ ์๋ค.
๋ค์ ๋งํด, ์ถ์ํ ๋ฒฝ์ ์กด์ฌํ๋ ํจ์ ์์ ์ด ํด๋น ๊ตฌํ์ ๋ณธ๋ฌธ์ ํ๊ณ ์์ผ๋ฉด ๋๋ค.
ID
๋ก "๋ธ๋ก๊ทธ ๊ธ"์ ๋ณ๊ฒฝํ๋ ํจ์๋ฅผ ๋ง๋ ๋ค.function updatePostById(category, id, modifyPost) {
return nestedUpdate(category, ['posts', id], modifyPost); // modifyPost // ๋ธ๋ก๊ทธ ๊ธ ๊ตฌ์กฐ์ ๋ํด์๋ ์ฝ๋ฐฑ์ ๋งก๊ธด๋ค. -> 2.
// key ๊ฒฝ๋ก ๋ฐฐ์ด์ ํจ์ถ๋ category์ ๊ตฌ์กฐ๋ ์ถ์ํ ๋ฒฝ ๋ค๋ก ์จ๊ธด๋ค.
// ์ฆ, ์ด ํจ์ ์์ ์ด ์ฌ๊ธฐ(๋ณธ๋ฌธ)์ ํ๋๋ค.
}
function updateAuthor(post, modifyUser) {
return update(post, 'author', modifyUser); // modifyUser // ์ฌ์ฉ์ ๊ตฌ์กฐ์ ๋ํด์๋ ์ฝ๋ฐฑ์ ๋งก๊ธด๋ค. -> 3.
// ๋ธ๋ก๊ทธ ๊ธ์ ๊ตฌ์กฐ๋ ์ด ํจ์ ์์ ์ด ์ฌ๊ธฐ(๋ณธ๋ฌธ)์ ํ๋๋ค.
}
function capitalizeName(user) {
return update(user, 'name', capitalize);
// ์ฌ์ฉ์์ ๊ตฌ์กฐ๋ ์ด ํจ์ ์์ ์ด ์ฌ๊ธฐ(๋ณธ๋ฌธ)์ ํ๋๋ค.
}
updatePostById(blogCategory, '12', function(post) {
return updateAuthor(post, capitalizeUserName);
});
๊ธฐ์ตํด์ผ ํ ์ฌํญ์ด ๊ฐ๋จํด ์ก๋ค.
๐ ๊ณ ์ฐจ ํจ์ ์ฒญ๋ฆฌ
forEach()
, map()
, filter()
, reduce()
update()
, nestedUpdate()
withArrayCopy()
, withObjectCopy()
wrapLogging()
<๋ฉ๋ชจ>
๋ค์ ์๊ฐ๋ถํด ๋๋์ด ๋ถ์ฐ ์์คํ
์ ๋ํด์ ์์๋ณด์.
395p ~ 419p
<์์ฝ>
ํ์๋ผ์ธ์๋ ์ก์ ๋ง ๊ทธ๋ฆฐ๋ค.
๋ ์ก์ ์ด ์์๋๋ก ๋ํ๋๋ฉด ๊ฐ์ ํ์๋ผ์ธ์ ๋ฃ๋๋ค.
sendEmail1();
sendEmail2();
setTimeout(sendEmail1, Math.random()*10000);
setTimeout(sendEmail2, Math.random()*10000);
โก๏ธ ์ก์ ์ด ์๋ก ๋ค๋ฅธ ์ค๋ ๋, ํ๋ก์ธ์ค, ๊ธฐ๊ณ, ๋น๋๊ธฐ ์ฝ๋ฐฑ ์์ ์คํ๋๋ฉด ์๋ก ๋ค๋ฅธ ํ์๋ผ์ธ์ ํ์ํ๋ค.
++
์ +=
๋ ์ธ ๋จ๊ณ์ด๋ค.
total++
// origin
var temp = total; // ์ฝ๊ธฐ (์ก์
)
temp = temp + 1; // ๋ํ๊ธฐ (๊ณ์ฐ)
total = temp; // ์ฐ๊ธฐ (์ก์
)
โก๏ธ ๋ฐ๋ผ์ ๋ ๊ฐ์ ์ก์ ์ผ๋ก ๋ค์ด์ด๊ทธ๋จ์ ํ์ํด์ผ ํจ.
์ธ์๋ ํจ์๋ฅผ ๋ถ๋ฅด๊ธฐ ์ ์ ์คํํ๋ค.
console.log(total);
// origin
temp = total;
console.log(temp);
โก๏ธ ์ ์ญ ๋ณ์๋ฅผ ์ฝ๋ ๊ฒ๋ ์ก์ ์์ ๊ธฐ์ต.
function add_item_to_cart(name, price, quantity) {
cart = add_item(cart, name, price, quantity); // cart ์ฝ๊ธฐ, ์ฐ๊ธฐ
calc_cart_total();
}
function calc_cart_total() {
total = 0; // total ์ฐ๊ธฐ
cost_ajax(cart, function(cost) { // cart ์ฝ๊ธฐ // cost_ajax ํธ์ถํ๊ธฐ
total += cost; // total ์ฝ๊ธฐ, ์ฐ๊ธฐ
shipping_ajax(cart, function(shipping) { // cart ์ฝ๊ธฐ // shipping_ajax ํธ์ถํ๊ธฐ
total += shipping; // total ์ฝ๊ธฐ, ์ฐ๊ธฐ
update_total_dom(total); // total ์ฝ๊ธฐ // update_total_dom ํธ์ถํ๊ธฐ
});
});
}
๊ฐ ์ก์ ์ ๊ทธ๋ฆฐ๋ค.
๋น๋๊ธฐ ์ฝ๋ฐฑ์ ์๋ก์ด ํ์๋ผ์ธ์ ํ์ํด์ผ ํ๋ค.
์คํ ์์๋ฅผ ์ ํํ๊ธฐ ์ํด ์ ์ ์ ์ฌ์ฉํ๋ค. (ajax ์ฝ๋ฐฑ์ ajax ์์ฒญ ์ ์ ์คํํ ์ ์๋ค)
๋ค๋ฅธ ์์>
saveUserAjax(user, function() {
setUserLoadingDOM(false); // ์ฝ๋ฐฑ ๋ด์ฉ
});
setUserLoadingDOM(true);
saveDocumentAjax(document, function() {
setDocLoadingDOM(false); // ์ฝ๋ฐฑ ๋ด์ฉ
});
setDocLoadingDOM(true);
์ฝ๋ฐฑ์ ๋น๋๊ธฐ๋ก ์คํ๋๊ธฐ ๋๋ฌธ์ ์์ฒญ์ด ๋๋๋ ์์ ์ ์ธ์ ๊ฐ ์คํ๋ ๊ฒ์์ ์ ์.
๋จ์ํํ๋ค.
๋ค๋ฅธ ์์>
์๋๋ ์๋ก์ด ํ์๋ผ์ธ์ด ๋ ๊ฐ ์๊ฒผ๊ธฐ ๋๋ฌธ์ ํตํฉํ ์ ์๋ค.
์ ์ฒด ํ์๋ผ์ธ์ ๊ฐ์๊ฐ ์ ์์๋ก ์ดํดํ๊ธฐ ์ฝ๋ค.
ํ์๋ผ์ธ ๋ด ๋จ๊ณ์ ๊ฐ์๊ฐ ์ ์์๋ก ์ดํดํ๊ธฐ ์ฝ๋ค.
๊ณต์ ํ๋ ์์์ด ์ ์์๋ก ์ดํดํ๊ธฐ ์ฝ๋ค.
์์์ ๊ณต์ ํ๋ค๋ฉด ์๋ก ์กฐ์จํด์ผ ํ๋ค.
์๊ฐ์ ์ผ๊ธ์ผ๋ก ๋ค๋ฃฌ๋ค.
- click ์ด๋ฒคํธ ๋์ ๊ณผ์ :
์ด๋ฒคํธ์ ์ฝ๋ฐฑ์ ๋ฑ๋ก -> ์ด๋ฒคํธ ๋ฐ์ -> ์์
ํ์ ์์
( ์ด๋ฒคํธ ๋ฐ์ดํฐ
(click
) + ์ฝ๋ฐฑ
) ์ถ๊ฐ -> ์ด๋ฒคํธ ๋ฃจํ๊ฐ ์ฝ๋ฐฑ ์คํload
๋๋ error
์ด๋ฒคํธ์ ์ฝ๋ฐฑ์ด ๋ฑ๋ก ๋จ -> ์ด๋ฒคํธ ๋ฐ์(์๋ต ๋์ฐฉ or ์๋ฌ) -> ์์
ํ์ ์์
( ์ด๋ฒคํธ ๋ฐ์ดํฐ
(load
orerror
) + ์ฝ๋ฐฑ
) ์ถ๊ฐ -> ์ด๋ฒคํธ ๋ฃจํ๊ฐ ์ฝ๋ฐฑ ์คํ์ธ์ด๋ณ ์ฌ์ฉํ๋ ์ค๋ ๋ ๋ชจ๋ธ
420p ~ 440p
<์์ฝ>
/// Original
function calc_cart_total(cart) {
var total = 0;
cost_ajax(cart, function(cost) {
total += cost;
shipping_ajax(cart, function(shipping) {
total += shipping;
update_total_dom(total); // here
});
});
}
function add_item_to_cart(name, price, quant) {
cart = add_item(cart, name, price, quant);
calc_cart_total(cart);
}
/// With extracted callback
function calc_cart_total(cart, callback) {
var total = 0;
cost_ajax(cart, function(cost) {
total += cost;
shipping_ajax(cart, function(shipping) {
total += shipping;
callback(total); // here
});
});
}
function add_item_to_cart(name, price, quant) {
cart = add_item(cart, name, price, quant);
calc_cart_total(cart, update_total_dom);
}
<๋ฐ์ท>
<๋ฉ๋ชจ>
441p ~ 468p
<์์ฝ>
์ ์ฒด ํ์๋ผ์ธ์ ๊ฐ์๊ฐ ์ ์์๋ก ์ดํดํ๊ธฐ ์ฝ๋ค.
ํ์๋ผ์ธ ๋ด ๋จ๊ณ์ ๊ฐ์๊ฐ ์ ์์๋ก ์ดํดํ๊ธฐ ์ฝ๋ค.
๊ณต์ ํ๋ ์์์ด ์ ์์๋ก ์ดํดํ๊ธฐ ์ฝ๋ค.
์์์ ๊ณต์ ํ๋ค๋ฉด ์๋ก ์กฐ์จํด์ผ ํ๋ค.
์๊ฐ์ ์ผ๊ธ์ผ๋ก ๋ค๋ฃฌ๋ค.
์์์ ๊ณต์ ํ๋ "์ก์ "๋ค์ด ์คํ๋๋ ์์๋ฅผ ๊ณ ๋ คํ๋ ๊ณผ์ ์ด๋ค.
function add_item_to_cart(item) {
cart = add_item(cart, item);
calc_cart_total(cart, update_total_dom);
}
function calc_cart_total(cart, callback) {
var total = 0;
cost_ajax(cart, function(cost) {
total += cost;
shipping_ajax(cart, function(shipping) {
total += shipping;
callback(total);
});
});
}
function add_item_to_cart(item) {
cart = add_item(cart, item);
update_total_queue(cart); // action
}
function calc_cart_total(cart, callback) {
var total = 0;
cost_ajax(cart, function(cost) {
total += cost;
shipping_ajax(cart, function(shipping) {
total += shipping;
callback(total);
});
});
}
var queue_items = [];
function runNext() {
var cart = queue_items.shift();
calc_cart_total(cart, update_total_dom);
}
function update_total_queue(cart) { // action
queue_items.push(cart);
setTimeout(runNext, 0);
}
function add_item_to_cart(item) {
cart = add_item(cart, item);
update_total_queue(cart);
}
function calc_cart_total(cart, callback) {
var total = 0;
cost_ajax(cart, function(cost) {
total += cost;
shipping_ajax(cart, function(shipping) {
total += shipping;
callback(total);
});
});
}
var queue_items = [];
var working = false; ////
function runNext() {
if(working) ////
return; ////
working = true; ////
var cart = queue_items.shift();
calc_cart_total(cart, update_total_dom);
}
function update_total_queue(cart) {
queue_items.push(cart);
setTimeout(runNext, 0);
}
var queue_items = [];
var working = false;
function runNext() {
if(working)
return;
working = true;
var cart = queue_items.shift();
calc_cart_total(cart, function(total) {
update_total_dom(total);
working = false; ////
runNext(); ////
});
}
function update_total_queue(cart) {
queue_items.push(cart);
setTimeout(runNext, 0);
}
var queue_items = [];
var working = false;
function runNext() {
if(working)
return;
if(queue_items.length === 0) ////
return; ////
working = true;
var cart = queue_items.shift();
calc_cart_total(cart, function(total) {
update_total_dom(total);
working = false;
runNext();
});
}
function update_total_queue(cart) {
queue_items.push(cart);
setTimeout(runNext, 0);
}
function Queue() { ////
var queue_items = [];
var working = false;
function runNext() {
if(working)
return;
if(queue_items.length === 0)
return;
working = true;
var cart = queue_items.shift();
calc_cart_total(cart, function(total) {
update_total_dom(total);
working = false;
runNext();
});
}
return function(cart) { ////
queue_items.push(cart);
setTimeout(runNext, 0);
};
}
var update_total_queue = Queue(); ////
function Queue(worker) {
var queue_items = [];
var working = false;
function runNext() {
if(working)
return;
if(queue_items.length === 0)
return;
working = true;
var cart = queue_items.shift();
worker(cart, function() { //// done()
working = false;
runNext();
});
}
return function(cart) {
queue_items.push(cart);
setTimeout(runNext, 0);
};
}
function calc_cart_worker(cart, done) { ////
calc_cart_total(cart, function(total) {
update_total_dom(total);
done(total); //// done()
});
}
var update_total_queue = Queue(calc_cart_worker);
function Queue(worker) {
var queue_items = [];
var working = false;
function runNext() {
if(working)
return;
if(queue_items.length === 0)
return;
working = true;
var item = queue_items.shift();
worker(item.data, function(val) { ////
working = false;
setTimeout(item.callback, 0, val); ////
runNext();
});
}
return function(data, callback) {
queue_items.push({
data: data, ////
callback: callback || function(){} ////
});
setTimeout(runNext, 0);
};
}
function calc_cart_worker(cart, done) {
calc_cart_total(cart, function(total) {
update_total_dom(total);
done(total);
});
}
var update_total_queue = Queue(calc_cart_worker);
/// Dropping Queue
function DroppingQueue(max, worker) {
var queue_items = [];
var working = false;
function runNext() {
if(working)
return;
if(queue_items.length === 0)
return;
working = true;
var item = queue_items.shift();
worker(item.data, function(val) {
working = false;
setTimeout(item.callback, 0, val);
runNext();
});
}
return function(data, callback) {
queue_items.push({
data: data,
callback: callback || function(){}
});
while(queue_items.length > max)
queue_items.shift();
setTimeout(runNext, 0);
};
}
function calc_cart_worker(cart, done) {
calc_cart_total(cart, function(total) {
update_total_dom(total);
done(total);
});
}
var update_total_queue = DroppingQueue(1, calc_cart_worker);
์ ๋ฆฌ
Queue()
๋ ํจ์๋ฅผ ์ธ์๋ก ๋ฐ์ ๋ ๋ค๋ฅธ ํจ์๋ฅผ ๋ฆฌํดํ๋ ํจ์์ด๋ค.Queue()
๋ ์ด๋ค ํจ์๋ฅผ ์๋ก์ด ํ์๋ผ์ธ์์ ์คํํ๊ณ ํ ๋ฒ์ ํ ํ์๋ผ์ธ๋ง ์คํํ ์ ์๋๋ก ๋ง๋ค์ด์ฃผ๋ ๊ณ ์ฐจํจ์์ด๋ค.Queue()
๋ ์ก์
์ '์์ ๋ณด์ฅ' ์ํผํ์๋ฅผ ์ฃผ๋ ๋๊ตฌ์ด๋ค.Queue()
๋ ๋์์ฑ ๊ธฐ๋ณธํ(concurrency primitive) ์ด๋ค.๐ก ๊ณต์ ํ๋ ๋ฐฉ๋ฒ์ ํ์ค์์ ์ฐฉ์ํ๊ธฐ
์ธ๊ฐ์ ์ธ์ ๋ ์์์ ๊ณต์ ํ๋ค. ์ด๋ฅผ ์ฐฉ์ํ์ฌ, ์ปดํจํฐ์๊ฒ๋ ์ธ๊ฐ์ ๋ฐฉ๋ฒ๊ณผ ๋น์ทํ๊ฒ ์์์ ๊ณต์ ํ ์ ์๋๋ก ํ๋ก๊ทธ๋๋ฐ ํ ์ ์๋ค.
ํ์ค์์ ์ด๋ค ์ผ์ด ์์๋๋ก ์งํ๋๊ฒ ํ๋ ๋ฐฉ๋ฒ์ ํ๋๋ ์ค์ ์๋ ๊ฒ -> queue๋ฅผ ๋ง๋ค์ด ์ปดํจํฐ๊ฐ ์์ ์ ์์๋๋ก ์งํํ๊ฒ ํ๋๋ก ํ๋ค.
๋ค๋ฅธ ์
1. ํ ๋ฒ์ ํ ๋ช
์ฉ ์ธ ์ ์๊ฒ ํ์ฅ์ค ๋ฌธ์ ์ ๊ธ ์ ์๋ค.
2. ๊ณต๊ณต ๋์๊ด์ ์ง์ญ์ฌํ๊ฐ ๋ง์ ์ฑ
์ ๊ณต์ ํ ์ ์๋ ๊ณณ์ด๋ค.
3. ์น ํ์ ์ฌ์ฉํ๋ฉด ์ ์๋(๊ธฐ๋ก์) ํ๋ช
์ด ๊ต์ค ์ ์ฒด(์ด๋์)์ ์ ๋ณด๋ฅผ ๊ณต์ ํ ์ ์๋ค.
๋์์ฑ ๊ธฐ๋ณธํ(concurrency primitive)์ ์์์ ์์ ํ๊ฒ ๊ณต์ ํ ์ ์๋ ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ์ฝ๋๋ฅผ ๋งํฉ๋๋ค.
<๋ฉ๋ชจ>
์ ์ ๋จ์ ํ์ด์ง๊ฐ ์ค์ด๋ค๊ณ ์๋ค.
469p ~ 490p
<์์ฝ>
์ ์ฒด ํ์๋ผ์ธ์ ๊ฐ์๊ฐ ์ ์์๋ก ์ดํดํ๊ธฐ ์ฝ๋ค.
ํ์๋ผ์ธ ๋ด ๋จ๊ณ์ ๊ฐ์๊ฐ ์ ์์๋ก ์ดํดํ๊ธฐ ์ฝ๋ค.
๊ณต์ ํ๋ ์์์ด ์ ์์๋ก ์ดํดํ๊ธฐ ์ฝ๋ค.
์์์ ๊ณต์ ํ๋ค๋ฉด ์๋ก ์กฐ์จํด์ผ ํ๋ค.
์๊ฐ์ ์ผ๊ธ์ผ๋ก ๋ค๋ฃฌ๋ค.
์์์ ๊ณต์ ํ๋ "์ก์ "๋ค์ด ์คํ๋๋ ์์๋ฅผ ๊ณ ๋ คํ๋ ๊ณผ์ ์ด๋ค.
function add_item_to_cart(item) {
cart = add_item(cart, item);
calc_cart_total(cart, update_total_dom);
}
function calc_cart_total(cart, callback) {
var total = 0;
cost_ajax(cart, function(cost) {
total += cost;
shipping_ajax(cart, function(shipping) {
total += shipping;
callback(total);
});
});
}
function add_item_to_cart(item) {
cart = add_item(cart, item);
update_total_queue(cart); // action
}
function calc_cart_total(cart, callback) {
var total = 0;
cost_ajax(cart, function(cost) {
total += cost;
shipping_ajax(cart, function(shipping) {
total += shipping;
callback(total);
});
});
}
var queue_items = [];
function runNext() {
var cart = queue_items.shift();
calc_cart_total(cart, update_total_dom);
}
function update_total_queue(cart) { // action
queue_items.push(cart);
setTimeout(runNext, 0);
}
function add_item_to_cart(item) {
cart = add_item(cart, item);
update_total_queue(cart);
}
function calc_cart_total(cart, callback) {
var total = 0;
cost_ajax(cart, function(cost) {
total += cost;
shipping_ajax(cart, function(shipping) {
total += shipping;
callback(total);
});
});
}
var queue_items = [];
var working = false; ////
function runNext() {
if(working) ////
return; ////
working = true; ////
var cart = queue_items.shift();
calc_cart_total(cart, update_total_dom);
}
function update_total_queue(cart) {
queue_items.push(cart);
setTimeout(runNext, 0);
}
var queue_items = [];
var working = false;
function runNext() {
if(working)
return;
working = true;
var cart = queue_items.shift();
calc_cart_total(cart, function(total) {
update_total_dom(total);
working = false; ////
runNext(); ////
});
}
function update_total_queue(cart) {
queue_items.push(cart);
setTimeout(runNext, 0);
}
var queue_items = [];
var working = false;
function runNext() {
if(working)
return;
if(queue_items.length === 0) ////
return; ////
working = true;
var cart = queue_items.shift();
calc_cart_total(cart, function(total) {
update_total_dom(total);
working = false;
runNext();
});
}
function update_total_queue(cart) {
queue_items.push(cart);
setTimeout(runNext, 0);
}
function Queue() { ////
var queue_items = [];
var working = false;
function runNext() {
if(working)
return;
if(queue_items.length === 0)
return;
working = true;
var cart = queue_items.shift();
calc_cart_total(cart, function(total) {
update_total_dom(total);
working = false;
runNext();
});
}
return function(cart) { ////
queue_items.push(cart);
setTimeout(runNext, 0);
};
}
var update_total_queue = Queue(); ////
function Queue(worker) {
var queue_items = [];
var working = false;
function runNext() {
if(working)
return;
if(queue_items.length === 0)
return;
working = true;
var cart = queue_items.shift();
worker(cart, function() { //// done()
working = false;
runNext();
});
}
return function(cart) {
queue_items.push(cart);
setTimeout(runNext, 0);
};
}
function calc_cart_worker(cart, done) { ////
calc_cart_total(cart, function(total) {
update_total_dom(total);
done(total); //// done()
});
}
var update_total_queue = Queue(calc_cart_worker);
function Queue(worker) {
var queue_items = [];
var working = false;
function runNext() {
if(working)
return;
if(queue_items.length === 0)
return;
working = true;
var item = queue_items.shift();
worker(item.data, function(val) { ////
working = false;
setTimeout(item.callback, 0, val); ////
runNext();
});
}
return function(data, callback) {
queue_items.push({
data: data, ////
callback: callback || function(){} ////
});
setTimeout(runNext, 0);
};
}
function calc_cart_worker(cart, done) {
calc_cart_total(cart, function(total) {
update_total_dom(total);
done(total);
});
}
var update_total_queue = Queue(calc_cart_worker);
/// Dropping Queue
function DroppingQueue(max, worker) {
var queue_items = [];
var working = false;
function runNext() {
if(working)
return;
if(queue_items.length === 0)
return;
working = true;
var item = queue_items.shift();
worker(item.data, function(val) {
working = false;
setTimeout(item.callback, 0, val);
runNext();
});
}
return function(data, callback) {
queue_items.push({
data: data,
callback: callback || function(){}
});
while(queue_items.length > max)
queue_items.shift();
setTimeout(runNext, 0);
};
}
function calc_cart_worker(cart, done) {
calc_cart_total(cart, function(total) {
update_total_dom(total);
done(total);
});
}
var update_total_queue = DroppingQueue(1, calc_cart_worker);
์ ๋ฆฌ
Queue()
๋ ํจ์๋ฅผ ์ธ์๋ก ๋ฐ์ ๋ ๋ค๋ฅธ ํจ์๋ฅผ ๋ฆฌํดํ๋ ํจ์์ด๋ค.Queue()
๋ ์ด๋ค ํจ์๋ฅผ ์๋ก์ด ํ์๋ผ์ธ์์ ์คํํ๊ณ ํ ๋ฒ์ ํ ํ์๋ผ์ธ๋ง ์คํํ ์ ์๋๋ก ๋ง๋ค์ด์ฃผ๋ ๊ณ ์ฐจํจ์์ด๋ค.Queue()
๋ ์ก์
์ '์์ ๋ณด์ฅ' ์ํผํ์๋ฅผ ์ฃผ๋ ๋๊ตฌ์ด๋ค.Queue()
๋ ๋์์ฑ ๊ธฐ๋ณธํ(concurrency primitive) ์ด๋ค.๐ก ๊ณต์ ํ๋ ๋ฐฉ๋ฒ์ ํ์ค์์ ์ฐฉ์ํ๊ธฐ
์ธ๊ฐ์ ์ธ์ ๋ ์์์ ๊ณต์ ํ๋ค. ์ด๋ฅผ ์ฐฉ์ํ์ฌ, ์ปดํจํฐ์๊ฒ๋ ์ธ๊ฐ์ ๋ฐฉ๋ฒ๊ณผ ๋น์ทํ๊ฒ ์์์ ๊ณต์ ํ ์ ์๋๋ก ํ๋ก๊ทธ๋๋ฐ ํ ์ ์๋ค.
ํ์ค์์ ์ด๋ค ์ผ์ด ์์๋๋ก ์งํ๋๊ฒ ํ๋ ๋ฐฉ๋ฒ์ ํ๋๋ ์ค์ ์๋ ๊ฒ -> queue๋ฅผ ๋ง๋ค์ด ์ปดํจํฐ๊ฐ ์์ ์ ์์๋๋ก ์งํํ๊ฒ ํ๋๋ก ํ๋ค.
๋ค๋ฅธ ์
1. ํ ๋ฒ์ ํ ๋ช
์ฉ ์ธ ์ ์๊ฒ ํ์ฅ์ค ๋ฌธ์ ์ ๊ธ ์ ์๋ค.
2. ๊ณต๊ณต ๋์๊ด์ ์ง์ญ์ฌํ๊ฐ ๋ง์ ์ฑ
์ ๊ณต์ ํ ์ ์๋ ๊ณณ์ด๋ค.
3. ์น ํ์ ์ฌ์ฉํ๋ฉด ์ ์๋(๊ธฐ๋ก์) ํ๋ช
์ด ๊ต์ค ์ ์ฒด(์ด๋์)์ ์ ๋ณด๋ฅผ ๊ณต์ ํ ์ ์๋ค.
๋์์ฑ ๊ธฐ๋ณธํ(concurrency primitive)์ ์์์ ์์ ํ๊ฒ ๊ณต์ ํ ์ ์๋ ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ์ฝ๋๋ฅผ ๋งํฉ๋๋ค.
<๋ฉ๋ชจ>
์ ์ ๋จ์ ํ์ด์ง๊ฐ ์ค์ด๋ค๊ณ ์๋ค.
๋๊น์ง ํ์ดํ !