# [์šฐ์•„ํ•œํ…Œํฌ์ฝ”์Šค 6๊ธฐ] ํ”„๋ฆฌ์ฝ”์Šค 4์ฃผ์ฐจ ํฌ๋ฆฌ์Šค๋งˆ์Šค ํ”„๋กœ๋ชจ์…˜ ๋ฏธ์…˜ ํ›„๊ธฐ
Study Repository

[์šฐ์•„ํ•œํ…Œํฌ์ฝ”์Šค 6๊ธฐ] ํ”„๋ฆฌ์ฝ”์Šค 4์ฃผ์ฐจ ํฌ๋ฆฌ์Šค๋งˆ์Šค ํ”„๋กœ๋ชจ์…˜ ๋ฏธ์…˜ ํ›„๊ธฐ

by rlaehddnd0422

๊ธธ์—ˆ๋˜ 4์ฃผ๊ฐ„์˜ ํ”„๋ฆฌ์ฝ”์Šค๊ฐ€ ๋์ด ๋‚ฌ์Šต๋‹ˆ๋‹ค. ๋งˆ์ง€๋ง‰ ์ฃผ์ฐจ๋Š” ํฌ๋ฆฌ์Šค๋งˆ์Šค ํ”„๋กœ๋ชจ์…˜ ๋ฏธ์…˜์œผ๋กœ 3์ฃผ์ฐจ ๋กœ๋˜ ๋ฏธ์…˜๊ณผ ๋น„์Šทํ•˜๋˜ ํ™•์žฅ๋œ ๋งฅ๋ฝ์˜ ๋ฏธ์…˜์ด์—ˆ๋Š”๋ฐ์š”. ๊ฐ„๋‹จํ•˜๊ฒŒ ์ด๋ฒˆ ์ฃผ์ฐจ์— ์ ์šฉํ•˜๊ณ  ๊ฐœ์„ ํ•˜๊ณ  ๊ณ ๋ฏผํ•œ ์ ๋“ค์„ ๋ฆฌ๋ทฐํ•ด๋ณด๊ณ ์žํ•ฉ๋‹ˆ๋‹ค.


๐Ÿšฉ4์ฃผ์ฐจ ๋ชฉํ‘œ

  • ์šฐ์„  ์ €๋Š” ์ด๋ฒˆ ๋ฏธ์…˜์—์„œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ชฉํ‘œ๋ฅผ ๋‘์—ˆ์Šต๋‹ˆ๋‹ค.
  1. ์š”๊ตฌ์‚ฌํ•ญ์ด ๋งŽ์•„์ง„ ๋งŒํผ, ๋ช…์„ธ์„œ ๊ผผ๊ผผํ•˜๊ฒŒ ํ™•์ธํ•˜๊ณ  ๊ตฌํ˜„ํ•˜๊ธฐ
  2. ๊ฐ์ฒด๋ฅผ ๊ฐ์ฒด์Šค๋Ÿฝ๊ฒŒ ์‚ฌ์šฉํ•˜๊ธฐ
    1. ๋„๋ฉ”์ธ๊ณผ ๋„๋ฉ”์ธ ์‚ฌ์ด ์˜์กด๊ด€๊ณ„๋ฅผ ๋‘์ง€ ์•Š๊ธฐ
      1. ๊ฐ์ฒด ์ƒ์„ฑ์— ๋‹ค๋ฅธ ๋„๋ฉ”์ธ์˜ ๊ฐ’์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ ๋ฉ”์‹œ์ง€๋ฅผ ํ†ตํ•ด ์—ฐ๊ฒฐ๊ณ ๋ฆฌ๋ฅผ ๋งŒ๋“ค์–ด ์ƒ์„ฑํ•จ์œผ๋กœ์จ, ์‘์ง‘๋„๋ฅผ ๋‚ฎ์ถ”์ž.
    2. getter ์ง€์–‘, TDA(Tell, Don't Ask) ์›์น™ ์ ์šฉ : ๊ฐ์ฒด๊ฐ€ ํ•  ์ˆ˜ ์žˆ๋Š” ์ผ์€ ๊ฐ์ฒด์—๊ฒŒ ๋ฌผ์–ด๋ณด์ง€ ์•Š๊ณ  ์‹œํ‚ค๋„๋ก ํ•˜์ž. 
      1. ๊ฐ์ฒด๊ฐ€ ํ•  ์ˆ˜ ์žˆ๋Š” ์ผ์ด๋ผ ํ•จ์€ ๊ฐ์ฒด์˜ ํ•„๋“œ๊ฐ’์— ๋Œ€ํ•œ ํ•ธ๋“ค๋ง(๊ฒ€์ฆ, ๊ณ„์‚ฐ)
      2. View์—์„œ ๋ถ€๋“์ดํ•˜๊ฒŒ ๊ฐ์ฒด์˜ ํ•„๋“œ๊ฐ’์„ ์ถœ๋ ฅํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ๋ฅผ ์ œ์™ธํ•˜๊ณ  getter๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋„๋ก ํ•˜๊ธฐ.
  3. ๋„ค์ด๋ฐ์— ์กฐ๊ธˆ ๋” ์‹ ๊ฒฝ์“ฐ๊ธฐ
    1. ์˜๋„๋ฅผ ํ•ด์น˜์ง€ ์•Š์Œ๊ณผ ๋™์‹œ์— ํ•œ ๋ˆˆ์— ์•Œ์•„๋ณผ ์ˆ˜ ์žˆ๋Š” ํ‚ค์›Œ๋“œ ์ค‘์‹ฌ์œผ๋กœ ์ž‘๋ช…ํ•˜์ž.
  4. ์ตœ์ข… ์ฝ”๋”ฉ ํ…Œ์ŠคํŠธ์—์„œ ์‹œ๊ฐ„ ๋‚ด์— ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋Š” ์ฝ”๋“œ๋ฅผ ๋งŒ๋“ค์ž.
    1. ๋น„์ฆˆ๋‹ˆ์Šค ํ™•์žฅ์„ฑ์„ ๊ณ ๋ คํ•ด ํ˜„์žฌ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ์ฝ”๋“œ์— ๋Œ€ํ•ด ๋ถˆํ•„์š”ํ•˜๊ฒŒ ๋ณผ๋ฅจ์„ ํ‚ค์šฐ๊ธฐ๋ณด๋‹ค, ์ตœ์ข… ์ฝ”๋”ฉ ํ…Œ์ŠคํŠธ์—์„œ ๋‚ด๊ฐ€ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋Š” ์ฝ”๋“œ๋ฅผ ๊ตฌํ˜„ํ•˜์ž. 
    2. ๋ฌด๋ฆฌํ•œ ํ™•์žฅ์€ ๊ฐ€๋…์„ฑ์„ ์ €ํ•˜์‹œํ‚ฌ ์šฐ๋ ค๊ฐ€ ํฌ๋‹ค. ํ™•์žฅ์„ฑ์„ ๊ณ ๋ คํ•  ์‹œ๊ฐ„์— ์ฐจ๋ผ๋ฆฌ ๊ฐ์ฒด์ง€ํ–ฅ์„ค๊ณ„์— ํž˜์„ ์Ÿ์ž.

ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์š”๊ตฌ์‚ฌํ•ญ๊ณผ ๊ธฐ๋Šฅ ์š”๊ตฌ์‚ฌํ•ญ์„ ์ •๋ฆฌํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

 

๐Ÿšฉํ”„๋กœ๊ทธ๋ž˜๋ฐ ์š”๊ตฌ์‚ฌํ•ญ

โžก๏ธ ์ถ”๊ฐ€๋œ ์š”๊ตฌ ์‚ฌํ•ญ

  • ์•„๋ž˜ ์žˆ๋Š” `InputView`, `OutputView` ํด๋ž˜์Šค๋ฅผ ์ฐธ๊ณ ํ•˜์—ฌ ์ž…์ถœ๋ ฅ ํด๋ž˜์Šค๋ฅผ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.
    • ์ž…๋ ฅ๊ณผ ์ถœ๋ ฅ์„ ๋‹ด๋‹นํ•˜๋Š” ํด๋ž˜์Šค๋ฅผ ๋ณ„๋„๋กœ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.
  • ํ•ด๋‹น ํด๋ž˜์Šค์˜ ํŒจํ‚ค์ง€, ํด๋ž˜์Šค๋ช…, ๋ฉ”์„œ๋“œ์˜ ๋ฐ˜ํ™˜ ํƒ€์ž…๊ณผ ์‹œ๊ทธ๋‹ˆ์ฒ˜๋Š” ์ž์œ ๋กญ๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
public class InputView {
      public int readDate() {
          System.out.println("12์›” ์ค‘ ์‹๋‹น ์˜ˆ์ƒ ๋ฐฉ๋ฌธ ๋‚ ์งœ๋Š” ์–ธ์ œ์ธ๊ฐ€์š”? (์ˆซ์ž๋งŒ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”!)");
          String input = Console.readLine();
      }
  }

public class OutputView {
  public void printMenu() {
      System.out.println("<์ฃผ๋ฌธ ๋ฉ”๋‰ด>");
      // ...
  }
  // ...
}

๐Ÿšฉ๊ธฐ๋Šฅ ์š”๊ตฌ ์‚ฌํ•ญ ์ •๋ฆฌ

โžก๏ธ ๋ฉ”๋‰ด

<์• ํ”ผํƒ€์ด์ €>
์–‘์†ก์ด์ˆ˜ํ”„(6,000), ํƒ€ํŒŒ์Šค(5,500), ์‹œ์ €์ƒ๋Ÿฌ๋“œ(8,000)
<๋ฉ”์ธ>
ํ‹ฐ๋ณธ์Šคํ…Œ์ดํฌ(55,000), ๋ฐ”๋น„ํ๋ฆฝ(54,000), ํ•ด์‚ฐ๋ฌผํŒŒ์Šคํƒ€(35,000), ํฌ๋ฆฌ์Šค๋งˆ์ŠคํŒŒ์Šคํƒ€(25,000)
<๋””์ €ํŠธ>
์ดˆ์ฝ”์ผ€์ดํฌ(15,000), ์•„์ด์Šคํฌ๋ฆผ(5,000)
<์Œ๋ฃŒ>
์ œ๋กœ์ฝœ๋ผ(3,000), ๋ ˆ๋“œ์™€์ธ(60,000), ์ƒดํŽ˜์ธ(25,000)

โžก๏ธ ํ• ์ธ

์ค‘๋ณต๋œ ํ• ์ธ + ์ฆ์ •์œผ๋กœ ์ด๋ฒคํŠธ ๊ธฐ๊ฐ„ : '๋””๋ฐ์ด ํ• ์ธ'์„ ์ œ์™ธํ•œ ๋ชจ๋“  ์ด๋ฒคํŠธ๋Š” 12์›” 1์ผ ~ 31์ผ๊นŒ์ง€ ์ ์šฉํ•œ๋‹ค.
1. ๋””๋ฐ์ด ํ• ์ธ : 1000์›์œผ๋กœ ์‹œ์ž‘ํ•ด์„œ ํ• ์ธ๊ธˆ์•ก์ด 100์›์”ฉ ์ฆ๊ฐ€ํ•œ๋‹ค.
        - ex) 12์›” 1์ผ 1000์›, 2์ผ์— 1100์›, 25์ผ์—” 3400์›
            - ์ด๋ฒคํŠธ ๊ธฐ๊ฐ„ : ํ• ์ธ์€ 12์›” 1์ผ๋ถ€ํ„ฐ 25์ผ๊นŒ์ง€
2. ํ‰์ผ ํ• ์ธ (์ผ์š”์ผ~๋ชฉ์š”์ผ) : ๋””์ €ํŠธ ๋ฉ”๋‰ด๋ฅผ ๋ฉ”๋‰ด 1๊ฐœ๋‹น 2023์› ํ• ์ธ
3. ์ฃผ๋ง ํ• ์ธ (๊ธˆ์š”์ผ,ํ† ์š”์ผ) : ๋ฉ”์ธ ๋ฉ”๋‰ด๋ฅผ ๋ฉ”๋‰ด 1๊ฐœ๋‹น 2023์› ํ• ์ธ
4. ํŠน๋ณ„ ํ• ์ธ : ์ด๋ฒคํŠธ ๋‹ฌ๋ ฅ์— ๋ณ„์ด ์žˆ์œผ๋ฉด ์ด ์ฃผ๋ฌธ ๊ธˆ์•ก์—์„œ 1000์› ํ• ์ธ
5. ์ฆ์ • ์ด๋ฒคํŠธ : ํ• ์ธ ์ „ ์ด ์ฃผ๋ฌธ ๊ธˆ์•ก์ด 120,000์›์ธ ๊ฒฝ์šฐ โ–ถ๏ธŽ "์ƒดํŽ˜์ธ 1๊ฐœ" ์ฆ์ •

โžก๏ธ ๋ฐฐ์ง€

์ด ํ˜œํƒ ๊ธˆ์•ก์ด 5000์› ์ด์ƒ โ–ถ๏ธŽ "๋ณ„" ๋ฐฐ์ง€ ์ฆ์ •
์ด ํ˜œํƒ ๊ธˆ์•ก์ด 1๋งŒ์› ์ด์ƒ โ–ถ๏ธŽ "ํŠธ๋ฆฌ" ๋ฐฐ์ง€ ์ฆ์ •
์ด ํ˜œํƒ ๊ธˆ์•ก์ด 2๋งŒ์› ์ด์ƒ โ–ถ๏ธŽ "์‚ฐํƒ€" ๋ฐฐ์ง€ ์ฆ์ •

โžก๏ธ ์ฃผ์˜ ์‚ฌํ•ญ

  • ์ด ์ฃผ๋ฌธ ๊ธˆ์•ก 10,000์› ์ด์ƒ ๋ถ€ํ„ฐ ์ด๋ฒคํŠธ๋ฅผ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • ์Œ๋ฃŒ๋งŒ ์ฃผ๋ฌธ ์‹œ ์ฃผ๋ฌธ์ด ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
  • ๋ฉ”๋‰ด๋Š” ํ•œ ๋ฒˆ์— ์ตœ๋Œ€ 20๊ฐœ๊นŒ์ง€๋งŒ ์ฃผ๋ฌธ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
    • (e.g. ์‹œ์ €์ƒ๋Ÿฌ๋“œ-1, ํ‹ฐ๋ณธ์Šคํ…Œ์ดํฌ-1, ํฌ๋ฆฌ์Šค๋งˆ์ŠคํŒŒ์Šคํƒ€-1, ์ œ๋กœ์ฝœ๋ผ-3, ์•„์ด์Šคํฌ๋ฆผ-1์˜ ์ด๊ฐœ์ˆ˜๋Š” 7๊ฐœ)

โžก๏ธ ์ถœ๋ ฅ

  • "12์›” ์ค‘ ์‹๋‹น ์˜ˆ์ƒ ๋ฐฉ๋ฌธ ๋‚ ์งœ๋Š” ์–ธ์ œ์ธ๊ฐ€์š”? (์ˆซ์ž๋งŒ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”!)"
    •  ๋ฐฉ๋ฌธํ•  ๋‚ ์งœ๋Š” 1 ์ด์ƒ 31 ์ดํ•˜์˜ ์ˆซ์ž
    •  1 ์ด์ƒ 31 ์ดํ•˜์˜ ์ˆซ์ž๊ฐ€ ์•„๋‹Œ ๊ฒฝ์šฐ, "[ERROR] ์œ ํšจํ•˜์ง€ ์•Š์€ ๋‚ ์งœ์ž…๋‹ˆ๋‹ค. ๋‹ค์‹œ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”."๋ผ๋Š” ์—๋Ÿฌ ๋ฉ”์‹œ์ง€ ์ถœ๋ ฅ
  • "์ฃผ๋ฌธํ•˜์‹ค ๋ฉ”๋‰ด์™€ ๊ฐœ์ˆ˜๋ฅผ ์•Œ๋ ค ์ฃผ์„ธ์š”. (e.g. ํ•ด์‚ฐ๋ฌผํŒŒ์Šคํƒ€-2,๋ ˆ๋“œ์™€์ธ-1,์ดˆ์ฝ”์ผ€์ดํฌ-1)"
    •  ๋ฉ”๋‰ดํŒ์— ์—†๋Š” ๋ฉ”๋‰ด๋ฅผ ์ž…๋ ฅํ•˜๋Š” ๊ฒฝ์šฐ, "[ERROR] ์œ ํšจํ•˜์ง€ ์•Š์€ ์ฃผ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋‹ค์‹œ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”."๋ผ๋Š” ์—๋Ÿฌ ๋ฉ”์‹œ์ง€ ์ถœ๋ ฅ
    •  ๋ฉ”๋‰ด์˜ ๊ฐœ์ˆ˜๋Š” 1 ์ด์ƒ์˜ ์ˆซ์ž๋งŒ ์ž…๋ ฅ๋˜๋„๋ก ํ•ด์ฃผ์„ธ์š”. ์ด์™ธ์˜ ์ž…๋ ฅ๊ฐ’์€ "[ERROR] ์œ ํšจํ•˜์ง€ ์•Š์€ ์ฃผ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋‹ค์‹œ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”."๋ผ๋Š” ์—๋Ÿฌ ๋ฉ”์‹œ์ง€ ์ถœ๋ ฅ
    •  ๋ฉ”๋‰ด ํ˜•์‹์ด ์˜ˆ์‹œ์™€ ๋‹ค๋ฅธ ๊ฒฝ์šฐ, "[ERROR] ์œ ํšจํ•˜์ง€ ์•Š์€ ์ฃผ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋‹ค์‹œ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”."๋ผ๋Š” ์—๋Ÿฌ ๋ฉ”์‹œ์ง€ ์ถœ๋ ฅ
    •  ์ค‘๋ณต ๋ฉ”๋‰ด๋ฅผ ์ž…๋ ฅํ•œ ๊ฒฝ์šฐ(e.g. ์‹œ์ €์ƒ๋Ÿฌ๋“œ-1,์‹œ์ €์ƒ๋Ÿฌ๋“œ-1), "[ERROR] ์œ ํšจํ•˜์ง€ ์•Š์€ ์ฃผ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋‹ค์‹œ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”."๋ผ๋Š”์—๋Ÿฌ ๋ฉ”์‹œ์ง€ ์ถœ๋ ฅ
  • ์ฃผ๋ฌธ ๋ฉ”๋‰ด ์ถœ๋ ฅ
    • ์ˆœ์„œ๋Š” ์ž์œ ๋กญ๊ฒŒ ์ถœ๋ ฅ ๊ฐ€๋Šฅ
  • ํ• ์ธ ์ „ ์ด ์ฃผ๋ฌธ ๊ธˆ์•ก ์ถœ๋ ฅ
  • ์ฆ์ • ๋ฉ”๋‰ด
    •  ํ• ์ธ ํ›„ ์˜ˆ์ƒ ๊ฒฐ์ œ ๊ธˆ์•ก(ํ• ์ธ ์ „ ์ด์ฃผ๋ฌธ ๊ธˆ์•ก - ํ• ์ธ ๊ธˆ์•ก)์ด 120,000์› ์ด์ƒ์ธ ๊ฒฝ์šฐ "์ƒดํŽ˜์ธ 1๊ฐœ" ์ถœ๋ ฅ
    •  ์ฆ์ • ์ด๋ฒคํŠธ์— ํ•ด๋‹นํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ, ์ฆ์ • ๋ฉ”๋‰ด "์—†์Œ"์œผ๋กœ ์ถœ๋ ฅ
  • ํ˜œํƒ ๋‚ด์—ญ
    •  ์ ์šฉ๋œ ์ด๋ฒคํŠธ ๋‚ด์—ญ’๋งŒ’ ์ถœ๋ ฅ
    •  ์ ์šฉ๋œ ์ด๋ฒคํŠธ๊ฐ€ ์—†๋‹ค๋ฉด ํ˜œํƒ ๋‚ด์—ญ "์—†์Œ"์œผ๋กœ ์ถœ๋ ฅ
    •  ํ˜œํƒ ๋‚ด์—ญ์— ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์ด๋ฒคํŠธ๊ฐ€ ์ ์šฉ๋œ ๊ฒฝ์šฐ, ์ถœ๋ ฅ ์ˆœ์„œ๋Š” ์ž์œ ๋กญ๊ฒŒ ์ถœ๋ ฅ๊ฐ€๋Šฅ
  • ์ดํ˜œํƒ ๊ธˆ์•ก(ํ• ์ธ ๊ธˆ์•ก์˜ ํ•ฉ๊ณ„ + ์ฆ์ • ๋ฉ”๋‰ด์˜ ๊ฐ€๊ฒฉ) ์ถœ๋ ฅ
  • ์ด๋ฒคํŠธ ๋ฐฐ์ง€
    • ์ดํ˜œํƒ ๊ธˆ์•ก์— ๋”ฐ๋ผ ์ด๋ฒคํŠธ ๋ฐฐ์ง€์˜ ์ด๋ฆ„์„ ๋‹ค๋ฅด๊ฒŒ ์ถœ๋ ฅ
    • ์ด๋ฒคํŠธ ๋ฐฐ์ง€๊ฐ€ ๋ถ€์—ฌ๋˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ, "์—†์Œ"์œผ๋กœ ์ถœ๋ ฅ

๐Ÿšฉ ์ž…๋ ฅ๊ฐ’ ํŒŒ์‹ฑ

๋ฐฉ๋ฌธ ๋‚ ์งœ์— ๋Œ€ํ•œ ์ž…๋ ฅ์€ InputValidtor์—์„œ ์ˆซ์ž ์ž…๋ ฅ์— ๋Œ€ํ•œ ๊ฒ€์ฆ์„ ๋งˆ์นœ ํ›„ VisitDay๋ผ๋Š” Value Object(์ด์ œ๋ถ€ํ„ฐ ์ค„์—ฌ VO๋ผ๊ณ  ์นญํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค)๋ฅผ ์ƒ์„ฑํ•˜๋˜, ์ƒ์„ฑ์ž์—์„œ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง๊ณผ ์—ฐ๊ด€๋œ ๊ฒ€์ฆ์„ ์ˆ˜ํ–‰ํ•˜๊ณ  ๊ฒ€์ฆ์— ํ†ต๊ณผํ•˜๋ฉด ์ •์ƒ์ ์œผ๋กœ ์ƒ์„ฑ์ž๊ฐ€ ๋™์ž‘ํ•˜๊ณ , ํ†ต๊ณผํ•˜์ง€ ๋ชปํ•˜๋ฉด ์ปค์Šคํ…€ํ•œ RuntimeException์„ ๋˜์ง€๋„๋ก ๊ตฌํ˜„ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

public VisitDay {
    validate(day);
}

private void validate(final Integer day) {
    if (!isInMonth(day)) {
        throw new InvalidValueOfDayException();
    }
}

private boolean isInMonth(final Integer day) {
    if (day >= START_DAY_OF_MONTH && day <= END_DAY_OF_MONTH) {
        return true;
    }
    return false;
}

 

 

์ฃผ๋ฌธ์— ๋Œ€ํ•œ ์ž…๋ ฅ์€ "์‹œ์ €์ƒ๋Ÿฌ๋“œ-1, ํ‹ฐ๋ณธ์Šคํ…Œ์ดํฌ-1, ํฌ๋ฆฌ์Šค๋งˆ์ŠคํŒŒ์Šคํƒ€-1, ์ œ๋กœ์ฝœ๋ผ-3, ์•„์ด์Šคํฌ๋ฆผ-1"์™€ ๊ฐ™์ด ๊ฐ ๋ฉ”๋‰ด๋Š” ","๋กœ ๋ถ„๋ฆฌํ•˜๊ณ  ๋ฉ”๋‰ด์— ๋Œ€ํ•œ ์ˆ˜๋Ÿ‰์€ "-"์œผ๋กœ ๋ถ„๋ฆฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. 

1. String์„ ","์„ ๊ธฐ์ ์œผ๋กœ ์Šฌ๋ผ์ด์‹ฑ

  • ์šฐ์„  ","์„ ๊ธฐ์ ์œผ๋กœ ์ž…๋ ฅ๋ฐ›์€ String์„ ์Šฌ๋ผ์ด์‹ฑํ•˜ํ•˜์—ฌ ์ฃผ๋ฌธ์˜ "๋ฉ”๋‰ด-์ˆ˜๋Ÿ‰"์„ String ํ˜•ํƒœ๋กœ List Collection์— ์ €์žฅํ•˜์˜€์Šต๋‹ˆ๋‹ค.

 

2. "-"์„ ๊ธฐ์ ์œผ๋กœ ์Šฌ๋ผ์ด์‹ฑํ•˜์—ฌ Map์— ์‚ฝ์ž…

  • 1๋ฒˆ ๊ณผ์ •์„ ํ†ตํ•ด ์ €์žฅํ•œ List<String>์„ streamํ•˜์—ฌ "-"์„ ๊ธฐ์ ์œผ๋กœ ์Šฌ๋ผ์ด์‹ฑํ•˜์—ฌ ๊ฐ๊ฐ์˜ ํ•„๋“œ๊ฐ’์„ ํ†ตํ•ด VO๋ฅผ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค.

 

3. VO๋กœ ๋งŒ๋“ค์–ด์ง„ ๊ฐ์ฒด๋“ค์„ Map์— ์‚ฝ์ž…

2๋ฒˆ ๊ณผ์ •์„ ํ†ตํ•ด ์Šฌ๋ผ์ด์‹ฑํ•œ String ๊ฐ’๋“ค์„ Map์— VO(Food์™€ Quantity)๋ฅผ ๋‹ด์•„์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค.

 

  • ๋งŒ๋“ค์–ด์ง„ Map์˜ ์ •๋ณด๋ฅผ ํ† ๋Œ€๋กœ ์ฃผ๋ฌธ ํด๋ž˜์Šค์˜ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ์‚ฌ์šฉํ•˜์˜€์Šต๋‹ˆ๋‹ค.
  • Order ํด๋ž˜์Šค๋Š” ๋น„์ฆˆ๋‹ˆ์Šค์™€ ์—ฐ๊ด€์ด ๊นŠ์€ ๋ชจ๋ธ๋กœ์„œ, ๊ธฐ๋ณธ ์ƒ์„ฑ์ž๋ฅผ private์œผ๋กœ ๋ง‰์•„์ฃผ๊ณ , ์ •์  ํŒฉํ† ๋ฆฌ ๋ฉ”์†Œ๋“œ ํŒจํ„ด์„ ์ ์šฉํ•˜์˜€๊ณ , ๋ฐฉ๋ฌธ ์ผ์ž์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๋„๋ฉ”์ธ ๋‚ด๋ถ€์—์„œ ๋น„์ฆˆ๋‹ˆ์Šค์™€ ์—ฐ๊ด€๋œ ๊ฐ’์— ๋Œ€ํ•œ ๊ฒ€์ฆ์„ ์ˆ˜ํ–‰ํ•ด์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค.
private Order(final Map<Food, Quantity> foodAndQuantity) {
    validate(foodAndQuantity);
    this.foodAndQuantity = foodAndQuantity;
}

public static Order create(final Map<Food, Quantity> foodAndQuantity) {
    return new Order(foodAndQuantity);
}

private void validate(final Map<Food, Quantity> foodAndQuantity) {
    if (isOrderOverMaxQuantity(foodAndQuantity)) {
        throw new OverMaxQuantityOrderException();
    }
    if (isContainOnlyDrink(foodAndQuantity)) {
        throw new OnlyDrinkOrderException();
    }
}

๐ŸšฉValue Object, record ๊ด€๋ฆฌ ๊ธฐ์ค€

์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•œ ๊ฐ’์ธ๊ฐ€? ------------> Value object๋กœ์„œ record๋กœ ๊ด€๋ฆฌ
else ------------> class๋กœ ๊ด€๋ฆฌ

 

์ €๋Š” ์œ„์™€ ๊ฐ™์€ ๊ธฐ์ค€์„ ์„ ๋‘๊ณ , VO์— ํ•œํ•˜์—ฌ model ํŒจํ‚ค์ง€ ๋‚ด๋ถ€์— vo ํŒจํ‚ค์ง€๋ฅผ ๋‘๊ณ , record๋กœ ๊ด€๋ฆฌํ•˜์—ฌ ๊ตฌ๋ถ„ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

 

 

Value Object๋ฅผ class๋กœ ๊ด€๋ฆฌํ•˜๋Š” ๊ฒฝ์šฐ ๋‘ ํ•„๋“œ ๊ฐ’์ด ๋™์ผํ•˜๋ฉด ๋™๋“ฑ, ๋™์ผํ•œ ๊ฐ์ฒด๋กœ ํŒ๋‹จํ•˜๋„๋ก equals์™€ hashCode ๋ฉ”์†Œ๋“œ๋ฅผ ๋ณ„๋„๋กœ ์ž‘์„ฑํ•˜์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค. Value Object๋กœ ๊ด€๋ฆฌํ•˜๋ƒ, ๋˜๋Š” ๋‹จ์ˆœ ์›์‹œ๊ฐ’์„ ํฌ์žฅํ•œ class๋กœ ๊ด€๋ฆฌํ•˜๋ƒ, ์ด ๊ธฐ์ค€์ ์„ ์–ด๋–ป๊ฒŒ ๋‘์–ด์•ผ ํ•  ์ง€ ๊ณ ๋ฏผ์ด ๋งŽ์•˜๋Š”๋ฐ, ์ €๋Š” ํšŒ์›๊ฐ€์ž…์„ ํ•  ๋•Œ ์ค‘๋ณต ์•„์ด๋””๋ฅผ ๊ฒ€์‚ฌํ•˜๊ฑฐ๋‚˜ ๋˜๋Š” ์œ„์™€ ๊ฐ™์ด ํšŒ์› ์ •๋ณด๋ฅผ ์ˆ˜์ •ํ•˜๋Š” ๊ฒฝ์šฐ ๊ฒฝ์šฐ ๊ฐ’์„ record๋กœ ๊ด€๋ฆฌํ•˜๋ฉด, ์ค‘๋ณต ๊ฒ€์‚ฌ ๋ณ„๋„์˜ ๊ฒ€์‚ฌ ๋กœ์ง์„ ๊ตฌํ˜„ํ•˜์ง€ ์•Š์•„๋„ ํ•„๋“œ๊ฐ’์— ๋Œ€ํ•ด equals()์™€ hashCode()๊ฐ€ ์ž๋™์œผ๋กœ ์ ์šฉ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ด Value Object๋ฅผ record๋กœ ๊ด€๋ฆฌํ•จ์œผ๋กœ์จ ์ฝ”๋“œ์˜ ๋ณต์žก๋„๋ฅผ ๋‚ฎ์ถœ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ฒฐ๋ก ์ ์œผ๋กœ ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•œ ๊ฐ’์— ํ•œํ•ด์„œ record๋กœ ๊ด€๋ฆฌํ•˜๋„๋ก ๊ตฌํ˜„ํ•˜์˜€์Šต๋‹ˆ๋‹ค. 

 

๋ฏธ์…˜๊ณผ ์—ฐ๊ด€๋œ Food record๋ฅผ ์˜ˆ๋กœ ๋“ค์–ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

Order ํด๋ž˜์Šค๊ฐ€ ๊ฐ€์ง€๋Š” Map ํ•„๋“œ์—๋Š” ์Œ์‹์˜ ์ด๋ฆ„์— ๋Œ€ํ•œ ํ•„๋“œ๊ฐ’์„ ํฌ์žฅํ•œ Food record์™€ ์ˆ˜๋Ÿ‰์— ๋Œ€ํ•œ ํ•„๋“œ๊ฐ’์„ ํฌ์žฅํ•œ Quantity๊ฐ€ ๋‹ด๊น๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ฃผ๋ฌธ์—๋Š” ์ค‘๋ณต๋œ Food์˜ name์„ ๊ฐ€์งˆ ์ˆ˜ ์—†๋‹ค๋Š” ์š”๊ตฌ์‚ฌํ•ญ์ด ์žˆ์Šต๋‹ˆ๋‹ค. 

 

eg) ํ•ด์‚ฐ๋ฌผํŒŒ์Šคํƒ€-1, ํ•ด์‚ฐ๋ฌผํŒŒ์Šคํƒ€-2 โ–ถ๏ธŽ should throw RuntimeException

public class Food {
    
    private final String name;
    
    public Food(String name) {
        validate(name);
        this.name = name;
    }

    private void validate(final String name) {
        if (!isContainInMenu(name)) {
            throw new OrderNotInMenuException();
        }
    }

    private boolean isContainInMenu(final String name) {
        return Arrays.stream(Menu.values())
                .anyMatch(menu -> menu.getSalesMenu().containsKey(name));
    }

    public boolean isDrink() {
        return DRINK.getSalesMenu()
                .containsKey(name);
    }

    public String getName() {
        return name;
    }
}
  • ๋งŒ์•ฝ Food record๋ฅผ ์œ„์™€ ๊ฐ™์ด ๋‹จ์ˆœํ•˜๊ฒŒ "์Œ์‹์˜ ์ด๋ฆ„"์„ ์›์‹œ๊ฐ’์„ ํฌ์žฅํ•œ class๋กœ ๊ด€๋ฆฌํ•˜๋Š” ๊ฒฝ์šฐ, equals์™€ hashCode๋ฉ”์†Œ๋“œ๋ฅผ ๋ณ„๋„๋กœ ๊ตฌํ˜„ํ•˜์ง€ ์•Š์œผ๋ฉด ์ค‘๋ณต๋œ ์ด๋ฆ„์— ๋Œ€ํ•ด ๊ฒ€์‚ฌํ•˜๋Š” ์•„๋ž˜์˜ ์ฝ”๋“œ๊ฐ€ ์˜๋„๋Œ€๋กœ ๋™์ž‘ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
private static Map<Food, Quantity> splitAndMapping(final List<String> menuItems) {
    return menuItems.stream()
            .map(item -> item.split(QUANTITY_DELIMITER))
            .collect(Collectors.toMap(
                    foodAndQuantity -> getFood(Arrays.asList(foodAndQuantity)),
                    foodAndQuantity -> getQuantity(Arrays.asList(foodAndQuantity)),
                    (existing, replacement) -> {
                        throw new AlreadyExistsInOrderException();
                    }
            ));
}
  • ๊ฐ’์ด ๋™์ผํ•œ ๊ฒฝ์šฐ์—๋„ ๋™์ผ, ๋™๋“ฑํ•œ ๊ฐ์ฒด๋กœ ํŒ๋‹จํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— toMap์˜ mergeFunction์—์„œ ์˜ˆ์™ธ๊ฐ€ ์ •์ƒ์ ์œผ๋กœ ๋ฐœ์ƒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
public record Food(String name) {

    public Food {
        validate(name);
    }

    private void validate(final String name) {
        if (!isContainInMenu(name)) {
            throw new OrderNotInMenuException();
        }
    }

    private boolean isContainInMenu(final String name) {
        return Arrays.stream(Menu.values())
                .anyMatch(menu -> menu.getSalesMenu().containsKey(name));
    }

    public boolean isDrink() {
        return DRINK.getSalesMenu()
                .containsKey(name);
    }
}
  • record๋Š” ์›์‹œ๊ฐ’์„ ํฌ์žฅํ•  ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋ ˆ์ฝ”๋“œ์˜ ๋™์ผํ•œ ํ•„๋“œ๊ฐ’์— ๋Œ€ํ•œ ๋™๋“ฑ์„ฑ, ๋™์ผ์„ฑ๊นŒ์ง€ ๋ณด์žฅํ•ด์ฃผ๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•œ ๊ฐ’์„ record๋กœ ๊ด€๋ฆฌํ•œ๋‹ค๋ฉด, ์ด๋Ÿฐ ๋ถ€๋ถ„๋“ค์„ ์‹ ๊ฒฝ์“ฐ์ง€ ์•Š์•„๋„ ๋œ๋‹ค๋Š” ์žฅ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค..

ํŒจํ‚ค์ง€๋Š” model ํŒจํ‚ค์ง€ ์™ธ๋ถ€์— ๋ณ„๋„์˜ vo ํŒจํ‚ค์ง€๋ฅผ ๋‘์–ด ๊ด€๋ฆฌํ•˜์ž๋‹ˆ, ๊ฐ’ ๊ฐ์ฒด ๋˜ํ•œ ๋น„์ฆˆ๋‹ˆ์Šค์™€ ์—ฐ๊ด€์„ฑ์ด ์žˆ๋‹ค๊ณ  ํŒ๋‹จํ•ด์„œ model ํŒจํ‚ค์ง€ ๋‚ด๋ถ€์— vo ํŒจํ‚ค์ง€๋ฅผ ๋‘์—ˆ์Šต๋‹ˆ๋‹ค.

๐Ÿšฉ enum ํ™œ์šฉ

โžก๏ธ enum ์ƒ์ˆ˜ 

์ง€๋‚œ ๋ฏธ์…˜ enum์„ ์ ์šฉํ•ด๋ณธ ๊ฒฝํ—˜์ด ์ด๋ฒˆ ๋ฏธ์…˜์—์„œ ์ƒ๋Œ€์ ์œผ๋กœ ์‰ฝ๊ฒŒ ์ ์šฉํ•˜๋„๋ก ๋„์™”๋˜ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

์ง€๋‚œ ๋ฏธ์…˜์—์„œ ๋ฐœ์ „ํ•œ ์ ์ด ์žˆ๋‹ค๋ฉด ์ง€๋‚œ ๋ฏธ์…˜์—์„œ๋Š” ์—ฐ๊ด€์„ฑ๋ณด๋‹ค๋Š” Type์„ ๊ธฐ์ค€์œผ๋กœ enum์œผ๋กœ ๋‚˜๋ˆ„์–ด ๊ด€๋ฆฌํ–ˆ๋‹ค๋ฉด, ์ด๋ฒˆ์—๋Š” ์ƒ์ˆ˜๋ผ๋ฆฌ ์—ฐ๊ด€์„ฑ์ด ์žˆ๋Š” ๊ฒฝ์šฐ์— ํ•œํ•ด์„œ๋งŒ enum์œผ๋กœ ๊ด€๋ฆฌํ–ˆ๋‹ค๋Š” ์ ์ž…๋‹ˆ๋‹ค!

3์ฃผ์ฐจ ๋ฏธ์…˜(์ขŒ)๊ณผ 4์ฃผ์ฐจ ๋ฏธ์…˜(์šฐ) enum ๊ด€๋ฆฌ ์˜ˆ์‹œ

  • 3์ฃผ์ฐจ ๋ฏธ์…˜์—์„œ๋Š” ์œ„ ์™ผ์ชฝ ์ฝ”๋“œ์™€ ๊ฐ™์ด ์—ฐ๊ด€์„ฑ์ด ์—†์Œ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ๊ฐ™์€ Integer Type์ด๋ผ๋Š” ์ด์œ  ํ•˜๋‚˜๋งŒ์œผ๋กœ LottoInfo enum์œผ๋กœ ํ‰์ณ์„œ ๊ด€๋ฆฌํ–ˆ๋Š”๋ฐ ์ด์ œ ๋Œ์•„๋ณด๋‹ˆ ์ด๋ ‡๊ฒŒ ๊ด€๋ฆฌํ•˜๊ฒŒ๋˜๋ฉด, ๋‚˜์ค‘์— ์ค‘๊ตฌ๋‚œ๋ฐฉ์ด ๋  ์šฐ๋ ค๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. 
  • 4์ฃผ์ฐจ์—์„œ๋Š” ์œ„ ์˜ค๋ฅธ์ชฝ ์ฝ”๋“œ์™€ ๊ฐ™์ด 'ํ• ์ธ ๊ธˆ์•ก์— ๋Œ€ํ•œ ์ •๋ณด'๋ผ๋Š” ์—ฐ๊ด€์„ฑ์„ ๊ฐ€์ง€๋Š” ์ƒ์ˆ˜๋“ค์„ DiscountInfo๋กœ ๋ฌถ์–ด enum์œผ๋กœ ๊ด€๋ฆฌํ–ˆ๊ณ , ์•„๋ž˜ ์ฝ”๋“œ์™€ ๊ฐ™์ด ์„ ๋ฌผ๊ณผ ๋ฐฐ์ง€์— ๋Œ€ํ•œ ์ƒ์ˆ˜๋Š” ์„œ๋กœ ์—ฐ๊ด€๋œ ์ •๋ณด๋ฅผ ์—ฌ๋Ÿฌ ํ•„๋“œ๋กœ ๋ฌถ์–ด ๊ด€๋ฆฌํ–ˆ์Šต๋‹ˆ๋‹ค!
public enum GiftInfo {

    ONE_CHAMPAGNE("์ƒดํŽ˜์ธ 1๊ฐœ", 120000, 25000),
    NONE_GIFT("์—†์Œ", 0, 0);

    private final String giftName;
    private final Integer requiredAmount;
    private final Integer giftAmount;
public enum BadgeInfo {

    SANTA_BADGE("์‚ฐํƒ€", 20000),
    TREE_BADGE("ํŠธ๋ฆฌ", 10000),
    STAR_BADGE("๋ณ„", 5000),
    NONE_BADGE("์—†์Œ", 0);

    private final String badgeName;
    private final Integer requiredAmount;
  • ๋ฉ”๋‰ด๋Š” ๊ฐ ๋ฉ”๋‰ด์˜ ์นดํ…Œ๊ณ ๋ฆฌ์™€ ํ•จ๊ป˜ ๊ฐ ๋ฉ”๋‰ด์˜ ์ด๋ฆ„๊ณผ ๊ฐ€๊ฒฉ์„ Map์„ ํ†ตํ•ด ๊ด€๋ฆฌํ•˜๋„๋ก ์„ค์ •ํ–ˆ์Šต๋‹ˆ๋‹ค!
public enum Menu {

    APPETIZER(Map.of("์–‘์†ก์ด์ˆ˜ํ”„", 6000,
            "ํƒ€ํŒŒ์Šค", 5500,
            "์‹œ์ €์ƒ๋Ÿฌ๋“œ", 8000)),
    MAIN(Map.of(
            "ํ‹ฐ๋ณธ์Šคํ…Œ์ดํฌ", 55000,
            "๋ฐ”๋น„ํ๋ฆฝ", 54000,
            "ํ•ด์‚ฐ๋ฌผํŒŒ์Šคํƒ€", 35000,
            "ํฌ๋ฆฌ์Šค๋งˆ์ŠคํŒŒ์Šคํƒ€", 25000)),
    DESSERT(Map.of(
            "์ดˆ์ฝ”์ผ€์ดํฌ", 15000,
            "์•„์ด์Šคํฌ๋ฆผ", 5000)),
    DRINK(Map.of(
            "์ œ๋กœ์ฝœ๋ผ", 3000,
            "๋ ˆ๋“œ์™€์ธ", 60000,
            "์ƒดํŽ˜์ธ", 25000));

 

๊ทธ ์™ธ ์—ฐ๊ด€์„ฑ์ด ์—†๊ณ , ํด๋ž˜์Šค์—์„œ๋งŒ ์‚ฌ์šฉํ•˜๋Š” ๋งค์ง๋„˜๋ฒ„๋“ค์€ static final ์ƒ์ˆ˜๋กœ ๊ด€๋ฆฌํ•˜์˜€์Šต๋‹ˆ๋‹ค.


โžก๏ธ enumMap

public class Discount {

    private static final Integer NO_QUANTITY = 0;
    private static final Integer NO_DISCOUNT_AMOUNT = 0;
    private static final Integer PRESENT_YEAR = 2023;

    private final Map<DiscountPolicy, DiscountAmount> discountDetails;

 

์‚ฌ์šฉ์ž์˜ ์ฃผ๋ฌธ์— ์˜ํ•ด ์ƒ์„ฑ๋œ ํ• ์ธ ์ •๋ณด๋ฅผ ๊ฐ–๋Š” Discount ํด๋ž˜์Šค์˜ ํ•„๋“œ๋ฅผ ์•„๋ž˜์™€ ๊ฐ™์ด DiscountPolicy๋ผ๋Š” enum์„ ๋‘๊ณ  ๊ฐ ํ• ์ธ ๊ธˆ์•ก์˜ ์›์‹œ๊ฐ’์„ ํฌ์žฅํ•œ DiscountAmount์™€ ํ•จ๊ป˜ Map์œผ๋กœ ๊ด€๋ฆฌํ•˜๋„๋ก ๊ตฌํ˜„ํ•˜์˜€์Šต๋‹ˆ๋‹ค!

public enum DiscountPolicy {

    WEEKDAY_DISCOUNT("ํ‰์ผ ํ• ์ธ"),
    WEEKEND_DISCOUNT("์ฃผ๋ง ํ• ์ธ"),
    D_DAY_DISCOUNT("ํฌ๋ฆฌ์Šค๋งˆ์Šค ๋””๋ฐ์ด ํ• ์ธ"),
    GIFT_DISCOUNT("์ฆ์ • ์ด๋ฒคํŠธ"),
    SPECIAL_DISCOUNT("ํŠน๋ณ„ ํ• ์ธ");

๐Ÿšฉ๊ฐ€์žฅ ๊ณ ๋ฏผํ–ˆ๋˜ ์  : ํ• ์ธ์ •์ฑ… ๋ถ„๋ฆฌ 

ํ• ์ธ ํด๋ž˜์Šค์˜ ๊ฐ ํ• ์ธ ์ •์ฑ…์„ ๋ถ„๋ฆฌํ•˜์—ฌ ๊ด€๋ฆฌํ•ด์•ผ ํ•  ์ง€ ๊ณ ๋ฏผ์ด ๋งŽ์•˜์Šต๋‹ˆ๋‹ค. ๋ถ„๋ฆฌ๋ฅผ ๊ฐ€์žฅ ๊ณ ๋ฏผํ–ˆ๋˜ ์ด์œ ๋Š” ํ• ์ธ ๊ฐ์ฒด ์ƒ์„ฑ์ž ๋ฉ”์†Œ๋“œ๋ฅผ ๋ณด๋ฉด ์ฝ”๋“œ๊ฐ€ ์ƒ๋‹นํžˆ ๊ธธ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋งŽ์ด ๊ฐ€์ง€๊ณ  ์žˆ์–ด ํ…Œ์ŠคํŠธ๊ฐ€ ์–ด๋ ค์›Œ์ง€๊ณ , ๋ณ€๊ฒฝ์ด ์–ด๋ ค์›Œ์ง€๋Š” ๊ตฌ์กฐ๋ฅผ ๊ฐ–๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด์—ˆ์Šต๋‹ˆ๋‹ค. ๊ฒฐ๋ก ์ ์œผ๋กœ๋Š” ๋ถ„๋ฆฌ๋ฅผ ์„ ํƒํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ๊ทธ ์ด์œ ๋Š” 

 

์ฒซ ๋ฒˆ์งธ, ํ™•์žฅ์„ฑ์„ ์ƒ๊ฐํ•˜์ง€ ์•Š๊ธฐ๋กœ ํ•œ ๋ชฉํ‘œ๋ฅผ ๊ณ ๋ คํ•ด ์ฝ”๋“œ๋ฅผ ๋ณด์•˜์„ ๋•Œ, ๋ฌธ์ œ ๋  ๊ฒƒ์ด ์—†๋‹ค๊ณ  ํŒ๋‹จํ–ˆ์Šต๋‹ˆ๋‹ค.

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

 

๋‘ ๋ฒˆ์งธ, ๋ถ„๋ฆฌ๋ฅผ ํ•  ๊ฒฝ์šฐ ๋ถˆํ•„์š”ํ•œ ๋ณต์žก์„ฑ์ด ์ฆ๊ฐ€ํ•œ๋‹ค.

  • ํ˜„์žฌ Discount ํด๋ž˜์Šค๋Š” "ํ• ์ธ ์ •๋ณด๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ํ•„๋“œ๋กœ ๊ฐ€์ง€๋Š” ๊ธฐ๋Šฅ, ์ž์‹ ์˜ ํ•„๋“œ๊ฐ’์„ ํ† ๋Œ€๋กœ ํ• ์ธ์˜ ์ด ๊ธˆ์•ก์„ ๊ณ„์‚ฐํ•˜์—ฌ ๋ฉ”์‹œ์ง€๋ฅผ ๋ฆฌํ„ดํ•˜๋Š” ๊ธฐ๋Šฅ, ์ฆ์ • ์ด๋ฒคํŠธ์˜ ํ• ์ธ ๊ธˆ์•ก์— ๋Œ€ํ•œ ๋ฉ”์‹œ์ง€๋ฅผ ๋ฆฌํ„ดํ•˜๋Š” ๊ธฐ๋Šฅ"์„ ๊ฐ€์ง‘๋‹ˆ๋‹ค. Discount ํด๋ž˜์Šค๊ฐ€ ์ƒ์„ฑ์ž๋ฅผ ํ†ตํ•œ ๊ธฐ๋Šฅ์„ ์ œ์™ธํ•˜๊ณ ๋Š” ๋‘ ๊ฐ€์ง€ ๊ธฐ๋Šฅ์„ ๊ฐ€์ง€๊ธฐ ๋•Œ๋ฌธ์— ๊ตณ์ด ๋ถ„๋ฆฌ๋ฅผ ํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค.
    • ๋งŒ์•ฝ Discount ํด๋ž˜์Šค๊ฐ€ ์ด ๋‘ ๊ฐ€์ง€์˜ ๊ธฐ๋Šฅ ์™ธ์— ๋‹ค๋ฅธ ๊ธฐ๋Šฅ๋“ค๊นŒ์ง€ ์ถ”๊ฐ€๋˜์–ด์•ผ ํ•˜๋Š” ์‹œ์ ์—์„œ๋Š” ํ• ์ธ ์ •์ฑ…๋“ค์„ ๋ถ„๋ฆฌํ•จ์œผ๋กœ์จ ๋ณต์žก์„ฑ์„ ๋‚ฎ์ถ”๋Š” ๊ฒƒ์„ ๊ณ ๋ คํ•ด๋ณด์•˜๊ฒ ์ง€๋งŒ, ํ˜„์žฌ๋กœ์„œ๋Š” ๋‘ ๊ฐ€์ง€ ๊ธฐ๋Šฅ์ด private ๋ฉ”์†Œ๋“œ๋ฅด ๊ฐ€์ง„๋‹ค๊ฑฐ๋‚˜, ์ฝ๊ธฐ ์–ด๋ ค์šด ์ฝ”๋“œ๊ฐ€ ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ํ• ์ธ ์ •์ฑ…๋“ค์„ ๋‹น์žฅ ๋ถ„๋ฆฌํ•ด์•ผ ํ•  ์ด์œ ๊ฐ€ ์—†๋‹ค๊ณ  ํŒ๋‹จ
public static Discount create(final Integer orderAmount, final Integer mainQuantity, final Integer dessertQuantity,
                              final VisitDay visitDay, final boolean isGiftReceived) {
    Map<DiscountPolicy, DiscountAmount> discountDetails = new HashMap<>();

    if (orderAmount < EVENT_ATTEND_MINIMUM_ORDER_AMOUNT.getAmount()) {
        return new Discount(discountDetails);
    }

    putWeekDayDiscount(dessertQuantity, visitDay, discountDetails);
    putWeekendDayDiscount(mainQuantity, visitDay, discountDetails);
    putD_DayDiscount(visitDay, discountDetails);
    putSpecialDayDiscount(visitDay, discountDetails);
    putGiftDiscount(isGiftReceived, discountDetails);

    return new Discount(discountDetails);
}

๐Ÿšฉ Review : ๊ฐœ์„ ํ•ด์•ผ ํ•  ์ ๋“ค

โžก๏ธ  View๋กœ ๊ฒ€์ฆ ๋กœ์ง ์˜ฎ๊ธฐ๊ธฐ

  • ํ˜„์žฌ Controller์—์„œ discountDetails์˜ ์ •๋ณด๋ฅผ ํŒ๋‹จํ•˜๊ณ , ํŒ๋‹จ์— ๋Œ€์‘ํ•˜๋Š” ์ถœ๋ ฅ๋ทฐ์˜ ๋ฉ”์†Œ๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋„๋ก ์ž‘์„ฑ๋˜์–ด ์žˆ๋Š”๋ฐ, ์ด ๋ณด๋‹ค๋Š” ๋ทฐ์—์„œ ์ •๋ณด๋ฅผ ํŒ๋‹จํ•˜์—ฌ ๋Œ€์‘ํ•˜๋Š” ๋ฉ”์†Œ๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋„๋ก ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์ด ๋” ์ข‹์„ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.
private void showDiscountDetails(final Map<DiscountPolicy, DiscountAmount> discountDetails) {
    outputView.printBenefitHeader();
    if (discountDetails.isEmpty()) {
        outputView.printNone();
        outputView.printLine();
        return;
    }
    discountDetails.forEach(
            (policy, amount) -> outputView.printBenefit(policy.getPolicy(), amount.getAmount()));
    outputView.printLine();
}

โžก๏ธ ์ค‘๋ณต ๋กœ์ง ์ œ๊ฑฐ 

public Integer getDessertQuantity() {
    return foodAndQuantity.entrySet()
            .stream()
            .filter(order -> DESSERT.getSalesMenu().containsKey(order.getKey().name()))
            .mapToInt(order -> order.getValue().amount())
            .sum();
}

public Integer getMainQuantity() {
    return foodAndQuantity.entrySet()
            .stream()
            .filter(order -> MAIN.getSalesMenu().containsKey(order.getKey().name()))
            .mapToInt(order -> order.getValue().amount())
            .sum();
}
  • Orderํด๋ž˜์Šค์—์„œ ๋ฉ”์ธ ๋ฉ”๋‰ด ์ฃผ๋ฌธ๋Ÿ‰๊ณผ, ๋””์ €ํŠธ ๋ฉ”๋‰ด ์ฃผ๋ฌธ๋Ÿ‰์„ ๋ฆฌํ„ดํ•˜๋Š” ๊ธฐ๋Šฅ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋Š”๋ฐ, ์ฝ”๋“œ์— ์ค‘๋ณต๋˜๋Š” ๋ถ€๋ถ„๋“ค์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด ๋‘ ๋ฉ”์†Œ๋“œ๋ฅผ ์•„๋ž˜์™€ ๊ฐ™์ด ํ•˜๋‚˜์˜ ๋ฉ”์†Œ๋“œ๋กœ ๋ณ€๊ฒฝํ•œ๋‹ค๋ฉด ๋” ์ข‹์€ ์ฝ”๋“œ๊ฐ€ ๋  ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.
public Integer getFoodQuantity(Menu menu) {
    return foodAndQuantity.entrySet()
            .stream()
            .filter(order -> menu.getSalesMenu().containsKey(order.getKey().name()))
            .mapToInt(order -> order.getValue().amount())
            .sum();
}

โžก๏ธ ๋„ค์ด๋ฐ ๋ณ€๊ฒฝ

public Integer getAmount() {
    return foodAndQuantity.keySet().stream()
            .mapToInt(food -> Menu.getPriceOfFood(food) * foodAndQuantity.get(food).amount())
            .sum();
}
  • Order ํด๋ž˜์Šค์—์„œ ์ด ์ฃผ๋ฌธ ๊ธˆ์•ก์„ ๋ฆฌํ„ดํ•˜๋Š” ๊ธฐ๋Šฅ์ธ๋ฐ, getAmount๋ผ๋Š” ๋„ค์ด๋ฐ์€ ์ด ์ฃผ๋ฌธ ๊ธˆ์•ก์„ ์„ค๋ช…ํ•˜๊ธฐ์— ๋ถ€์กฑํ•˜๋‹ค๊ณ  ๋Š๊ปด์ง€๋Š”๋ฐ, getAmount๋ณด๋‹ค๋Š” getTotalAmount๋‚˜ getTotalOrderAmount์™€ ๊ฐ™์€ ๋ฉ”์†Œ๋“œ๋ช…์ด ๋” ์ด ๊ธฐ๋Šฅ์„ ์ž˜ ๋‚˜ํƒ€๋‚ด๋Š” ์ด๋ฆ„์ด๋ผ๊ณ  ์ƒ๊ฐ๋ฉ๋‹ˆ๋‹ค. 

๐Ÿšฉํ”„๋ฆฌ์ฝ”์Šค ์ดํ‰ / ์•ž์œผ๋กœ์˜ ๊ณ„ํš

 

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

 

๋ฏธ์…˜์— ๊ด€ํ•œ ์ œ ์ฝ”๋“œ๋Š” ์•„๋ž˜ ๋งํฌ์—์„œ ํ™•์ธํ•˜์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค..

 

GitHub - Dongwoongkim/java-christmas-6-Dongwoongkim: ์šฐ์•„ํ•œํ…Œํฌ์ฝ”์Šค - ํ”„๋ฆฌ์ฝ”์Šค 4์ฃผ์ฐจ ๋ฏธ์…˜

์šฐ์•„ํ•œํ…Œํฌ์ฝ”์Šค - ํ”„๋ฆฌ์ฝ”์Šค 4์ฃผ์ฐจ ๋ฏธ์…˜. Contribute to Dongwoongkim/java-christmas-6-Dongwoongkim development by creating an account on GitHub.

github.com

 

๋ธ”๋กœ๊ทธ์˜ ์ •๋ณด

Study Repository

rlaehddnd0422

ํ™œ๋™ํ•˜๊ธฐ