๐ ์ฐํ ์ฝ 7๊ธฐ ํ๋ฆฌ์ฝ์ค 3์ฃผ์ฐจ ํ๊ณ
๐ 3์ฃผ์ฐจ ํ๊ธฐ
1,2 ์ฃผ์ฐจ์ ๋น๊ตํ์ ๋ 3์ฃผ์ฐจ์์ ์ ์ฒด์ ์ธ ๊ฐ์ฒด ์งํฅ ์ค๊ณ์ ๋ํด์ ๊นจ๋ฌ์ ๊ฒ ๊ฐ์ต๋๋ค.
ํนํ MVC ํจํด์ ์์กด์ฑ ๊ท์น์ ๋ ๊น์ด ์ดํดํ๊ณ ์ ์ฉํ๊ธฐ ์ํด ๋ง์ ๋ ธ๋ ฅ์ ๊ธฐ์ธ์์ต๋๋ค. Model์ด Controller์ View์ ์์กดํ์ง ์์์ผ ํ๋ค๋ ๊ท์น์ ์งํค๊ธฐ ์ํด Lotto ํด๋์ค๋ ์์ ํ ๋ ๋ฆฝ์ ์ผ๋ก ์ค๊ณํ์ต๋๋ค. Lotto ํด๋์ค๋ ์ค์ง ์์ ์ ์ํ(๋ก๋ ๋ฒํธ)๋ง์ ๊ด๋ฆฌํ๊ณ , ์ธ๋ถ ์์กด์ฑ ์์ด ์์ฒด์ ์ผ๋ก ์ ํจ์ฑ ๊ฒ์ฌ๋ฅผ ์ํํฉ๋๋ค. ์๋ฅผ ๋ค์ด, Lotto ํด๋์ค๋ ์ซ์ ๋ฐฐ์ด์ ๋ฐ์ ๊ฒ์ฆํ๊ณ ์ ์ฅํ๋ ๊ฒ ์ธ์๋ ๋ค๋ฅธ ํด๋์ค์ ์กด์ฌ๋ฅผ ์ ํ ์์ง ๋ชปํ๋๋ก ์ค๊ณํ์ต๋๋ค.
View๊ฐ Model์๋ง ์์กดํด์ผ ํ๋ค๋ ๊ท์น๋ ์ค์ํ๊ฒ ๊ณ ๋ คํ์ต๋๋ค. OutputView ํด๋์ค๋ ๋จ์ํ ๋ฐ์ ๋ฐ์ดํฐ๋ฅผ ์ถ๋ ฅํ๋ ์ญํ ๋ง ์ํํ๋ฉฐ, ์ง์ ์ ์ผ๋ก Controller์ ๋ฉ์๋๋ฅผ ํธ์ถํ์ง ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ๋ก๋ ๊ฒฐ๊ณผ๋ฅผ ์ถ๋ ฅํ ๋ OutputView๋ Controller๋ก๋ถํฐ ๊ฒฐ๊ณผ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌ๋ฐ์ ๋จ์ํ ์ถ๋ ฅ๋ง ๋ด๋นํฉ๋๋ค.
2์ฃผ์ฐจ ๊ณผ์ ์์ ์ฌ์ฉํ์๋ MVC ํจํด๊ณผ ๋น๊ตํ์ ๋, Service Layer์ ์ถ๊ฐ๋ ์ด๋ฒ ๋ฏธ์ ์ ๊ฐ์ฅ ํฐ ๊ตฌ์กฐ์ ๋ณํ์์ต๋๋ค. ์ด์ ๋ํด์ ๊ณต๋ถํ๋ฉด์ ๊ฐ์ฒด ์งํฅ ์ค๊ณ์ ๋ํ ์ดํด๋๊ฐ ํฌ๊ฒ ์ฑ์ฅํ์ต๋๋ค. 2์ฃผ์ฐจ์์๋ Controller๊ฐ ๋ชจ๋ ๋น์ฆ๋์ค ๋ก์ง์ ๋ด๋นํ์ง๋ง, ์ด๋ ๋จ์ผ ์ฑ ์ ์์น์ ์๋ฐฐ๋๋ฉฐ ์ ์ง๋ณด์๋ฅผ ์ด๋ ต๊ฒ ๋ง๋ ๋ค๋ ๊ฒ์ ๊นจ๋ฌ์์ต๋๋ค. ๊ทธ๋ฆฌํ์ฌ, ์ดํ LottoService๋ฅผ ๋์ ํ์ฌ ๋ก๋ ๊ฒ์์ ํต์ฌ ๋ก์ง(๋น์ฒจ ํ์ธ, ์์ต๋ฅ ๊ณ์ฐ ๋ฑ)์ ๋ถ๋ฆฌํ์ต๋๋ค. ์ด๋ฅผ ํตํด ๋จ์ผ ์ฑ ์ ์์น์ ๋ ์ ์ค์ํ ์ ์์๊ณ , ๊ฐ ๋ก์ง์ ๋ ๋ฆฝ์ ์ผ๋ก ํ ์คํธํ๊ธฐ๋ ์ฌ์์ก์ต๋๋ค.
LottoService์์๋ ๋น์ฆ๋์ค ๋ก์ง์ ์์ง๋๋ฅผ ๋์ด๋ ๋ฐ ์ฃผ๋ ฅํ์ต๋๋ค. ๋น์ฒจ ๋ฒํธ ํ์ธ ๋ก์ง์ ์ฌ๋ฌ ์์ ๋ฉ์๋๋ก ๋ถ๋ฆฌํ์ฌ, ๊ฐ ๋ฉ์๋๊ฐ ํ ๊ฐ์ง ์ฑ ์๋ง ๊ฐ์ง๋๋ก ๊ฐ์ ํ์ต๋๋ค. ์๋ฅผ ๋ค์ด, ๊ธฐ์กด์ ํ๋์ ๋ฉ์๋์์ ์ฒ๋ฆฌํ๋ ๋น์ฒจ ํ์ธ ๋ก์ง์ ๋ค์๊ณผ ๊ฐ์ด ๋ถ๋ฆฌํ์ต๋๋ค. 1: ์ผ์นํ๋ ๋ฒํธ ๊ฐ์ ํ์ธ, 2: ๋ณด๋์ค ๋ฒํธ ํ์ธ, 3: ๋น์ฒจ ๊ธ์ก ๊ณ์ฐ, 4: ์์ต๋ฅ ๊ณ์ฐ - ์ด๋ ๊ฒ ๋ถ๋ฆฌํจ์ผ๋ก์จ ๊ฐ ๋ก์ง์ ๋ ๋ฆฝ์ ์ผ๋ก ํ ์คํธํ ์ ์์๊ณ , ์ฝ๋์ ์ฌ์ฌ์ฉ์ฑ๋ ๋์์ก์ต๋๋ค.
๋ํ, JSDoc์ ๋์
ํ์ฌ ๊ฐ ๋ฉ์๋์ ํด๋์ค์ ๋ชฉ์ , ๋งค๊ฐ๋ณ์, ๋ฐํ๊ฐ์ ๋ช
ํํ ๋ฌธ์ํํ์ต๋๋ค. ์๋ฅผ ๋ค์ด, Service ํด๋์ค์ ๋ฉ์๋๋ค์ ๋ชจ๋ ์
๋ ฅ ํ์
๊ณผ ๋ฐํ ํ์
, ๋ฉ์๋์ ๋ชฉ์ ์ JSDoc์ผ๋ก ๋ช
์ํ์ฌ ๋ค๋ฅธ ๊ฐ๋ฐ์๊ฐ ์ฝ๊ฒ ์ดํดํ ์ ์๋๋ก ํ์ต๋๋ค.
ํ
์คํธ ์ ๋ต๋ ํฌ๊ฒ ๊ฐ์ ํ์ต๋๋ค. 2์ฃผ์ฐจ์์๋ ์ฃผ๋ก ํตํฉ ํ
์คํธ ์์ฃผ๋ก ์งํํ๋ค๋ฉด, ์ด๋ฒ์๋ ๊ฐ ํด๋์ค์ ๋ฉ์๋๋ณ๋ก ์ธ๋ถํ๋ ๋จ์ ํ
์คํธ๋ฅผ ์์ฑํ์ต๋๋ค. ํนํ Jest์ test.each๋ฅผ ํ์ฉํ์ฌ ๋ค์ํ ์
๋ ฅ ์ผ์ด์ค์ ๋ํ ํ
์คํธ๋ฅผ ํจ์จ์ ์ผ๋ก ๊ตฌํํ์ต๋๋ค. ์๋ฅผ ๋ค์ด, ๋ก๋ ๋ฒํธ ๊ฒ์ฆ ํ
์คํธ์ ๊ฒฝ์ฐ ์ฌ๋ฌ ๊ฐ์ง ์๋ชป๋ ์
๋ ฅ ์ผ์ด์ค(๋ฒ์ ์ด๊ณผ, ์ค๋ณต ์ซ์, ์๋ชป๋ ๊ฐ์ ๋ฑ)๋ฅผ ํ ๋ฒ์ ํ
์คํธํ ์ ์์์ต๋๋ค.
๋ฉ์๋์ ๋จ์ผ ์ฑ
์๋ ๋์ฑ ์ฒ ์ ํ ์งํค๋ ค ๋
ธ๋ ฅํ์ต๋๋ค. ์๋ฅผ ๋ค์ด, ๋น์ฒจ ๊ฒฐ๊ณผ ๊ณ์ฐ ๋ก์ง์ '๋ฒํธ ๋งค์นญ ํ์ธ', '๋ณด๋์ค ๋ฒํธ ํ์ธ', '๋น์ฒจ๊ธ ๊ณ์ฐ' ๋ฑ ์์ ๋จ์๋ก ๋ถ๋ฆฌํ์ต๋๋ค. ์ด๋ ์ฝ๋์ ์ฌ์ฌ์ฉ์ฑ์ ๋์ด๊ณ ํ
์คํธ๋ฅผ ์ฝ๊ฒ ๋ง๋ค์์ต๋๋ค.
2์ฃผ์ฐจ PR ๋ฆฌ๋ทฐ์์ ํผ๋๋ฐฑ์ ํตํด ๋ค์ด๋ฐ์ ์ค์์ฑ์ ๋ํด์ ํฌ๊ฒ ๊นจ๋ฌ์ ์ ์ด ์์ต๋๋ค. ๋ค์ด๋ฐ๋ง์ผ๋ก๋ ๋ฉ์๋์ ์ ๋ฐ์ ์ธ ์ญํ ์ ๋ํ๋ผ ์ ์์๊ณ , 3์ฃผ์ฐจ ๊ณผ์ ์ ์ ์ฉํ์์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ ์ฝ๋ ํ์ง ํฅ์์ ์ํด ๋ช
ํํ ๋ค์ด๋ฐ๊ณผ ์ผ๊ด๋ ์ฝ๋ฉ ์คํ์ผ๋ ์ค์ํ๊ฒ ์๊ฐํ์ต๋๋ค. ๋ฉ์๋ ์ด๋ฆ์ ํด๋น ๋ฉ์๋์ ์ญํ ์ ๋ช
ํํ ํํํ๋๋ก ์ง์์ผ๋ฉฐ, ๋ณ์๋ช
๋ ๊ทธ ์ฉ๋๋ฅผ ์ฆ์ ์ ์ ์๋๋ก ์ค์ ํ์ต๋๋ค. ๋ํ ์ผ๊ด๋ ๋ค์ฌ์ฐ๊ธฐ์ ์ฃผ์ ์คํ์ผ์ ์ ์งํ์ฌ ์ฝ๋์ ๊ฐ๋
์ฑ์ ๋์์ต๋๋ค. ๋ํ, ์์๋ฅผ ์ ๊ทน์ ์ผ๋ก ํ์ฉํ์ฌ ๋งค์ง ๋๋ฒ๋ฅผ ์ ๊ฑฐํ์ต๋๋ค. ๋ก๋ ๊ด๋ จ ์์๋ค์ LOTTO_CONFIG ๊ฐ์ฒด๋ก ๋ชจ์์ ๊ด๋ฆฌํจ์ผ๋ก์จ, ํฅํ ๋ณ๊ฒฝ ์ฌํญ์ด ๋ฐ์ํ์ ๋ ํ ๊ณณ์์๋ง ์์ ํ๋ฉด ๋๋๋ก ๊ฐ์ ํ์ต๋๋ค.
๋ง์ง๋ง์ผ๋ก ๊ฐ์ฅ ๋ง์ด ๊ณ ๋ฏผํ๋ ๊ฒ ์ค ํ๋๋ static ๋ฐฉ์๊ณผ ์ธ์คํด์ค ์์ฑ ๋ฐฉ์์ ๋๋ค. InputView์ ์ฝ๋๋ฅผ ์งค ๋, static ๋ฐฉ์๊ณผ ์ธ์คํด์ค ์์ฑ ๋ฐฉ์ ์ค ๊ณ ๋ฏผ์ ํ์๊ณ , ํจ์จ์ ์ธ ์ฝ๋๋ฅผ ์ง๊ธฐ ์ํด์ ๊ฐ ํน์ง์ ์ ์์์ผ ํ๋ค๊ณ ์๊ฐํ๊ธฐ ๋๋ฌธ์ ๊ตฌ๊ธ๋ง์ ํตํ์ฌ ๊น๊ฒ ๊ณต๋ถ๋ฅผ ํ์๊ณ ์ฌ๋๋ง๋ค ๋ค์ํ๊ฒ ํํ๋ค๋ ๊ฒ์ ์๊ฒ๋์์ต๋๋ค. ์ ๋ InputView์ ๊ฒฝ์ฐ ์ธ์คํด์ค ์์ฑ ๋ฐฉ๋ฒ์ ํํ์๋๋ฐ, InputView๋ฅผ ์ธ์คํด์ค๋ก ์์ฑํ๋๋ก ์ค๊ณํ ์ด์ ๋, ํ ์คํธ์ ํ์ฅ์ฑ ์ธก๋ฉด์์ ๋ ์ ๋ฆฌํ๊ธฐ ๋๋ฌธ์ ๋๋ค. static ๋ฉ์๋๋ฅผ ์ฌ์ฉํ ๊ฒฝ์ฐ, ์ธ์คํด์ค๋ฅผ ๋ฐ๋ก ์์ฑํ์ง ์์๋ ๋์ด ํธ๋ฆฌํ์ง๋ง, ์ด๋ฌํ ๊ตฌ์กฐ๋ ์์กด์ฑ ์ฃผ์ ์ ์ด๋ ต๊ฒ ๋ง๋ค๊ณ , ํ ์คํธ๋ ์ ์ง๋ณด์์ ์ ์ฝ์ ์ค ์ ์์ต๋๋ค.
๋ฐ๋ฉด, ์ธ์คํด์ค๋ฅผ ์์ฑํ๋ ๋ฐฉ์์ ์ฑํํ๋ฉด ์์กด์ฑ ์ฃผ์
์ด ๊ฐ๋ฅํด์ง๋ฉฐ, ์ด๋ฅผ ํตํด ํด๋์ค ๊ฐ์ ๊ฒฐํฉ๋๋ฅผ ๋ฎ์ถ๊ณ ๋ ์ ์ฐํ ์ค๊ณ๋ฅผ ํ ์ ์์ต๋๋ค. ์ด๋ฅผ ํตํด InputView ํด๋์ค๋ ํ์ํ ๋ค๋ฅธ ๊ฐ์ฒด๋ฅผ ์ฃผ์
๋ฐ์ ์ฌ์ฉํ ์ ์์ด ์ฌ์ฌ์ฉ์ฑ๊ณผ ํ์ฅ์ฑ์ด ๋์์ง๋๋ค.
๋ํ, InputView๋ฅผ ํด๋์ค๋ก ์ค๊ณํ ์ด์ ๋ ๋จ์ํ ๊ฐ์ฒด๋ก ๊ตฌํํ ๋๋ณด๋ค ์บก์ํ, ์ถ์ํ, ์ฌ์ฌ์ฉ์ฑ ์ธก๋ฉด์์ ๋ ๋ง์ ์ฅ์ ์ ์ ๊ณตํ๊ธฐ ๋๋ฌธ์
๋๋ค. ์ด๋ฅผ ํตํด InputView๋ SOLID ์์น ์ค ์์กด์ฑ ์ญ์ ์์น(DIP)์ ์งํค๋ฉฐ, ํฅํ ๋ณํ์๋ ์ ์ฐํ๊ฒ ๋์ํ ์ ์๋ ๊ตฌ์กฐ๋ฅผ ๊ฐ์ถ๊ฒ ๋์์ต๋๋ค.
์ด๋ฒ ๋ฏธ์ ์ ํตํด ๋จ์ํ ๊ธฐ๋ฅ์ ๊ตฌํํ๋ ๊ฒ์ ๋์ด์, ์ข์ ์ฝ๋๋ ๋ฌด์์ธ์ง, ์ด๋ป๊ฒ ํ๋ฉด ๋ ๋์ ์ค๊ณ๋ฅผ ํ ์ ์๋์ง์ ๋ํด ๊น์ด ๊ณ ๋ฏผํ ์ ์์์ต๋๋ค. ๋งค์ฃผ์ฐจ ๊ณผ์ ๋ฅผ ํตํด์ ์๋ก์ด ์ง์์ ๋ฐฐ์ฐ๊ณ ๋ง์ ๋ค๋ฅธ ์ฐธ๊ฐ์๋ถ๋ค๊ณผ ํผ๋๋ฐฑ์ ์ฃผ๊ณ ๋ฐ์ผ๋ฉด์ ๋ค์ํ ๋ฐฉ๋ฉด์์ ์ค์ค๋ก ๋ฐ์ ํ๊ณ ๋์ฑ ํ๋ฅญํ ๊ฐ๋ฐ์๋ก ์ฑ์ฅํ๋ค๋ ๋๋์ ๋ง์ด ๋ฐ์ ํ๋ฆฌ์ฝ์ค๋ฅผ ์ฆ๊ฒ๊ฒ ์ํํ ์ ์๋ ๊ฒ ๊ฐ์ต๋๋ค. ํนํ ๊ฐ์ฒด ์งํฅ ์ค๊ณ์ ํ ์คํธ ์ฃผ๋ ๊ฐ๋ฐ์ ์ค์์ฑ์ ์ฒด๊ฐํ์ผ๋ฉฐ, ์ด๋ฅผ ํตํด ๋ ๋์ ๊ฐ๋ฐ์๋ก ์ฑ์ฅํ ์ ์์์ต๋๋ค.
3์ฃผ์ฐจ์์ ์๋กญ๊ฒ ๋ฐฐ์ด์
App์์ constroller ์ธ์คํด์ค ์์ฑ
class App {
async run() {
const lottoController = new LottoController();
await lottoController.run();
}
}
export default App;
๋ณดํต controller ์ ์ธ์คํด์ค๋ฅผ ์์ฑํ ๋ App์์ ์์ฑ์ ํ๋ค.
ํ์ง๋ง ์? ๋ผ๋ ์ด์ ๋ฅผ ๋ฌป์ง ์๊ณ ๊ทธ์ ์ฐ๊ธฐ๋ง ํ์๋ค.
์ฐจ์ด๋ ์ด๋ ๋ค.
ํด๋์ค์ constructor์์ ํ์ํ ์ธ์คํด์ค๋ฅผ ์์ฑํ๋ฉด, ํด๋์ค๊ฐ ์์ฑ๋ ๋ ์ด๊ธฐํ๊ฐ ์ด๋ฃจ์ด์ง๋ค.
์ฆ, constructor์์ ์ธ์คํด์ค๋ฅผ ์์ฑํ๋ ๊ฒ์ ํด๋์ค์ ์ํ๋ฅผ ์์ฑ ์ฆ์ ๊ณ ์ ์ํค๊ณ , ์ดํ์๋ ์ฌ์ค์ ๋์ง ์๋ ์ํ๋ก ๋ง๋๋ ๊ฒ๊ณผ ๊ฐ๋ค.
ํ์ง๋ง,
run ๋ฉ์๋ ๋ด๋ถ์์ ์ธ์คํด์ค๋ฅผ ์์ฑํ๋ฉด,
๋ฉ์๋๊ฐ ํธ์ถ๋ ๋ ์ธ์คํด์ค๋ฅผ ์์ฑํ๊ฒ ๋ฉ๋๋ค. ์ฆ, ์ค์ ์ฌ์ฉ๋๋ ์์ ์์ ์ธ์คํด์ค๋ฅผ ์ด๊ธฐํํ๋ค.
๋ฐ๋ผ์, ์ธ์คํด์ค๋ฅผ ํด๋์ค ์ ๋ฐ์์ ์ฌ์ฌ์ฉํด์ผ ํ๊ฑฐ๋, ์ด๊ธฐํ๊ฐ ๋ฐ๋์ ํ์ํ๋ค๋ฉด constructor์์ ์ธ์คํด์ค๋ฅผ ์์ฑํ๋ ๊ฒ์ด ์ข๋ค.
๋ฐ๋ฉด, ์ธ์คํด์ค๋ฅผ ๋งค๋ฒ ์๋ก ์์ฑํ๊ณ , ์ง์ฐ๋ ์ด๊ธฐํ๊ฐ ํ์ํ ๊ฒฝ์ฐ run ๋ด๋ถ์์ ์์ฑํ๋ ๊ฒ์ด ๋ ์ ๋ฆฌํ๋ค.
deepFreeze
export const PROMPT_MESSAGES = Object.freeze({
INPUT: {
PURCHACE_PRICE: '๊ตฌ์
๊ธ์ก์ ์
๋ ฅํด ์ฃผ์ธ์.\n',
WINNING_NUMBER: '\n๋น์ฒจ ๋ฒํธ๋ฅผ ์
๋ ฅํด ์ฃผ์ธ์.\n',
BONUS_NUMBER: '\n๋ณด๋์ค ๋ฒํธ๋ฅผ ์
๋ ฅํด ์ฃผ์ธ์.\n',
},
OUTPUT: {
PURCHACE_QUANTITY: '๊ฐ๋ฅผ ๊ตฌ๋งคํ์ต๋๋ค.',
WINNING_RESULT: '๋น์ฒจ ํต๊ณ',
},
});
์ด ์ฝ๋์์๋ INPUT ๊ณผ OUTPUT ์ ํ์๊ฐ์ฒด๋ค์ freeze๋ฅผ ๋ฐ์ง ๋ชปํ๊ฒ ๋๋ค.
๊ทธ๋์ ๊ฐ๊ฐ freeze๋ฅผ ๋ ํด์ฃผ๋๊ฐ ์๋๋ฉด deepFreeze๋ฅผ ์ด์ฉํ์ฌ ํ์ ๊ฐ์ฒด๋ ๋ถ๋ณํ๊ฒ ๋ง๋ค์ด ์ค ์ ์๋ค.
jsdoc
class LottoService {
#lottos;
#winningNumbers;
#bonusNumber;
/**
* @type {object<string, number>} - 3๊ฐ, 4๊ฐ, 5๊ฐ, 5๊ฐ + ๋ณด๋์ค, 6๊ฐ ์ผ์นํ๋ ๊ฐ์๋ฅผ ์ ์ฅํ๋ ๊ฐ์ฒด
*/
#lottoResult;
constructor(lottos, winningNumber, bonusNumber) {
this.#lottos = lottos;
this.#winningNumbers = winningNumber;
this.#bonusNumber = bonusNumber;
this.#lottoResult = { 3: 0, 4: 0, 5: 0, 5.5: 0, 6: 0 };
}
์ด ์ฝ๋์์ object<string, number>
๋ any ๊ฐ ๋์ค๊ฒ ๋๋ค. ์ฆ, ์ด๋ฌํ jsdoc ๋ฌธ๋ฒ์ ๋ง์ง๊ฐ ์๋ค.
3๊ฐ์ง๋ก ํด๊ฒฐํ ์ ์๋๋ฐ
(1)
/**
*@type {Record<string, number>}
*/
(2)
/**
*@type {{ [key: string]: number }}
*/
(3)
/**
* @type {{
* '3': number,
* '4': number,
* '5': number,
* '5.5': number,
* '6': number
* }}
*/
์ด๋ ๊ฒ ๋ํ๋ผ ์ ์๋ค.