DevLog ๐Ÿ˜ถ

[์šฐํ…Œ์ฝ” 5๊ธฐ] ์‚ฌ๋‹ค๋ฆฌ ํƒ€๊ธฐ ๊ฒŒ์ž„ ๋ฏธ์…˜ ํšŒ๊ณ  ๋ณธ๋ฌธ

์šฐ์•„ํ•œํ…Œํฌ์ฝ”์Šค/๋ ˆ๋ฒจ 1

[์šฐํ…Œ์ฝ” 5๊ธฐ] ์‚ฌ๋‹ค๋ฆฌ ํƒ€๊ธฐ ๊ฒŒ์ž„ ๋ฏธ์…˜ ํšŒ๊ณ 

dolmeng2 2023. 4. 3. 14:12

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

 

โœ”๏ธ ์ž‘์„ฑํ•œ ์ฝ”๋“œ

GitHub - Cl8D/java-ladder: ์‚ฌ๋‹ค๋ฆฌํƒ€๊ธฐ ๋ฏธ์…˜์„ ์œ„ํ•œ ์ €์žฅ์†Œ

์‚ฌ๋‹ค๋ฆฌํƒ€๊ธฐ ๋ฏธ์…˜์„ ์œ„ํ•œ ์ €์žฅ์†Œ. Contribute to Cl8D/java-ladder development by creating an account on GitHub.

github.com

โœ”๏ธ 1์ฐจ PR

[1๋‹จ๊ณ„ - ์‚ฌ๋‹ค๋ฆฌ ์ƒ์„ฑ] ์ ธ๋‹ˆ(์ด์ง€์›) ๋ฏธ์…˜ ์ œ์ถœํ•ฉ๋‹ˆ๋‹ค. by Cl8D ยท Pull Request #140 ยท woowacourse/java-ladder

์•ˆ๋…•ํ•˜์„ธ์š”, ์›จ์ง€! ์šฐํ…Œ์ฝ” 5๊ธฐ ๋ฐฑ์—”๋“œ ํฌ๋ฃจ ์ ธ๋‹ˆ์ž…๋‹ˆ๋‹ค โ›„๏ธ ํ›„์ถ”์™€ ํ•จ๊ป˜ ๋‘ ๋ฒˆ์งธ ํŽ˜์–ด ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ์ง„ํ–‰ํ•˜์˜€์Šต๋‹ˆ๋‹ค. ์ฒซ ํŽ˜์–ด ํ”„๋กœ๊ทธ๋ž˜๋ฐ๊ณผ ๋‹ค๋ฅด๊ฒŒ, ์ด๋ฒˆ์—๋Š” TDD๋ฅผ ์ ๊ทน์ ์œผ๋กœ ํ™œ์šฉํ•˜๋ ค๊ณ  ํ–ˆ๋˜

github.com

โœ”๏ธ 2์ฐจ PR

[2๋‹จ๊ณ„ - ์‚ฌ๋‹ค๋ฆฌ ๊ฒŒ์ž„ ์‹คํ–‰] ์ ธ๋‹ˆ(์ด์ง€์›) ๋ฏธ์…˜ ์ œ์ถœํ•ฉ๋‹ˆ๋‹ค. by Cl8D ยท Pull Request #156 ยท woowacourse/java-l

์•ˆ๋…•ํ•˜์„ธ์š”, ์›จ์ง€ ๐Ÿ‘‹ ์ €๋ฒˆ 1๋‹จ๊ณ„ ๋ฏธ์…˜ ๋•Œ ๋น ๋ฅด๊ฒŒ ํ”ผ๋“œ๋ฐฑํ•ด์ฃผ์‹  ๋•๋ถ„์— 2๋‹จ๊ณ„ ๋ฏธ์…˜๋„ ๊ธˆ๋ฐฉ ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ์—ˆ์–ด์š”. ๐Ÿ‘ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฒˆ ๋ฏธ์…˜์—๋„ ์–ด๊น€์—†์ด ์งˆ๋ฌธ ์‚ฌํ•ญ์ด ์žˆ๋‹ต๋‹ˆ๋‹ค ๐Ÿค—... โœ”๏ธ ์ปค๋ฐ‹

github.com

 


โœ”๏ธ ๊ธฐ๋Šฅ ์š”๊ตฌ์‚ฌํ•ญ

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


 
PR ๋‚ด์šฉ ์ค‘์—์„œ ๋ช‡ ๊ฐ€์ง€ ์ธ์ƒ ๊นŠ์—ˆ๋˜ ๋‚ด์šฉ์„ ์ ์–ด๋ณด๋ ค๊ณ  ํ•œ๋‹ค.
 

๐Ÿ’ฌ ์‚ฌ๋‹ค๋ฆฌ๋Š” ์™„์ „ํžˆ ๋žœ๋คํ•˜๊ฒŒ ์ƒ์„ฑ๋˜์–ด์•ผ ํ• ๊นŒ?

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

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


๐Ÿ’ฌ Scanner vs BufferedReader

    private String readConsole() {
        try {
        return bufferedReader.readLine();
        } catch (IOException e) {
        OutputView.print(e.getMessage());
        }
        return null;
        }

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

ํ™•์‹คํžˆ ์„ฑ๋Šฅ์ ์œผ๋กœ๋Š” ์ข‹์ง€๋งŒ, ์‚ฌ์‹ค ์ด๋ฒˆ ๋ฏธ์…˜์—์„œ๋Š” ์˜คํžˆ๋ ค ๋…์ด ๋˜์—ˆ์„ ์ˆ˜๋„ ์žˆ๋‹ค. ๋ช…์‹œ์ ์œผ๋กœ try-catch๋ฅผ ํ†ตํ•ด์„œ IoException์„ ์žก์•„์•ผ ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์˜คํžˆ๋ ค ์ฝ”๋“œ๊ฐ€ ๋” ์•ˆ ์˜ˆ์˜๊ฒŒ ๋ณด์ผ ์ˆ˜๋„ ์žˆ์—ˆ๋‹ค๋Š” ์ ์ด๋‹ค. ํ•˜์ง€๋งŒ, ๊ฐœ์ธ์ ์œผ๋กœ๋Š” ์„ฑ๋Šฅ์„ ์กฐ๊ธˆ ๋” ์ค‘์š”์‹œํ•˜๋Š” ์ž…์žฅ์—์„œ ๋ฆฌ๋ทฐ์–ด๋‹˜๊ป˜ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ง์”€๋“œ๋ ธ๋‹ค.

๋Œ€์ถฉ checked Exception์€ unchecked Exception์œผ๋กœ ๊ฐ์‹ธ๋Š” ๊ฑธ ์„ ํ˜ธํ•œ๋‹ค๋Š” ์ด์•ผ๊ธฐ... ์•„๋ฌดํŠผ, ๊ทธ๋ž˜์„œ ๋ฆฌํŒฉํ„ฐ๋ง์€ ์ง„ํ–‰ํ•˜์ง€ ์•Š์•˜์ง€๋งŒ ์ด๋ฒˆ ๊ธฐํšŒ์— ์ƒˆ๋กญ๊ฒŒ ์•Œ์•„๊ฐˆ ์ˆ˜ ์žˆ์—ˆ์–ด์„œ ๋„์›€์ด ๋˜์—ˆ๋‹ค.


๐Ÿ’ฌ ์ •๋ณด์ „๋ฌธ๊ฐ€ ํŒจํ„ด

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

public class InputView {

    private final BufferedReader bufferedReader;

    public InputView() {
        this.bufferedReader = new BufferedReader(new InputStreamReader(System.in));
    }

    public String readConsole() {
        try {
            return bufferedReader.readLine();
        } catch (IOException e) {
            OutputView.print(e.getMessage());
        }
        return null;
    }

    public <T> T getUserInput(Supplier<T> inputReader) {
        try {
            return inputReader.get();
        } catch (IllegalArgumentException e) {
            OutputView.print(e.getMessage());
            return getUserInput(inputReader);
        }
    }
}
// Controller
private Participants createParticipants() {
        return inputView.getUserInput(() -> {
        OutputView.print(INPUT_PARTICIPANT_NAMES_GUIDE.getMessage());
        String participantNames = inputView.readConsole();
        return Participants.create(participantNames);
        });
        }

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

public String getParticipantNames() {
    OutputView.print(INPUT_PARTICIPANT_NAMES_GUIDE.getMessage());
    return readConsole();
}
 // Controller
private Participants createParticipants() {
    return inputView.getInputWithRetry(() -> {
        String participantNames = inputView.getParticipantNames();
        return Participants.create(participantNames);
    });
}

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


๐Ÿ’ฌ ์‚ฌ๋‹ค๋ฆฌ ์ƒ์„ฑ ๋กœ์ง

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

public class Ladder {

    private final List<Rungs> ladder;

    public Ladder(final List<Rungs> ladder) {
        this.ladder = ladder;
    }
}
public class LadderFactory {
    private static final int MIN_HEIGHT = 1;
    private static final int MAX_HEIGHT = 10_000;
    private static final int DEFAULT_COUNT = 1;
    private final NumberGenerator rungNumberGenerator;

    public LadderFactory(final NumberGenerator rungNumberGenerator) {
        this.rungNumberGenerator = rungNumberGenerator;
    }

    public Ladder createLadder(final String height, final int participantCount) {
        int ladderHeight = convertLadderHeight(height);
        List<Rungs> ladder = new ArrayList<>();
        for (int i = 0; i < ladderHeight; i++) {
            ladder.add(new Rungs(makeRungCount(participantCount), rungNumberGenerator));
        }
        return new Ladder(ladder);
    }
}

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

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

๊ทธ๋ฆผ์œผ๋กœ ์ƒ๊ฐํ•œ๋‹ค๋ฉด ํ˜„์žฌ ์ด๋Ÿฐ ๋Š๋‚Œ์ธ ๊ฒƒ์ด๋‹ค.
 
๊ทธ๋ž˜์„œ...! ๋ฆฌ๋ทฐ์–ด๋‹˜์ด ์ •๋ง ์ข‹์€ ๋ฐฉ์•ˆ์„ ์ฃผ์…จ๋‹ค ๐Ÿ‘ 

public class Ladder {
    private final List<Rungs> ladderRungs;
    private Ladder(final List<Rungs> ladderRungs) {
        this.ladderRungs = ladderRungs;
    }

    public static Ladder create(final String height, final int participantCount, final BooleanGenerator rungGenerator) {
        List<Rungs> ladderRungs = LadderRungsFactory
                .getInstance(rungGenerator)
                .createLadderRungs(height, participantCount);
        return new Ladder(ladderRungs);
    }
}
public class LadderRungsFactory {

    private static final int MIN_HEIGHT = 1;
    private static final int MAX_HEIGHT = 10_000;
    private static final int DEFAULT_COUNT = 1;
    private static final Map<BooleanGenerator, LadderRungsFactory> CACHE = new HashMap<>();

    private final BooleanGenerator rungGenerator;

    private LadderRungsFactory(final BooleanGenerator rungGenerator) {
        this.rungGenerator = rungGenerator;
    }

    static LadderRungsFactory getInstance(final BooleanGenerator rungGenerator) {
        if (CACHE.containsKey(rungGenerator)) {
            return CACHE.get(rungGenerator);
        }

        LadderRungsFactory ladderRungsFactory = new LadderRungsFactory(rungGenerator);
        CACHE.put(rungGenerator, ladderRungsFactory);
        return ladderRungsFactory;
    }

    protected List<Rungs> createLadderRungs(final String height, final int participantCount) {
        int ladderHeight = convertToLadderHeight(height);
        List<Rungs> ladder = new ArrayList<>();
        for (int i = 0; i < ladderHeight; i++) {
            ladder.add(Rungs.create(makeRungCount(participantCount), rungGenerator));
        }
        return ladder;
    }

๋ฌด์Šจ ์ฐจ์ด๊ฐ€ ์žˆ๋Š”์ง€ ๋ˆˆ์— ๋ณด์ด๋Š”๊ฐ€? (์บ์‹œ๋Š” ํŒฉํ† ๋ฆฌ ์ž์ฒด๊ฐ€ ์—ฌ๋Ÿฌ ๋ฒˆ ์ƒ์„ฑ๋  ํ•„์š”๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์— ์ฒ˜๋ฆฌํ•ด๋‘์—ˆ๋‹ค.)
์‚ฌ๋‹ค๋ฆฌ๋ฅผ ์ƒ์„ฑํ•  ๋•Œ ๋‹จ์ˆœํžˆ Ladder ๊ฐ์ฒด๋ฅผ Ladder๊ฐ€ ํ˜ผ์ž ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹Œ, ๋‚ด๋ถ€์ ์œผ๋กœ LadderFactory๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ์ œ์–ด ๋กœ์ง์ด Ladder -> LadderFactory -> Ladder๋กœ ๋‹ค์‹œ ์œ„์ž„ํ•˜๋Š” ๊ตฌ์กฐ๊ฐ€ ๋˜๋Š” ๊ฒƒ์ด๋‹ค.
 
๊ทธ๋ฆผ์œผ๋กœ ์‚ดํŽด๋ณด์ž. ์บ์‹ฑ์— ๋Œ€ํ•œ ๋ถ€๋ถ„์€ ์ œ์™ธํ•˜๊ณ  ๋กœ์ง์„ ๋‹ค์‹œ ์„ธ์› ๋‹ค.

์šฐ์„ , LadderFactory๊ฐ€ ํ•„์š”ํ•œ ๋ณ€์ˆ˜์˜ ๊ฒฝ์šฐ Ladder๊ฐ€ ๊ฐ€์ง€๊ฒŒ ๋œ๋‹ค. 
Ladder๋Š” ์‚ฌ๋‹ค๋ฆฌ๋ฅผ ์ƒ์„ฑํ•  ๋•Œ ๋‚ด๋ถ€์ ์œผ๋กœ LadderFactory๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์‚ฌ๋‹ค๋ฆฌ ์ƒ์„ฑ์— ํ•„์š”ํ•œ ๋ถ€ํ’ˆ์ธ List<Rungs>๋ฅผ ๋ฐ›๊ฒŒ ๋˜๊ณ , ๊ฐ™์€ ํŒจํ‚ค์ง€ ๋‚ด์—์„œ LadderFactory์˜ createLadderRungs๋ฅผ ํ˜ธ์ถœํ•˜๋”๋ผ๋„ Ladder ์ž์ฒด๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— ๊ฒฐ๊ตญ 'Ladder' ์ž์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” Ladder ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ฒŒ ๋œ๋‹ค. 
 
์œ„ ํ•ด๋ฒ•์„ ์•Œ๊ณ  ๋‚˜์„œ ์ •๋ง ํฐ ๊นจ๋‹ฌ์Œ์„ ์–ป๊ฒŒ ๋˜์—ˆ๋‹ค... ์ด๋Š” ์ถ”ํ›„ ๋‚˜์˜ฌ ์ฒด์Šค ๋ฏธ์…˜์—์„œ๋„ ์•Œ์ฐจ๊ฒŒ ์จ๋จน์—ˆ๋‹ค.


๐Ÿ’ฌ ์˜ˆ์™ธ ๋ฉ”์‹œ์ง€ ์ฒ˜๋ฆฌ

์‚ฌ์‹ค ์˜ˆ์™ธ ๋ฉ”์‹œ์ง€๋Š” ์ด์ „ ๋ฏธ์…˜์—์„œ๋„ ๊ณ„์† ๊ณ ๋ฏผํ•ด์™”์—ˆ๋‹ค. ์ด์ „๊นŒ์ง€๋Š” ๋ฉ”์‹œ์ง€ ์ž์ฒด๋ฅผ enum์œผ๋กœ ๊ด€๋ฆฌํ•˜๋ฉด์„œ ๋ณ„๋„์˜ ์˜ˆ์™ธ ๋ฉ”์‹œ์ง€์— ๋Œ€ํ•ด ํ•œ ๋ฒˆ์— ๊ด€๋ฆฌํ•˜๋„๋ก ๋งŒ๋“ค์—ˆ์—ˆ๋Š”๋ฐ, ์„œ๋น„์Šค๊ฐ€ ์ปค์ง€๊ณ  ๋„๋ฉ”์ธ์ด ์ปค์ง„๋‹ค๋ฉด ์ด๋Ÿฐ ์‹์œผ๋กœ ๊ด€๋ฆฌํ•˜๋Š” ๊ฒŒ ๊ทธ๋ ‡๊ฒŒ ์ข‹์ง€ ์•Š์„ ๊ฒƒ ๊ฐ™๋‹ค๋Š” ์ƒ๊ฐ์ด ๋“ค์—ˆ๋‹ค. 

public enum ErrorMessage {
        AAA("")
    ...
    }

ํ•˜์ง€๋งŒ, ์ด๋Ÿฐ util์„ฑ ๊ฐ์ฒด๊ฐ€ ๊ณผ์—ฐ ๊ฐ์ฒด์ง€ํ–ฅ์  ๊ด€์ ์—์„œ ์œ ์˜๋ฏธํ•  ๊ฒƒ์ธ๊ฐ€?๋ฅผ ์ƒ๊ฐํ•ด๋ณด์•„์•ผ ํ•œ๋‹ค.
๋‚˜๋Š” ์ด์ „๊นŒ์ง€ util ์„ฑ ๊ฐ์ฒด์— ๋Œ€ํ•ด์„œ ์•„๋ฌด ์ƒ๊ฐ๋„ ์—†์—ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์ด๋ฒˆ ๊ธฐํšŒ์— ํ•œ ๋ฒˆ ์ƒ๊ฐํ•ด๋ณด์•˜๋‹ค...

์–ด๋Š ๊ณณ์—์„œ ์ฐธ์กฐ๊ฐ€ ๊ฐ€๋Šฅํ•œ ํด๋ž˜์Šค๋ผ๋ฉด ๊ฐ์ฒด์˜ ์ฑ…์ž„ ๋ถ„๋ฆฌ ๊ด€์ ์—์„œ ๋งž์ง€ ์•Š๋‹ค๋Š” ๊ฒƒ์œผ๋กœ ๊ฒฐ๋ก ์„ ๋‚ด๋ ธ๋‹ค. (SRP ์œ„๋ฐ˜)
๊ทธ๋ž˜์„œ ๊ฒฐ๊ณผ์ ์œผ๋กœ๋Š” Custom Exception์„ ์ƒ์„ฑํ•ด์„œ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•œ ์ง€์ ์—์„œ ๋ฉ”์‹œ์ง€๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ๋ฐฉํ–ฅ์œผ๋กœ ๋ณ€๊ฒฝํ•˜์˜€๋‹ค.

๋„๋ฉ”์ธ์—์„œ ์ปค์Šคํ…€ ์˜ˆ์™ธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๋Š” ๋ฐฉํ–ฅ์œผ๋กœ ์ง„ํ–‰ํ•˜์…จ๊ตฐ์š”!
๊ทธ๋Ÿผ ๋„๋ฉ”์ธ์„ ์ฐธ์กฐํ•œ ๊ฐ์ฒด ์ž…์žฅ์—์„œ ์ปค์Šคํ…€ ์˜ˆ์™ธ๋ฅผ ๊ตฌ๋ถ„ํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ์ค€์ด ์ƒ๊ฒผ์Šต๋‹ˆ๋‹ค ^_^ ํ•ด๋‹น ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ์ง€์ ์—์„œ ํŠน์ • ํƒ€์ž…์œผ๋กœ Catch ํ•  ์ˆ˜ ์žˆ์œผ๋‹ˆ๊นŒ์š”
๊ทธ๋Ÿฌ๋ฉด ํŠน์ •ํ•œ ๋„๋ฉ”์ธ ์˜ˆ์™ธ๋ฅผ Catchํ•ด์„œ ๋‹ค๋ฅธ ๋ฉ”์‹œ์ง€๋กœ ๋ฐ”๊ฟ” ์ถœ๋ ฅํ•  ์ˆ˜๋„ ์žˆ๊ฒ ์ฃ ?
๋” ๋‚˜์•„๊ฐ€ ๋„๋ฉ”์ธ ์˜ˆ์™ธ๋ฅผ ๊ทธ๋ฃนํ•‘ (RuntimeException์„ ์ƒ์†ํ•˜๋Š” ServiceException์„ ๋งŒ๋“ค๊ณ  ๊ฐ ๋„๋ฉ”์ธ ์˜ˆ์™ธ๋Š” ServiceException์„ ์ƒ์†)ํ•˜๋Š” ์‹์œผ๋กœ "ํŠน์ • ๊ทธ๋ฃน์˜ ์˜ˆ์™ธ๋Š” A ๋ฉ”์‹œ์ง€๋กœ ์ผ๊ด„์ฒ˜๋ฆฌ" ๊ฐ™์€ ๋กœ์ง๋„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๊ฒ ์Šต๋‹ˆ๋‹ค.

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

๋ฆฌ๋ทฐ์–ด๋‹˜์˜ ๋ง์”€ ์ค‘์— ๊ฐ€์žฅ ์ธ์ƒ๊นŠ์€ ๋ถ€๋ถ„์„ ๊ฐ€์ ธ์™”๋‹ค.
์ด๋ฒˆ ๋ฏธ์…˜์„ ์ง„ํ–‰ํ•˜๋ฉด์„œ ๊ฐ์ฒด์ง€ํ–ฅ์— ํ•œ ๋ฐœ์ง ๋‹ค๊ฐ€๊ฐ„ ๋Š๋‚Œ์ด๋‹ค.
 


๐Ÿ’ฌ ํ”„๋กœ๊ทธ๋žจ ์‹คํ–‰ ์ข…๋ฃŒ์˜ ๋กœ์ง

   private void printGameResultWithRetry(final Participants participants, final List<String> ladderResultNames) {
        List<Participant> resultParticipants;
        do {
            resultParticipants = getResultParticipants(participants);
            printGameResult(resultParticipants, ladderResultNames);
        } while (isProceed(resultParticipants));
    }


    private List<Participant> getResultParticipants(final Participants participants) {
        return inputView.getInputWithRetry(() -> {
            String resultParticipantName = inputView.getResultParticipantName();
            return getParticipants(participants, resultParticipantName);
        });
    }


    private List<Participant> getParticipants(final Participants participants, final String resultParticipantName) {
        if (resultParticipantName.equalsIgnoreCase(EXIT_INPUT_MESSAGE.getMessage())) {
            return null;
        }
        return participants.getResultParticipants(resultParticipantName);
    }


    private boolean isProceed(final List<Participant> resultParticipants) {
        return resultParticipants != null;
    }


    private void printGameResult(final List<Participant> resultParticipants,
    final List<String> ladderResultNames) {
        if (resultParticipants == null) {
            return;
        }
        OutputView.print(System.lineSeparator() + RESULT_GAME_GUIDE.getMessage());
        outputView.printLadderGameResult(resultParticipants, ladderResultNames);
    }
}

์ฝ”๋“œ๊ฐ€ ๊ธธ์–ด์„œ ์•Œ์•„๋ณด๊ธฐ ํž˜๋“ค๊ฒ ์ง€๋งŒ...!
EXIT๋ฅผ ์ž…๋ ฅํ–ˆ์„ ๋•Œ ํ”„๋กœ๊ทธ๋žจ์ด ์ข…๋ฃŒ๋˜๋„๋ก ๋งŒ๋“  ๋ถ€๋ถ„์ด๋‹ค.
๋‹ค๋งŒ, ์ข…๋ฃŒ ์กฐ๊ฑด์œผ๋กœ getParticipants()์—์„œ ๋ช…์‹œ์ ์œผ๋กœ null์„ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ๋งŒ๋“  ๊ฒƒ์ธ๋ฐ (์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•œ console ๋ฉ”์‹œ์ง€์˜ String ๊ฐ’์€ null์ด ๋“ค์–ด์˜ฌ ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— Exit๋ฅผ ์ž…๋ ฅํ–ˆ์„ ๊ฒฝ์šฐ ์‚ฌ์šฉ์ž ๋ชฉ๋ก์— ๋Œ€ํ•ด null์„ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ์ฒ˜๋ฆฌ) ๋‚ด๊ฐ€ ๋ด๋„ ์ด ๋ถ€๋ถ„์€ ์ด์ƒํ–ˆ๋‹ค. ใ…Žใ…Ž
 
๊ทธ๋ž˜์„œ ์ด์— ๋Œ€ํ•ด ๋ฆฌ๋ทฐ์–ด๋‹˜์ด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํ”ผ๋“œ๋ฐฑ์„ ์ฃผ์…จ๋‹ค.

๋ฆฌ๋ทฐ๋ฅผ ๋“ฃ๊ณ  ๋จธ๋ฆฌ๊ฐ€ ๋ตํ–ˆ๋‹ค. ๊ฒฐ๊ตญ null์„ ๋ฐ›๊ฒŒ ๋œ ์ด์œ ๋Š”, List ์ž์ฒด๋กœ๋Š” ํ‘œํ˜„ํ•  ์ˆ˜ ์—†๋Š” ๊ฐœ๋…์ด ์กด์žฌํ–ˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
๊ฐ์ฒด์˜ ์ฑ…์ž„์€ ์–ด๋””์—์„œ ์˜ค๋Š”๊ฐ€?๋กœ ์ƒ๊ฐํ•ด๋ดค์„ ๋•Œ, ํ•„์š”ํ•œ ๊ธฐ๋Šฅ๋“ค์— ๋Œ€ํ•ด ์ˆ˜ํ–‰ํ•˜๋Š” ์—ญํ• ์„ ํ•˜๋Š” ๊ฒƒ์ด๊ฒ ๊ตฌ๋‚˜...! ์–ด๋– ํ•œ ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•˜๋Š” ์—ญํ• ์„ ์œ„ํ•ด ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๊ฒ ๊ตฌ๋‚˜! ๋ผ๊ณ  ๊นจ๋‹ฌ์„ ์ˆ˜ ์žˆ์—ˆ๋‹ค.
 
๊ทธ๋ž˜์„œ ๋‹ค์Œ ํ”ผ๋“œ๋ฐฑ์—๋Š” DTO๋ฅผ ํ™œ์šฉํ•ด์ฃผ์—ˆ๋‹ค.

public class ResultParticipantsDto {

    private final boolean isProceed;
    private final List<Participant> participants;

    public ResultParticipantsDto(final List<Participant> participants, final boolean isProceed) {
        this.participants = participants;
        this.isProceed = isProceed;
    }

    public static ResultParticipantsDto create(final List<Participant> participants, final boolean isProceed) {
        return new ResultParticipantsDto(participants, isProceed);
    }

    public boolean isProceed() {
        return isProceed;
    }

    public List<Participant> getParticipants() {
        return List.copyOf(participants);
    }

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

    private void printGameResultWithRetry(final Participants participants, final List<String> ladderResultNames) {
        ResultParticipantsDto resultParticipantsDto;
        do {
            resultParticipantsDto = getResultParticipantsDto(participants);
            outputView.printLadderGameResult(resultParticipantsDto, ladderResultNames);
        } while (resultParticipantsDto.isProceed());
    }

    private ResultParticipantsDto getResultParticipantsDto(final Participants participants) {
        return inputView.getInputWithRetry(() -> {
            String resultParticipantName = inputView.getResultParticipantName();
            return makeResultParticipantsDto(participants, resultParticipantName);
        });
    }

    private ResultParticipantsDto makeResultParticipantsDto(final Participants participants, final String resultParticipantName) {
        if (resultParticipantName.equalsIgnoreCase(EXIT_INPUT_MESSAGE.getMessage())) {
            return ResultParticipantsDto.create(Collections.emptyList(), false);
        }
        List<Participant> resultParticipants = participants.getResultParticipants(resultParticipantName);
        return ResultParticipantsDto.create(resultParticipants, true);
    }
}

๋•๋ถ„์— null์„ ๋ฐ˜ํ™˜ํ•˜์ง€ ์•Š๊ณ , isProceed์— ๋Œ€ํ•œ false / true, ๊ทธ๋ฆฌ๊ณ  Collections.emptyList() ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด์„œ ๋” ์šฉ์ดํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค. NPE๋Š” ํ”ผํ•˜์ž...! ์ด๋ž˜์„œ ์ฝ”ํ‹€๋ฆฐ์„ ๋งŽ์ด ์„ ํ˜ธํ•˜๋Š”๊ตฌ๋‚˜...๋„ ๋ฐฐ์šธ ์ˆ˜ ์žˆ๋˜ ๐Ÿ‘


 
์‚ฌ์‹ค ์ด๊ฒƒ ์™ธ์—๋„ ๋˜๊ฒŒ ๋งŽ์€ ๊ฒƒ๋“ค์„ ๋ฐฐ์› ์ง€๋งŒ...!
PR ์ปค๋ฉ˜ํŠธ์—์„œ ์ถฉ๋ถ„ํžˆ ๋“œ๋Ÿฌ๋‚œ ๊ฒƒ๋“ค์ด๊ธฐ ๋•Œ๋ฌธ์— ์ด์ •๋„๋กœ ์ž‘์„ฑํ•ด๋‘๊ฒ ๋‹ค.
์‚ฌ๋‹ค๋ฆฌ ๋ฏธ์…˜์€ ๋ฆฌ๋ทฐ์–ด๋‹˜์ด ๋„ˆ๋ฌด๋„ˆ๋ฌด๋„ˆ๋ฌด ์ข‹์•˜์–ด์„œ ๋ ˆ๋ฒจ 1 ๋ฏธ์…˜ ์ค‘ ๊ฐ€์žฅ ํ–‰๋ณตํ–ˆ๋‹ค :D
์–ผ๋ฅธ ๋‹ค๋ฅธ ๋ฏธ์…˜๋“ค๋„ ํšŒ๊ณ  ๊ธ€์„ ์ž‘์„ฑํ•ด์•ผ๊ฒ ๋‹ค ใ…Žใ…Ž;;

Comments