From a38bf76ed417e4ceda0c1a8970ced39dfcf03686 Mon Sep 17 00:00:00 2001 From: junsoo Date: Mon, 20 Nov 2023 17:10:12 +0900 Subject: [PATCH 01/20] =?UTF-8?q?feat:=20OutputView=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/README.md | 4 ++++ .../java/controller/VendingMachineController.java | 12 ++++++++++++ src/main/java/vendingmachine/Application.java | 5 ++++- src/main/java/view/OutputView.java | 8 ++++++++ 4 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 src/main/README.md create mode 100644 src/main/java/controller/VendingMachineController.java create mode 100644 src/main/java/view/OutputView.java diff --git a/src/main/README.md b/src/main/README.md new file mode 100644 index 000000000..778f62a32 --- /dev/null +++ b/src/main/README.md @@ -0,0 +1,4 @@ +### 기능 요구 사항 + + - [] 자판기가 보유하고 있는 금액으로 동전을 무작위로 생성한다. + diff --git a/src/main/java/controller/VendingMachineController.java b/src/main/java/controller/VendingMachineController.java new file mode 100644 index 000000000..6e8c19dc2 --- /dev/null +++ b/src/main/java/controller/VendingMachineController.java @@ -0,0 +1,12 @@ +package controller; + +import view.OutputView; + +public class VendingMachineController { + + public void run() { + OutputView.printVendingMachineMoney(); + } + + +} diff --git a/src/main/java/vendingmachine/Application.java b/src/main/java/vendingmachine/Application.java index 9d3be447b..8fbb942c7 100644 --- a/src/main/java/vendingmachine/Application.java +++ b/src/main/java/vendingmachine/Application.java @@ -1,7 +1,10 @@ package vendingmachine; +import controller.VendingMachineController; + public class Application { public static void main(String[] args) { - // TODO: 프로그램 구현 + VendingMachineController vendingMachineController = new VendingMachineController(); + vendingMachineController.run(); } } diff --git a/src/main/java/view/OutputView.java b/src/main/java/view/OutputView.java new file mode 100644 index 000000000..b65f7a3f8 --- /dev/null +++ b/src/main/java/view/OutputView.java @@ -0,0 +1,8 @@ +package view; + +public class OutputView { + + public static void printVendingMachineMoney() { + System.out.println("자판기가 보유하고 있는 금액을 입력해 주세요."); + } +} From f88e80c57c92ec6f046ec18b63e2f53209633ae5 Mon Sep 17 00:00:00 2001 From: junsoo Date: Mon, 20 Nov 2023 17:11:32 +0900 Subject: [PATCH 02/20] =?UTF-8?q?feat:=20InputView=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/controller/VendingMachineController.java | 2 ++ src/main/java/view/InputView.java | 11 +++++++++++ 2 files changed, 13 insertions(+) create mode 100644 src/main/java/view/InputView.java diff --git a/src/main/java/controller/VendingMachineController.java b/src/main/java/controller/VendingMachineController.java index 6e8c19dc2..b37c927a3 100644 --- a/src/main/java/controller/VendingMachineController.java +++ b/src/main/java/controller/VendingMachineController.java @@ -1,11 +1,13 @@ package controller; +import view.InputView; import view.OutputView; public class VendingMachineController { public void run() { OutputView.printVendingMachineMoney(); + InputView.readVendingMachineMoney(); } diff --git a/src/main/java/view/InputView.java b/src/main/java/view/InputView.java new file mode 100644 index 000000000..614420f2e --- /dev/null +++ b/src/main/java/view/InputView.java @@ -0,0 +1,11 @@ +package view; + +import camp.nextstep.edu.missionutils.Console; + +public class InputView { + + public static String readVendingMachineMoney() { + String amount = Console.readLine(); + return amount; + } +} From 76e49e1c43dfc63ac20a0c02e66b3d435bd17ffb Mon Sep 17 00:00:00 2001 From: junsoo Date: Mon, 20 Nov 2023 17:13:03 +0900 Subject: [PATCH 03/20] =?UTF-8?q?feat:=20Parser=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=EB=A5=BC=20=ED=86=B5=ED=95=B4=20String=20->=20int=20?= =?UTF-8?q?=ED=98=95=EB=B3=80=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/utils/Parser.java | 9 +++++++++ src/main/java/view/InputView.java | 5 +++-- 2 files changed, 12 insertions(+), 2 deletions(-) create mode 100644 src/main/java/utils/Parser.java diff --git a/src/main/java/utils/Parser.java b/src/main/java/utils/Parser.java new file mode 100644 index 000000000..7d7b294bc --- /dev/null +++ b/src/main/java/utils/Parser.java @@ -0,0 +1,9 @@ +package utils; + +public class Parser { + + public static int convertToInt(String amount){ + int parsedString = Integer.parseInt(amount); + return parsedString; + } +} diff --git a/src/main/java/view/InputView.java b/src/main/java/view/InputView.java index 614420f2e..8c31d75d7 100644 --- a/src/main/java/view/InputView.java +++ b/src/main/java/view/InputView.java @@ -1,11 +1,12 @@ package view; import camp.nextstep.edu.missionutils.Console; +import utils.Parser; public class InputView { - public static String readVendingMachineMoney() { + public static int readVendingMachineMoney() { String amount = Console.readLine(); - return amount; + return Parser.convertToInt(amount); } } From 34a4a8294ecc6197a1aed3f920d71281e6699d57 Mon Sep 17 00:00:00 2001 From: junsoo Date: Mon, 20 Nov 2023 17:17:05 +0900 Subject: [PATCH 04/20] =?UTF-8?q?refactor:=20Parsing=20=EC=B2=98=EB=A6=AC?= =?UTF-8?q?=EB=8A=94=20=EC=BB=A8=ED=8A=B8=EB=A1=A4=EB=9F=AC=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=EB=8B=B4=EB=8B=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/controller/VendingMachineController.java | 10 +++++++--- src/main/java/view/InputView.java | 6 ++---- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/main/java/controller/VendingMachineController.java b/src/main/java/controller/VendingMachineController.java index b37c927a3..a07032f3a 100644 --- a/src/main/java/controller/VendingMachineController.java +++ b/src/main/java/controller/VendingMachineController.java @@ -1,14 +1,18 @@ package controller; +import utils.Parser; import view.InputView; import view.OutputView; public class VendingMachineController { public void run() { - OutputView.printVendingMachineMoney(); - InputView.readVendingMachineMoney(); + vendingMachineMoney(); } - + private int vendingMachineMoney() { + OutputView.printVendingMachineMoney(); + String amount = InputView.readVendingMachineMoney(); + return Parser.convertToInt(amount); + } } diff --git a/src/main/java/view/InputView.java b/src/main/java/view/InputView.java index 8c31d75d7..e4b83ac5e 100644 --- a/src/main/java/view/InputView.java +++ b/src/main/java/view/InputView.java @@ -1,12 +1,10 @@ package view; import camp.nextstep.edu.missionutils.Console; -import utils.Parser; - public class InputView { - public static int readVendingMachineMoney() { + public static String readVendingMachineMoney() { String amount = Console.readLine(); - return Parser.convertToInt(amount); + return amount; } } From 1969e811349e1155499341ea7e588c58a16c1307 Mon Sep 17 00:00:00 2001 From: junsoo Date: Mon, 20 Nov 2023 17:25:35 +0900 Subject: [PATCH 05/20] =?UTF-8?q?feat:=20=EC=97=90=EB=9F=AC=20=EB=A9=94?= =?UTF-8?q?=EC=84=B8=EC=A7=80=EB=93=A4=EC=9D=84=20=EB=AA=A8=EC=95=84?= =?UTF-8?q?=EB=86=93=EB=8A=94=20ErrorMessages=20enum=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/utils/ErrorMessages.java | 17 +++++++++++++++++ src/main/java/utils/Parser.java | 1 - src/main/java/vendingmachine/Amount.java | 20 ++++++++++++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 src/main/java/utils/ErrorMessages.java create mode 100644 src/main/java/vendingmachine/Amount.java diff --git a/src/main/java/utils/ErrorMessages.java b/src/main/java/utils/ErrorMessages.java new file mode 100644 index 000000000..3ca3ea1ae --- /dev/null +++ b/src/main/java/utils/ErrorMessages.java @@ -0,0 +1,17 @@ +package utils; + +public enum ErrorMessages { + + VALIDATE_BLANK("[ERROR] 금액은 공백일 수 없습니다. 다시 입력해 주세요."), + ; + + private final String message; + + ErrorMessages(String message) { + this.message = message; + } + + public String getErrorMessage() { + return message; + } +} diff --git a/src/main/java/utils/Parser.java b/src/main/java/utils/Parser.java index 7d7b294bc..fc1c65814 100644 --- a/src/main/java/utils/Parser.java +++ b/src/main/java/utils/Parser.java @@ -1,7 +1,6 @@ package utils; public class Parser { - public static int convertToInt(String amount){ int parsedString = Integer.parseInt(amount); return parsedString; diff --git a/src/main/java/vendingmachine/Amount.java b/src/main/java/vendingmachine/Amount.java new file mode 100644 index 000000000..c9a3b6db1 --- /dev/null +++ b/src/main/java/vendingmachine/Amount.java @@ -0,0 +1,20 @@ +package vendingmachine; + +import utils.ErrorMessages; +import utils.Parser; + +public class Amount { + + private final int money; + + public Amount(String moneyString) { + validateBlank(moneyString); + this.money = Parser.convertToInt(moneyString); + } + + private void validateBlank(String input) { + if (input.isEmpty()){ + throw new IllegalArgumentException(ErrorMessages.VALIDATE_BLANK.getErrorMessage()); + } + } +} From 1d79eb9c307e31bb7086f7d6afcee4b1b526b8d3 Mon Sep 17 00:00:00 2001 From: junsoo Date: Mon, 20 Nov 2023 17:36:33 +0900 Subject: [PATCH 06/20] =?UTF-8?q?feat:=20=EC=9E=90=ED=8C=90=EA=B8=B0?= =?UTF-8?q?=EA=B0=80=20=EB=B3=B4=EC=9C=A0=ED=95=98=EA=B3=A0=20=EC=9E=88?= =?UTF-8?q?=EB=8A=94=20=EA=B8=88=EC=95=A1=20=EC=9C=A0=ED=9A=A8=EC=84=B1=20?= =?UTF-8?q?=EA=B2=80=EC=82=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/README.md | 7 +++- .../controller/VendingMachineController.java | 5 +-- src/main/java/utils/ErrorMessages.java | 5 ++- src/main/java/vendingmachine/Amount.java | 32 +++++++++++++++++++ 4 files changed, 45 insertions(+), 4 deletions(-) diff --git a/src/main/README.md b/src/main/README.md index 778f62a32..b1114aabb 100644 --- a/src/main/README.md +++ b/src/main/README.md @@ -1,4 +1,9 @@ ### 기능 요구 사항 - - [] 자판기가 보유하고 있는 금액으로 동전을 무작위로 생성한다. + - [X] 자판기가 보유하고 있는 금액으로 동전을 무작위로 생성한다. + - [X] 공백일 수 없다 + - [X] 100원 미만일 경우, 예외 처리 + - [X] 10원으로 나누어 떨어지지 않을 경우, 예외 처리 + - [X] 문자열이 들어올 수 없다. + diff --git a/src/main/java/controller/VendingMachineController.java b/src/main/java/controller/VendingMachineController.java index a07032f3a..c7e85c3cd 100644 --- a/src/main/java/controller/VendingMachineController.java +++ b/src/main/java/controller/VendingMachineController.java @@ -1,6 +1,7 @@ package controller; import utils.Parser; +import vendingmachine.Amount; import view.InputView; import view.OutputView; @@ -10,9 +11,9 @@ public void run() { vendingMachineMoney(); } - private int vendingMachineMoney() { + private Amount vendingMachineMoney() { OutputView.printVendingMachineMoney(); String amount = InputView.readVendingMachineMoney(); - return Parser.convertToInt(amount); + return new Amount(amount); } } diff --git a/src/main/java/utils/ErrorMessages.java b/src/main/java/utils/ErrorMessages.java index 3ca3ea1ae..cbf64da45 100644 --- a/src/main/java/utils/ErrorMessages.java +++ b/src/main/java/utils/ErrorMessages.java @@ -2,7 +2,10 @@ public enum ErrorMessages { - VALIDATE_BLANK("[ERROR] 금액은 공백일 수 없습니다. 다시 입력해 주세요."), + VALIDATE_BLANK("[ERROR] 금액은 공백일 수 없습니다."), + VALIDATE_MINIMUM_RANGE("[ERROR] 금액은 100원 보다 적을 수 없습니다."), + VALIDATE_DIVIDE_BY_TEN("[ERROR] 금액은 10원 단위여야 합니다."), + VALIDATE_NUMERIC("[ERROR] 금액에 숫자 이외의 값이 들어올 수 없습니다."), ; private final String message; diff --git a/src/main/java/vendingmachine/Amount.java b/src/main/java/vendingmachine/Amount.java index c9a3b6db1..ae95b6830 100644 --- a/src/main/java/vendingmachine/Amount.java +++ b/src/main/java/vendingmachine/Amount.java @@ -3,13 +3,24 @@ import utils.ErrorMessages; import utils.Parser; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + public class Amount { + private static final int MINIMUM_MONEY = 100; + private static final int DIVISIBLE_AMOUNT = 10; + private static final int ZERO = 0; + private static final String NUMBER_REG_EXP = "^[0-9]+$"; + private static final Pattern NUMBER = Pattern.compile(NUMBER_REG_EXP); private final int money; public Amount(String moneyString) { validateBlank(moneyString); + validateIsNumeric(moneyString); this.money = Parser.convertToInt(moneyString); + validateMinimumAmount(money); + validateDivideByTen(money); } private void validateBlank(String input) { @@ -17,4 +28,25 @@ private void validateBlank(String input) { throw new IllegalArgumentException(ErrorMessages.VALIDATE_BLANK.getErrorMessage()); } } + + private void validateIsNumeric(String input) { + Matcher matcher = NUMBER.matcher(input); + if (!matcher.find()) { + throw new IllegalArgumentException(ErrorMessages.VALIDATE_NUMERIC.getErrorMessage()); + } + } + + private void validateMinimumAmount(int amount) { + if (amount < MINIMUM_MONEY) { + throw new IllegalArgumentException(ErrorMessages.VALIDATE_MINIMUM_RANGE.getErrorMessage()); + } + } + + private void validateDivideByTen(int amount) { + if (amount % DIVISIBLE_AMOUNT != ZERO){ + throw new IllegalArgumentException(ErrorMessages.VALIDATE_DIVIDE_BY_TEN.getErrorMessage()); + } + } + + } From ef1c9cc310785ac0cc311c857ab73f41bfc97a52 Mon Sep 17 00:00:00 2001 From: junsoo Date: Mon, 20 Nov 2023 17:44:20 +0900 Subject: [PATCH 07/20] =?UTF-8?q?feat:=20=EA=B3=B5=EB=B0=B1=EC=97=AC?= =?UTF-8?q?=EB=B6=80=EC=99=80=20=EC=88=AB=EC=9E=90=20=EC=97=AC=EB=B6=80?= =?UTF-8?q?=EB=A5=BC=20=EC=B2=B4=ED=81=AC=ED=95=98=EB=8A=94=20InputValidat?= =?UTF-8?q?or=20=ED=81=B4=EB=9E=98=EC=8A=A4=20=EC=83=9D=EC=84=B1=ED=95=B4?= =?UTF-8?q?=EC=84=9C=20=EC=97=AD=ED=95=A0=EC=9D=84=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/VendingMachineController.java | 3 ++- src/main/java/utils/InputValidator.java | 23 +++++++++++++++++++ src/main/java/vendingmachine/Amount.java | 21 ++++------------- src/main/java/vendingmachine/Coin.java | 2 +- src/main/java/view/InputView.java | 4 ++++ 5 files changed, 34 insertions(+), 19 deletions(-) create mode 100644 src/main/java/utils/InputValidator.java diff --git a/src/main/java/controller/VendingMachineController.java b/src/main/java/controller/VendingMachineController.java index c7e85c3cd..ca40ee5d3 100644 --- a/src/main/java/controller/VendingMachineController.java +++ b/src/main/java/controller/VendingMachineController.java @@ -14,6 +14,7 @@ public void run() { private Amount vendingMachineMoney() { OutputView.printVendingMachineMoney(); String amount = InputView.readVendingMachineMoney(); - return new Amount(amount); + int money = Parser.convertToInt(amount); + return new Amount(money); } } diff --git a/src/main/java/utils/InputValidator.java b/src/main/java/utils/InputValidator.java new file mode 100644 index 000000000..83a5bebe3 --- /dev/null +++ b/src/main/java/utils/InputValidator.java @@ -0,0 +1,23 @@ +package utils; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class InputValidator { + + private static final String NUMBER_REG_EXP = "^[0-9]+$"; + private static final Pattern NUMBER = Pattern.compile(NUMBER_REG_EXP); + + public static void validateBlank(String input) { + if (input.isEmpty()){ + throw new IllegalArgumentException(ErrorMessages.VALIDATE_BLANK.getErrorMessage()); + } + } + + public static void validateIsNumeric(String input) { + Matcher matcher = NUMBER.matcher(input); + if (!matcher.find()) { + throw new IllegalArgumentException(ErrorMessages.VALIDATE_NUMERIC.getErrorMessage()); + } + } +} diff --git a/src/main/java/vendingmachine/Amount.java b/src/main/java/vendingmachine/Amount.java index ae95b6830..66e85eb2d 100644 --- a/src/main/java/vendingmachine/Amount.java +++ b/src/main/java/vendingmachine/Amount.java @@ -11,29 +11,16 @@ public class Amount { private static final int MINIMUM_MONEY = 100; private static final int DIVISIBLE_AMOUNT = 10; private static final int ZERO = 0; - private static final String NUMBER_REG_EXP = "^[0-9]+$"; - private static final Pattern NUMBER = Pattern.compile(NUMBER_REG_EXP); private final int money; - public Amount(String moneyString) { - validateBlank(moneyString); - validateIsNumeric(moneyString); - this.money = Parser.convertToInt(moneyString); + public Amount(int money) { validateMinimumAmount(money); validateDivideByTen(money); + this.money = money; } - private void validateBlank(String input) { - if (input.isEmpty()){ - throw new IllegalArgumentException(ErrorMessages.VALIDATE_BLANK.getErrorMessage()); - } - } - - private void validateIsNumeric(String input) { - Matcher matcher = NUMBER.matcher(input); - if (!matcher.find()) { - throw new IllegalArgumentException(ErrorMessages.VALIDATE_NUMERIC.getErrorMessage()); - } + public int getMoney() { + return money; } private void validateMinimumAmount(int amount) { diff --git a/src/main/java/vendingmachine/Coin.java b/src/main/java/vendingmachine/Coin.java index c76293fbc..c2bb61f79 100644 --- a/src/main/java/vendingmachine/Coin.java +++ b/src/main/java/vendingmachine/Coin.java @@ -12,5 +12,5 @@ public enum Coin { this.amount = amount; } - // 추가 기능 구현 + } diff --git a/src/main/java/view/InputView.java b/src/main/java/view/InputView.java index e4b83ac5e..5a3f2c61a 100644 --- a/src/main/java/view/InputView.java +++ b/src/main/java/view/InputView.java @@ -1,10 +1,14 @@ package view; import camp.nextstep.edu.missionutils.Console; +import utils.InputValidator; + public class InputView { public static String readVendingMachineMoney() { String amount = Console.readLine(); + InputValidator.validateBlank(amount); + InputValidator.validateIsNumeric(amount); return amount; } } From 12f33a199ca3d812a87481351aebed489442dc9b Mon Sep 17 00:00:00 2001 From: junsoo Date: Mon, 20 Nov 2023 17:47:02 +0900 Subject: [PATCH 08/20] =?UTF-8?q?feat:=20=EC=9E=85=EB=A0=A5=EA=B0=92?= =?UTF-8?q?=EC=9D=84=20=EB=8B=A4=EC=8B=9C=20=EB=B0=9B=EC=95=84=EC=A3=BC?= =?UTF-8?q?=EB=8A=94=20RepeatInput=20=ED=81=B4=EB=9E=98=EC=8A=A4=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/controller/VendingMachineController.java | 3 ++- src/main/java/utils/RepeatInput.java | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 src/main/java/utils/RepeatInput.java diff --git a/src/main/java/controller/VendingMachineController.java b/src/main/java/controller/VendingMachineController.java index ca40ee5d3..af394a0f7 100644 --- a/src/main/java/controller/VendingMachineController.java +++ b/src/main/java/controller/VendingMachineController.java @@ -1,6 +1,7 @@ package controller; import utils.Parser; +import utils.RepeatInput; import vendingmachine.Amount; import view.InputView; import view.OutputView; @@ -8,7 +9,7 @@ public class VendingMachineController { public void run() { - vendingMachineMoney(); + Amount amount = RepeatInput.repeatWhenInvalid(this::vendingMachineMoney); } private Amount vendingMachineMoney() { diff --git a/src/main/java/utils/RepeatInput.java b/src/main/java/utils/RepeatInput.java new file mode 100644 index 000000000..701812104 --- /dev/null +++ b/src/main/java/utils/RepeatInput.java @@ -0,0 +1,15 @@ +package utils; + +import java.util.function.Supplier; + +public class RepeatInput { + + public static T repeatWhenInvalid(Supplier input) { + try { + return input.get(); + } catch (IllegalArgumentException e) { + System.out.println(e.getMessage()); + return repeatWhenInvalid(input); + } + } +} From 9d559518fc272aeb0e89c6376f342143c294c040 Mon Sep 17 00:00:00 2001 From: junsoo Date: Mon, 20 Nov 2023 18:01:58 +0900 Subject: [PATCH 09/20] =?UTF-8?q?feat:=20coin=EC=9D=98=20=EC=B5=9C?= =?UTF-8?q?=EC=86=9F=EA=B0=92=EC=9D=84=20map=EC=97=90=20=EB=8B=B4=EC=95=84?= =?UTF-8?q?=20return=20=ED=95=98=EB=8A=94=20CoinCounter=20=ED=81=B4?= =?UTF-8?q?=EB=9E=98=EC=8A=A4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/vendingmachine/Coin.java | 4 +++- src/main/java/vendingmachine/CoinCounter.java | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 src/main/java/vendingmachine/CoinCounter.java diff --git a/src/main/java/vendingmachine/Coin.java b/src/main/java/vendingmachine/Coin.java index c2bb61f79..6e6237203 100644 --- a/src/main/java/vendingmachine/Coin.java +++ b/src/main/java/vendingmachine/Coin.java @@ -12,5 +12,7 @@ public enum Coin { this.amount = amount; } - + public int getAmount() { + return amount; + } } diff --git a/src/main/java/vendingmachine/CoinCounter.java b/src/main/java/vendingmachine/CoinCounter.java new file mode 100644 index 000000000..ccb0c9e28 --- /dev/null +++ b/src/main/java/vendingmachine/CoinCounter.java @@ -0,0 +1,19 @@ +package vendingmachine; + +import java.util.EnumMap; +import java.util.Map; + +public class CoinCounter { + + private final Map coinCounterMap = new EnumMap<>(Coin.class); + + public Map getCounter(Amount amount) { + int targetAmount = amount.getMoney(); + for (Coin coin : Coin.values()){ + int coinNumbers = targetAmount / coin.getAmount(); + coinCounterMap.put(coin, coinNumbers); + targetAmount %= coin.getAmount(); + } + return coinCounterMap; + } +} From 72e17e5e068bdda242d6148c502b5f9491a72b2c Mon Sep 17 00:00:00 2001 From: junsoo Date: Mon, 20 Nov 2023 18:18:31 +0900 Subject: [PATCH 10/20] =?UTF-8?q?feat:=20=EB=8F=99=EC=A0=84=EA=B3=BC=20?= =?UTF-8?q?=EC=B5=9C=EC=86=8C=20=EB=8F=99=EC=A0=84=EC=9D=98=20=EA=B0=9C?= =?UTF-8?q?=EC=88=98=EB=A5=BC=20=EC=B6=9C=EB=A0=A5=ED=95=B4=EC=A3=BC?= =?UTF-8?q?=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/README.md | 3 +++ .../controller/VendingMachineController.java | 2 ++ src/main/java/vendingmachine/Coin.java | 4 ++++ src/main/java/vendingmachine/CoinCounter.java | 2 -- src/main/java/view/OutputView.java | 18 ++++++++++++++++++ 5 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/main/README.md b/src/main/README.md index b1114aabb..7db52db98 100644 --- a/src/main/README.md +++ b/src/main/README.md @@ -5,5 +5,8 @@ - [X] 100원 미만일 경우, 예외 처리 - [X] 10원으로 나누어 떨어지지 않을 경우, 예외 처리 - [X] 문자열이 들어올 수 없다. + + - [X] 해당 금액에 맞는 잔돈을 돌려준다. + - [X] 잔돈은 동전의 최소 개수로 돌려주어야 한다. diff --git a/src/main/java/controller/VendingMachineController.java b/src/main/java/controller/VendingMachineController.java index af394a0f7..efbef3195 100644 --- a/src/main/java/controller/VendingMachineController.java +++ b/src/main/java/controller/VendingMachineController.java @@ -3,6 +3,7 @@ import utils.Parser; import utils.RepeatInput; import vendingmachine.Amount; +import vendingmachine.CoinCounter; import view.InputView; import view.OutputView; @@ -10,6 +11,7 @@ public class VendingMachineController { public void run() { Amount amount = RepeatInput.repeatWhenInvalid(this::vendingMachineMoney); + OutputView.printVendingMachineCoinAmount(new CoinCounter(), amount); } private Amount vendingMachineMoney() { diff --git a/src/main/java/vendingmachine/Coin.java b/src/main/java/vendingmachine/Coin.java index 6e6237203..20ee4d913 100644 --- a/src/main/java/vendingmachine/Coin.java +++ b/src/main/java/vendingmachine/Coin.java @@ -15,4 +15,8 @@ public enum Coin { public int getAmount() { return amount; } + + public String displayCoinName() { + return amount + "원"; + } } diff --git a/src/main/java/vendingmachine/CoinCounter.java b/src/main/java/vendingmachine/CoinCounter.java index ccb0c9e28..5cff576d9 100644 --- a/src/main/java/vendingmachine/CoinCounter.java +++ b/src/main/java/vendingmachine/CoinCounter.java @@ -2,11 +2,9 @@ import java.util.EnumMap; import java.util.Map; - public class CoinCounter { private final Map coinCounterMap = new EnumMap<>(Coin.class); - public Map getCounter(Amount amount) { int targetAmount = amount.getMoney(); for (Coin coin : Coin.values()){ diff --git a/src/main/java/view/OutputView.java b/src/main/java/view/OutputView.java index b65f7a3f8..42c167909 100644 --- a/src/main/java/view/OutputView.java +++ b/src/main/java/view/OutputView.java @@ -1,8 +1,26 @@ package view; +import vendingmachine.Amount; +import vendingmachine.Coin; +import vendingmachine.CoinCounter; + +import java.util.Map; + public class OutputView { public static void printVendingMachineMoney() { System.out.println("자판기가 보유하고 있는 금액을 입력해 주세요."); } + + public static void printVendingMachineCoinAmount(CoinCounter coinCounter, Amount amount) { + System.out.println(); + System.out.println("자판기가 보유한 동전"); + Map counterMap = coinCounter.getCounter(amount); + + for(Map.Entry entry : counterMap.entrySet()) { + Coin coin = entry.getKey(); + int count = entry.getValue(); + System.out.println(coin.displayCoinName() + " : " + count + "개"); + } + } } From 02e5950f53b390c8ec01080ede0d58eba2228c74 Mon Sep 17 00:00:00 2001 From: junsoo Date: Mon, 20 Nov 2023 18:21:56 +0900 Subject: [PATCH 11/20] =?UTF-8?q?feat:=20=EC=83=81=ED=92=88=EB=AA=85,=20?= =?UTF-8?q?=EA=B0=80=EA=B2=A9,=20=EC=88=98=EB=9F=89=20=EC=9E=85/=EC=B6=9C?= =?UTF-8?q?=EB=A0=A5=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/README.md | 3 +++ src/main/java/controller/VendingMachineController.java | 3 +++ src/main/java/view/InputView.java | 5 +++++ src/main/java/view/OutputView.java | 5 +++++ 4 files changed, 16 insertions(+) diff --git a/src/main/README.md b/src/main/README.md index 7db52db98..332bfa67e 100644 --- a/src/main/README.md +++ b/src/main/README.md @@ -8,5 +8,8 @@ - [X] 해당 금액에 맞는 잔돈을 돌려준다. - [X] 잔돈은 동전의 최소 개수로 돌려주어야 한다. + + - [] 상품명, 가격, 수량을 입력받는다. + - [] 상품명, 가격, 수량은 쉼표로, 개별 상품은 대괄호([])로 묶어 세미콜론(;)으로 구분한다. diff --git a/src/main/java/controller/VendingMachineController.java b/src/main/java/controller/VendingMachineController.java index efbef3195..c9c51f6fc 100644 --- a/src/main/java/controller/VendingMachineController.java +++ b/src/main/java/controller/VendingMachineController.java @@ -12,6 +12,9 @@ public class VendingMachineController { public void run() { Amount amount = RepeatInput.repeatWhenInvalid(this::vendingMachineMoney); OutputView.printVendingMachineCoinAmount(new CoinCounter(), amount); + + OutputView.printOrderDetails(); + InputView.readOrderDetails(); } private Amount vendingMachineMoney() { diff --git a/src/main/java/view/InputView.java b/src/main/java/view/InputView.java index 5a3f2c61a..b7ed51f8d 100644 --- a/src/main/java/view/InputView.java +++ b/src/main/java/view/InputView.java @@ -11,4 +11,9 @@ public static String readVendingMachineMoney() { InputValidator.validateIsNumeric(amount); return amount; } + + public static String readOrderDetails() { + String order = Console.readLine(); + return order; + } } diff --git a/src/main/java/view/OutputView.java b/src/main/java/view/OutputView.java index 42c167909..1ca31f0c0 100644 --- a/src/main/java/view/OutputView.java +++ b/src/main/java/view/OutputView.java @@ -23,4 +23,9 @@ public static void printVendingMachineCoinAmount(CoinCounter coinCounter, Amount System.out.println(coin.displayCoinName() + " : " + count + "개"); } } + + public static void printOrderDetails() { + System.out.println(); + System.out.println("상품명과 가격, 수량을 입력해 주세요."); + } } From 445a465062e5c37b9028b0a41ca9d68a18511044 Mon Sep 17 00:00:00 2001 From: junsoo Date: Mon, 20 Nov 2023 18:50:17 +0900 Subject: [PATCH 12/20] =?UTF-8?q?feat:=20=EC=A3=BC=EB=AC=B8=20=EC=9E=85?= =?UTF-8?q?=EB=A0=A5=EA=B0=92=20=EC=9C=A0=ED=9A=A8=EC=84=B1=20=EA=B2=80?= =?UTF-8?q?=EC=82=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/README.md | 2 ++ .../java/controller/VendingMachineController.java | 8 ++++---- src/main/java/utils/ErrorMessages.java | 1 + src/main/java/utils/InputValidator.java | 13 +++++++++++-- src/main/java/utils/Parser.java | 6 ++++++ src/main/java/vendingmachine/CoinCounter.java | 2 +- .../{Amount.java => MachineAmount.java} | 8 ++------ src/main/java/view/InputView.java | 2 ++ src/main/java/view/OutputView.java | 4 ++-- 9 files changed, 31 insertions(+), 15 deletions(-) rename src/main/java/vendingmachine/{Amount.java => MachineAmount.java} (85%) diff --git a/src/main/README.md b/src/main/README.md index 332bfa67e..ee1f948d8 100644 --- a/src/main/README.md +++ b/src/main/README.md @@ -11,5 +11,7 @@ - [] 상품명, 가격, 수량을 입력받는다. - [] 상품명, 가격, 수량은 쉼표로, 개별 상품은 대괄호([])로 묶어 세미콜론(;)으로 구분한다. + - [] 정규식으로 매칭되나 체크 + - [] diff --git a/src/main/java/controller/VendingMachineController.java b/src/main/java/controller/VendingMachineController.java index c9c51f6fc..5a34e4d15 100644 --- a/src/main/java/controller/VendingMachineController.java +++ b/src/main/java/controller/VendingMachineController.java @@ -2,7 +2,7 @@ import utils.Parser; import utils.RepeatInput; -import vendingmachine.Amount; +import vendingmachine.MachineAmount; import vendingmachine.CoinCounter; import view.InputView; import view.OutputView; @@ -10,17 +10,17 @@ public class VendingMachineController { public void run() { - Amount amount = RepeatInput.repeatWhenInvalid(this::vendingMachineMoney); + MachineAmount amount = RepeatInput.repeatWhenInvalid(this::vendingMachineMoney); OutputView.printVendingMachineCoinAmount(new CoinCounter(), amount); OutputView.printOrderDetails(); InputView.readOrderDetails(); } - private Amount vendingMachineMoney() { + private MachineAmount vendingMachineMoney() { OutputView.printVendingMachineMoney(); String amount = InputView.readVendingMachineMoney(); int money = Parser.convertToInt(amount); - return new Amount(money); + return new MachineAmount(money); } } diff --git a/src/main/java/utils/ErrorMessages.java b/src/main/java/utils/ErrorMessages.java index cbf64da45..aab0de32c 100644 --- a/src/main/java/utils/ErrorMessages.java +++ b/src/main/java/utils/ErrorMessages.java @@ -6,6 +6,7 @@ public enum ErrorMessages { VALIDATE_MINIMUM_RANGE("[ERROR] 금액은 100원 보다 적을 수 없습니다."), VALIDATE_DIVIDE_BY_TEN("[ERROR] 금액은 10원 단위여야 합니다."), VALIDATE_NUMERIC("[ERROR] 금액에 숫자 이외의 값이 들어올 수 없습니다."), + VALIDATE_ORDER_FORMAT("[ERROR] 올바르지 않은 입력 형식 입니다."), ; private final String message; diff --git a/src/main/java/utils/InputValidator.java b/src/main/java/utils/InputValidator.java index 83a5bebe3..b66a3f57a 100644 --- a/src/main/java/utils/InputValidator.java +++ b/src/main/java/utils/InputValidator.java @@ -5,8 +5,10 @@ public class InputValidator { - private static final String NUMBER_REG_EXP = "^[0-9]+$"; - private static final Pattern NUMBER = Pattern.compile(NUMBER_REG_EXP); + private static final String NUMBER_REGEX = "^[0-9]+$"; + private static final String ORDER_REGEX = "\\[([^;]+),(\\d+),(\\d+)\\](?:;\\[([^;]+),(\\d+),(\\d+)\\])?;"; + private static final Pattern NUMBER = Pattern.compile(NUMBER_REGEX); + private static final Pattern ORDER = Pattern.compile(ORDER_REGEX); public static void validateBlank(String input) { if (input.isEmpty()){ @@ -20,4 +22,11 @@ public static void validateIsNumeric(String input) { throw new IllegalArgumentException(ErrorMessages.VALIDATE_NUMERIC.getErrorMessage()); } } + + public static void validateIsOrderFormat(String input) { + Matcher matcher = ORDER.matcher(input); + if (!matcher.find()) { + throw new IllegalArgumentException(ErrorMessages.VALIDATE_ORDER_FORMAT.getErrorMessage()); + } + } } diff --git a/src/main/java/utils/Parser.java b/src/main/java/utils/Parser.java index fc1c65814..044f3a887 100644 --- a/src/main/java/utils/Parser.java +++ b/src/main/java/utils/Parser.java @@ -1,8 +1,14 @@ package utils; public class Parser { + + private static final String SEMI_COLON = ";"; public static int convertToInt(String amount){ int parsedString = Integer.parseInt(amount); return parsedString; } + + public static void divideSemiColon(String input) { + String[] parsedInput = input.split(";"); + } } diff --git a/src/main/java/vendingmachine/CoinCounter.java b/src/main/java/vendingmachine/CoinCounter.java index 5cff576d9..543825413 100644 --- a/src/main/java/vendingmachine/CoinCounter.java +++ b/src/main/java/vendingmachine/CoinCounter.java @@ -5,7 +5,7 @@ public class CoinCounter { private final Map coinCounterMap = new EnumMap<>(Coin.class); - public Map getCounter(Amount amount) { + public Map getCounter(MachineAmount amount) { int targetAmount = amount.getMoney(); for (Coin coin : Coin.values()){ int coinNumbers = targetAmount / coin.getAmount(); diff --git a/src/main/java/vendingmachine/Amount.java b/src/main/java/vendingmachine/MachineAmount.java similarity index 85% rename from src/main/java/vendingmachine/Amount.java rename to src/main/java/vendingmachine/MachineAmount.java index 66e85eb2d..d79a17556 100644 --- a/src/main/java/vendingmachine/Amount.java +++ b/src/main/java/vendingmachine/MachineAmount.java @@ -1,19 +1,15 @@ package vendingmachine; import utils.ErrorMessages; -import utils.Parser; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class Amount { +public class MachineAmount { private static final int MINIMUM_MONEY = 100; private static final int DIVISIBLE_AMOUNT = 10; private static final int ZERO = 0; private final int money; - public Amount(int money) { + public MachineAmount(int money) { validateMinimumAmount(money); validateDivideByTen(money); this.money = money; diff --git a/src/main/java/view/InputView.java b/src/main/java/view/InputView.java index b7ed51f8d..7bf8bee1c 100644 --- a/src/main/java/view/InputView.java +++ b/src/main/java/view/InputView.java @@ -14,6 +14,8 @@ public static String readVendingMachineMoney() { public static String readOrderDetails() { String order = Console.readLine(); + InputValidator.validateBlank(order); + InputValidator.validateIsOrderFormat(order); return order; } } diff --git a/src/main/java/view/OutputView.java b/src/main/java/view/OutputView.java index 1ca31f0c0..031c6fab1 100644 --- a/src/main/java/view/OutputView.java +++ b/src/main/java/view/OutputView.java @@ -1,6 +1,6 @@ package view; -import vendingmachine.Amount; +import vendingmachine.MachineAmount; import vendingmachine.Coin; import vendingmachine.CoinCounter; @@ -12,7 +12,7 @@ public static void printVendingMachineMoney() { System.out.println("자판기가 보유하고 있는 금액을 입력해 주세요."); } - public static void printVendingMachineCoinAmount(CoinCounter coinCounter, Amount amount) { + public static void printVendingMachineCoinAmount(CoinCounter coinCounter, MachineAmount amount) { System.out.println(); System.out.println("자판기가 보유한 동전"); Map counterMap = coinCounter.getCounter(amount); From 5128030ba6d4b8a8e0e4ffd20dea19470bb5082d Mon Sep 17 00:00:00 2001 From: junsoo Date: Mon, 20 Nov 2023 19:33:33 +0900 Subject: [PATCH 13/20] =?UTF-8?q?feat:=20=EC=83=81=ED=92=88=EC=9D=98=20?= =?UTF-8?q?=EC=A0=95=EB=B3=B4=EB=A5=BC=20=EC=A0=80=EC=9E=A5=ED=95=98?= =?UTF-8?q?=EB=8A=94=20Product=20=ED=81=B4=EB=9E=98=EC=8A=A4=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/VendingMachineController.java | 13 ++++++++-- src/main/java/utils/Parser.java | 21 ++++++++++++++-- src/main/java/vendingmachine/Product.java | 25 +++++++++++++++++++ 3 files changed, 55 insertions(+), 4 deletions(-) create mode 100644 src/main/java/vendingmachine/Product.java diff --git a/src/main/java/controller/VendingMachineController.java b/src/main/java/controller/VendingMachineController.java index 5a34e4d15..b15cc9f2a 100644 --- a/src/main/java/controller/VendingMachineController.java +++ b/src/main/java/controller/VendingMachineController.java @@ -4,17 +4,19 @@ import utils.RepeatInput; import vendingmachine.MachineAmount; import vendingmachine.CoinCounter; +import vendingmachine.Product; import view.InputView; import view.OutputView; +import java.util.Map; + public class VendingMachineController { public void run() { MachineAmount amount = RepeatInput.repeatWhenInvalid(this::vendingMachineMoney); OutputView.printVendingMachineCoinAmount(new CoinCounter(), amount); - OutputView.printOrderDetails(); - InputView.readOrderDetails(); + Map productMap = RepeatInput.repeatWhenInvalid(this::productInformation); } private MachineAmount vendingMachineMoney() { @@ -23,4 +25,11 @@ private MachineAmount vendingMachineMoney() { int money = Parser.convertToInt(amount); return new MachineAmount(money); } + + private Map productInformation() { + OutputView.printOrderDetails(); + String input = InputView.readOrderDetails(); + Map productMap = Parser.convertToProductMap(input); + return productMap; + } } diff --git a/src/main/java/utils/Parser.java b/src/main/java/utils/Parser.java index 044f3a887..3c19de97d 100644 --- a/src/main/java/utils/Parser.java +++ b/src/main/java/utils/Parser.java @@ -1,14 +1,31 @@ package utils; +import vendingmachine.Product; + +import java.util.LinkedHashMap; +import java.util.Map; + public class Parser { private static final String SEMI_COLON = ";"; + private static final String BRACKETS = "\\[|\\]"; + private static final String BLANK = ""; public static int convertToInt(String amount){ int parsedString = Integer.parseInt(amount); return parsedString; } - public static void divideSemiColon(String input) { - String[] parsedInput = input.split(";"); + public static Map convertToProductMap(String input) { + String[] products = input.split(SEMI_COLON); + Map productMap = new LinkedHashMap<>(); + for (String product : products) { + String [] productInfo = product.replaceAll(BRACKETS, BLANK).split(SEMI_COLON); + String productName = productInfo[0]; + int price = convertToInt(productInfo[1]); + int quantity = convertToInt(productInfo[2]); + Product savedProduct = new Product(productName, price, quantity); + productMap.put(productName, savedProduct); + } + return productMap; } } diff --git a/src/main/java/vendingmachine/Product.java b/src/main/java/vendingmachine/Product.java new file mode 100644 index 000000000..0ade34f04 --- /dev/null +++ b/src/main/java/vendingmachine/Product.java @@ -0,0 +1,25 @@ +package vendingmachine; + +public class Product { + private final String name; + private final int price; + private final int quantity; + + public Product(String name, int price, int quantity) { + this.name = name; + this.price = price; + this.quantity = quantity; + } + + public String getName() { + return name; + } + + public int getPrice() { + return price; + } + + public int getQuantity() { + return quantity; + } +} \ No newline at end of file From 72e700392e588e1ea99557dbbc3f1fbac6e800fc Mon Sep 17 00:00:00 2001 From: junsoo Date: Mon, 20 Nov 2023 20:08:43 +0900 Subject: [PATCH 14/20] =?UTF-8?q?feat:=20Product=20=EC=A0=95=EB=B3=B4?= =?UTF-8?q?=EB=A5=BC=20Map=20=ED=98=95=ED=83=9C=EB=A1=9C=20=EC=A0=80?= =?UTF-8?q?=EC=9E=A5=ED=95=98=EB=8A=94=20Products=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/README.md | 9 +++++- .../controller/VendingMachineController.java | 30 ++++++++++++------- src/main/java/utils/ErrorMessages.java | 1 + src/main/java/utils/Parser.java | 3 +- src/main/java/vendingmachine/Products.java | 16 ++++++++++ src/main/java/view/InputView.java | 2 +- src/main/java/view/OutputView.java | 5 ++++ 7 files changed, 52 insertions(+), 14 deletions(-) create mode 100644 src/main/java/vendingmachine/Products.java diff --git a/src/main/README.md b/src/main/README.md index ee1f948d8..d40058161 100644 --- a/src/main/README.md +++ b/src/main/README.md @@ -12,6 +12,13 @@ - [] 상품명, 가격, 수량을 입력받는다. - [] 상품명, 가격, 수량은 쉼표로, 개별 상품은 대괄호([])로 묶어 세미콜론(;)으로 구분한다. - [] 정규식으로 매칭되나 체크 - - [] + + - [] 투입 금액을 입력 받는다. + - [X] 공백일 수 없다 + - [X] 0보다 작을 경우에 예외 처리 + - [X] 문자열이 들어올 수 없다 + - [] 투입 금액이 0일 때 + - [] 남은 금액이 최저 금액보다 적을 떄, 잔돈을 돌려받는다. + - [] 모든 상품이 소진된 경우, 잔돈을 돌려받는다. diff --git a/src/main/java/controller/VendingMachineController.java b/src/main/java/controller/VendingMachineController.java index b15cc9f2a..0d4cf4c9b 100644 --- a/src/main/java/controller/VendingMachineController.java +++ b/src/main/java/controller/VendingMachineController.java @@ -2,9 +2,7 @@ import utils.Parser; import utils.RepeatInput; -import vendingmachine.MachineAmount; -import vendingmachine.CoinCounter; -import vendingmachine.Product; +import vendingmachine.*; import view.InputView; import view.OutputView; @@ -13,23 +11,33 @@ public class VendingMachineController { public void run() { - MachineAmount amount = RepeatInput.repeatWhenInvalid(this::vendingMachineMoney); - OutputView.printVendingMachineCoinAmount(new CoinCounter(), amount); + MachineAmount vendingMoney = RepeatInput.repeatWhenInvalid(this::vendingMachineMoney); + OutputView.printVendingMachineCoinAmount(new CoinCounter(), vendingMoney); + + Products productsMap = RepeatInput.repeatWhenInvalid(this::productInformation); + + InputAmount inputAmount = RepeatInput.repeatWhenInvalid(this::inputAmount); - Map productMap = RepeatInput.repeatWhenInvalid(this::productInformation); } private MachineAmount vendingMachineMoney() { OutputView.printVendingMachineMoney(); - String amount = InputView.readVendingMachineMoney(); - int money = Parser.convertToInt(amount); - return new MachineAmount(money); + String amount = InputView.readAmountInput(); + int vendingMoney = Parser.convertToInt(amount); + return new MachineAmount(vendingMoney); } - private Map productInformation() { + private Products productInformation() { OutputView.printOrderDetails(); String input = InputView.readOrderDetails(); Map productMap = Parser.convertToProductMap(input); - return productMap; + return new Products(productMap); + } + + private InputAmount inputAmount() { + OutputView.printInputAmount(); + String amount = InputView.readAmountInput(); + int inputAmount = Parser.convertToInt(amount); + return new InputAmount(inputAmount); } } diff --git a/src/main/java/utils/ErrorMessages.java b/src/main/java/utils/ErrorMessages.java index aab0de32c..81adf6afb 100644 --- a/src/main/java/utils/ErrorMessages.java +++ b/src/main/java/utils/ErrorMessages.java @@ -7,6 +7,7 @@ public enum ErrorMessages { VALIDATE_DIVIDE_BY_TEN("[ERROR] 금액은 10원 단위여야 합니다."), VALIDATE_NUMERIC("[ERROR] 금액에 숫자 이외의 값이 들어올 수 없습니다."), VALIDATE_ORDER_FORMAT("[ERROR] 올바르지 않은 입력 형식 입니다."), + VALIDATE_NEGATIVE("[ERROR] 투입 금액은 0보다 작을 수 없습니다."), ; private final String message; diff --git a/src/main/java/utils/Parser.java b/src/main/java/utils/Parser.java index 3c19de97d..91e89c67c 100644 --- a/src/main/java/utils/Parser.java +++ b/src/main/java/utils/Parser.java @@ -8,6 +8,7 @@ public class Parser { private static final String SEMI_COLON = ";"; + private static final String COMMA = ","; private static final String BRACKETS = "\\[|\\]"; private static final String BLANK = ""; public static int convertToInt(String amount){ @@ -19,7 +20,7 @@ public static Map convertToProductMap(String input) { String[] products = input.split(SEMI_COLON); Map productMap = new LinkedHashMap<>(); for (String product : products) { - String [] productInfo = product.replaceAll(BRACKETS, BLANK).split(SEMI_COLON); + String [] productInfo = product.replaceAll(BRACKETS, BLANK).split(COMMA); String productName = productInfo[0]; int price = convertToInt(productInfo[1]); int quantity = convertToInt(productInfo[2]); diff --git a/src/main/java/vendingmachine/Products.java b/src/main/java/vendingmachine/Products.java new file mode 100644 index 000000000..be416278b --- /dev/null +++ b/src/main/java/vendingmachine/Products.java @@ -0,0 +1,16 @@ +package vendingmachine; + +import java.util.Map; + +public class Products { + + private final Map productMap; + + public Products(Map productMap) { + this.productMap = productMap; + } + + public Map getProductMap() { + return productMap; + } +} diff --git a/src/main/java/view/InputView.java b/src/main/java/view/InputView.java index 7bf8bee1c..bbba7537f 100644 --- a/src/main/java/view/InputView.java +++ b/src/main/java/view/InputView.java @@ -5,7 +5,7 @@ public class InputView { - public static String readVendingMachineMoney() { + public static String readAmountInput() { String amount = Console.readLine(); InputValidator.validateBlank(amount); InputValidator.validateIsNumeric(amount); diff --git a/src/main/java/view/OutputView.java b/src/main/java/view/OutputView.java index 031c6fab1..d4dd53d18 100644 --- a/src/main/java/view/OutputView.java +++ b/src/main/java/view/OutputView.java @@ -28,4 +28,9 @@ public static void printOrderDetails() { System.out.println(); System.out.println("상품명과 가격, 수량을 입력해 주세요."); } + + public static void printInputAmount() { + System.out.println(); + System.out.println("투입 금액을 입력해 주세요."); + } } From 6220e22899b14de75d6e7af465d978f0286f4350 Mon Sep 17 00:00:00 2001 From: junsoo Date: Mon, 20 Nov 2023 20:08:56 +0900 Subject: [PATCH 15/20] =?UTF-8?q?feat:=20=ED=88=AC=EC=9E=85=20=EA=B8=88?= =?UTF-8?q?=EC=95=A1=EC=9D=84=20=EA=B4=80=EB=A6=AC=ED=95=98=EB=8A=94=20Inp?= =?UTF-8?q?utAmount=20=ED=81=B4=EB=9E=98=EC=8A=A4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/vendingmachine/InputAmount.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 src/main/java/vendingmachine/InputAmount.java diff --git a/src/main/java/vendingmachine/InputAmount.java b/src/main/java/vendingmachine/InputAmount.java new file mode 100644 index 000000000..d2210bd6c --- /dev/null +++ b/src/main/java/vendingmachine/InputAmount.java @@ -0,0 +1,24 @@ +package vendingmachine; + +import utils.ErrorMessages; + +public class InputAmount { + + private static final int ZERO = 0; + private final int money; + + public InputAmount(int money) { + validateNegative(money); + this.money = money; + } + + public int getMoney() { + return money; + } + + private void validateNegative(int money) { + if (money < ZERO) { + throw new IllegalArgumentException(ErrorMessages.VALIDATE_NEGATIVE.getErrorMessage()); + } + } +} From c7fa76115a5bc163055c59d022a0defec9f1c467 Mon Sep 17 00:00:00 2001 From: junsoo Date: Mon, 20 Nov 2023 20:40:14 +0900 Subject: [PATCH 16/20] =?UTF-8?q?feat:=20=EC=A1=B4=EC=9E=AC=ED=95=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EB=8A=94=20=EC=83=81=ED=92=88=20=EC=9D=B4?= =?UTF-8?q?=EB=A6=84=EC=9D=84=20=EC=9E=85=EB=A0=A5=ED=95=A0=20=EA=B2=BD?= =?UTF-8?q?=EC=9A=B0=20=EC=9C=A0=ED=9A=A8=EC=84=B1=20=EA=B2=80=EC=82=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/README.md | 10 ++++++---- .../java/controller/VendingMachineController.java | 9 +++++++++ src/main/java/utils/ErrorMessages.java | 1 + src/main/java/utils/InputValidator.java | 14 ++++++++++++++ src/main/java/vendingmachine/Products.java | 11 +++++++++++ src/main/java/view/InputView.java | 8 ++++++++ src/main/java/view/OutputView.java | 8 ++++++++ 7 files changed, 57 insertions(+), 4 deletions(-) diff --git a/src/main/README.md b/src/main/README.md index d40058161..cb7623607 100644 --- a/src/main/README.md +++ b/src/main/README.md @@ -9,9 +9,9 @@ - [X] 해당 금액에 맞는 잔돈을 돌려준다. - [X] 잔돈은 동전의 최소 개수로 돌려주어야 한다. - - [] 상품명, 가격, 수량을 입력받는다. - - [] 상품명, 가격, 수량은 쉼표로, 개별 상품은 대괄호([])로 묶어 세미콜론(;)으로 구분한다. - - [] 정규식으로 매칭되나 체크 + - [X] 상품명, 가격, 수량을 입력받는다. + - [X] 상품명, 가격, 수량은 쉼표로, 개별 상품은 대괄호([])로 묶어 세미콜론(;)으로 구분한다. + - [X] 정규식으로 매칭되나 체크 - [] 투입 금액을 입력 받는다. - [X] 공백일 수 없다 @@ -21,4 +21,6 @@ - [] 남은 금액이 최저 금액보다 적을 떄, 잔돈을 돌려받는다. - [] 모든 상품이 소진된 경우, 잔돈을 돌려받는다. - + - [X] 구매할 상품명을 입력 받는다. + - [X] 공백일 수 없다. + - [X] 입력받은 메뉴와 일치하지 않는 경우, 예외 처리 diff --git a/src/main/java/controller/VendingMachineController.java b/src/main/java/controller/VendingMachineController.java index 0d4cf4c9b..05ea2454d 100644 --- a/src/main/java/controller/VendingMachineController.java +++ b/src/main/java/controller/VendingMachineController.java @@ -18,6 +18,10 @@ public void run() { InputAmount inputAmount = RepeatInput.repeatWhenInvalid(this::inputAmount); + purchaseProcess(productsMap, inputAmount); + // 입력값을 다시 받지 않는 오류 수정해야 함. + + } private MachineAmount vendingMachineMoney() { @@ -40,4 +44,9 @@ private InputAmount inputAmount() { int inputAmount = Parser.convertToInt(amount); return new InputAmount(inputAmount); } + + private void purchaseProcess(Products products, InputAmount inputAmount) { + OutputView.printPurchaseProduct(inputAmount); + String purchaseName = InputView.readPurchaseName(products); + } } diff --git a/src/main/java/utils/ErrorMessages.java b/src/main/java/utils/ErrorMessages.java index 81adf6afb..722d6a922 100644 --- a/src/main/java/utils/ErrorMessages.java +++ b/src/main/java/utils/ErrorMessages.java @@ -8,6 +8,7 @@ public enum ErrorMessages { VALIDATE_NUMERIC("[ERROR] 금액에 숫자 이외의 값이 들어올 수 없습니다."), VALIDATE_ORDER_FORMAT("[ERROR] 올바르지 않은 입력 형식 입니다."), VALIDATE_NEGATIVE("[ERROR] 투입 금액은 0보다 작을 수 없습니다."), + VALIDATE_EXIST_NAME("[ERROR] 구매할 상품이 존재하지 않습니다."), ; private final String message; diff --git a/src/main/java/utils/InputValidator.java b/src/main/java/utils/InputValidator.java index b66a3f57a..7ef352758 100644 --- a/src/main/java/utils/InputValidator.java +++ b/src/main/java/utils/InputValidator.java @@ -1,5 +1,9 @@ package utils; +import vendingmachine.Product; +import vendingmachine.Products; + +import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -29,4 +33,14 @@ public static void validateIsOrderFormat(String input) { throw new IllegalArgumentException(ErrorMessages.VALIDATE_ORDER_FORMAT.getErrorMessage()); } } + + public static void validatePurchaseProductExist(Products products , String input) { + Map productMap = products.getProductMap(); + for (String savedName : productMap.keySet()) { + if (savedName.equals(input)) { + return; + } + } + throw new IllegalArgumentException(ErrorMessages.VALIDATE_EXIST_NAME.getErrorMessage()); + } } diff --git a/src/main/java/vendingmachine/Products.java b/src/main/java/vendingmachine/Products.java index be416278b..080be12f6 100644 --- a/src/main/java/vendingmachine/Products.java +++ b/src/main/java/vendingmachine/Products.java @@ -13,4 +13,15 @@ public Products(Map productMap) { public Map getProductMap() { return productMap; } + + public int getMininumProduct() { + int minimumPrice = Integer.MAX_VALUE; + for (Product product : productMap.values()) { + int price = product.getPrice(); + if (price < minimumPrice) { + minimumPrice = price; + } + } + return minimumPrice; + } } diff --git a/src/main/java/view/InputView.java b/src/main/java/view/InputView.java index bbba7537f..c72e18dc4 100644 --- a/src/main/java/view/InputView.java +++ b/src/main/java/view/InputView.java @@ -2,6 +2,7 @@ import camp.nextstep.edu.missionutils.Console; import utils.InputValidator; +import vendingmachine.Products; public class InputView { @@ -18,4 +19,11 @@ public static String readOrderDetails() { InputValidator.validateIsOrderFormat(order); return order; } + + public static String readPurchaseName(Products products) { + String name = Console.readLine(); + InputValidator.validateBlank(name); + InputValidator.validatePurchaseProductExist(products, name); + return name; + } } diff --git a/src/main/java/view/OutputView.java b/src/main/java/view/OutputView.java index d4dd53d18..3b53a8313 100644 --- a/src/main/java/view/OutputView.java +++ b/src/main/java/view/OutputView.java @@ -1,5 +1,6 @@ package view; +import vendingmachine.InputAmount; import vendingmachine.MachineAmount; import vendingmachine.Coin; import vendingmachine.CoinCounter; @@ -33,4 +34,11 @@ public static void printInputAmount() { System.out.println(); System.out.println("투입 금액을 입력해 주세요."); } + + public static void printPurchaseProduct(InputAmount inputAmount) { + System.out.println(); + System.out.println(String.format("투입 금액: %d" , inputAmount.getMoney())); + System.out.println("구매할 상품명을 입력해 주세요."); + + } } From b1a83cbfa756fff96e5d3d1f16d32e682681004c Mon Sep 17 00:00:00 2001 From: junsoo Date: Mon, 20 Nov 2023 21:16:27 +0900 Subject: [PATCH 17/20] =?UTF-8?q?feat:=20=EB=82=A8=EC=9D=80=20=EA=B8=88?= =?UTF-8?q?=EC=95=A1=EC=9D=B4=20=EC=83=81=ED=92=88=EC=9D=98=20=EC=B5=9C?= =?UTF-8?q?=EC=A0=80=20=EA=B0=80=EA=B2=A9=EB=B3=B4=EB=8B=A4=20=EB=82=AE?= =?UTF-8?q?=EC=9D=84=EB=95=8C=EA=B9=8C=EC=A7=80=20=EA=B3=84=EC=82=B0?= =?UTF-8?q?=ED=95=98=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/controller/VendingMachineController.java | 14 ++++++++++---- src/main/java/utils/RepeatInput.java | 2 ++ src/main/java/vendingmachine/InputAmount.java | 7 ++++++- src/main/java/vendingmachine/Products.java | 9 +++++++++ src/main/java/view/OutputView.java | 1 - 5 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/main/java/controller/VendingMachineController.java b/src/main/java/controller/VendingMachineController.java index 05ea2454d..8e8f04aac 100644 --- a/src/main/java/controller/VendingMachineController.java +++ b/src/main/java/controller/VendingMachineController.java @@ -18,7 +18,8 @@ public void run() { InputAmount inputAmount = RepeatInput.repeatWhenInvalid(this::inputAmount); - purchaseProcess(productsMap, inputAmount); + int remainder = RepeatInput.repeatWhenInvalid(() -> purchaseProcess(productsMap, inputAmount)); + // 입력값을 다시 받지 않는 오류 수정해야 함. @@ -45,8 +46,13 @@ private InputAmount inputAmount() { return new InputAmount(inputAmount); } - private void purchaseProcess(Products products, InputAmount inputAmount) { - OutputView.printPurchaseProduct(inputAmount); - String purchaseName = InputView.readPurchaseName(products); + private int purchaseProcess(Products products, InputAmount inputAmount) { + while(inputAmount.getMoney() >= products.getMininumProduct()) { + OutputView.printPurchaseProduct(inputAmount); + String purchaseName = InputView.readPurchaseName(products); + int purchasePrice = products.findInputAmount(purchaseName); + inputAmount.subtractMoney(purchasePrice); + } + return inputAmount.getMoney(); } } diff --git a/src/main/java/utils/RepeatInput.java b/src/main/java/utils/RepeatInput.java index 701812104..b3a3e09d9 100644 --- a/src/main/java/utils/RepeatInput.java +++ b/src/main/java/utils/RepeatInput.java @@ -1,5 +1,7 @@ package utils; +import vendingmachine.MachineAmount; + import java.util.function.Supplier; public class RepeatInput { diff --git a/src/main/java/vendingmachine/InputAmount.java b/src/main/java/vendingmachine/InputAmount.java index d2210bd6c..4bdf24b4b 100644 --- a/src/main/java/vendingmachine/InputAmount.java +++ b/src/main/java/vendingmachine/InputAmount.java @@ -5,7 +5,7 @@ public class InputAmount { private static final int ZERO = 0; - private final int money; + private int money; public InputAmount(int money) { validateNegative(money); @@ -16,6 +16,11 @@ public int getMoney() { return money; } + public void subtractMoney(int subtractAmount) { + validateNegative(subtractAmount); + money -= subtractAmount; + } + private void validateNegative(int money) { if (money < ZERO) { throw new IllegalArgumentException(ErrorMessages.VALIDATE_NEGATIVE.getErrorMessage()); diff --git a/src/main/java/vendingmachine/Products.java b/src/main/java/vendingmachine/Products.java index 080be12f6..36d969f45 100644 --- a/src/main/java/vendingmachine/Products.java +++ b/src/main/java/vendingmachine/Products.java @@ -14,6 +14,15 @@ public Map getProductMap() { return productMap; } + public int findInputAmount(String inputName) { + for (String name : productMap.keySet()) { + if (name.equals(inputName)) { + return productMap.get(name).getPrice(); + } + } + return 0; + } + public int getMininumProduct() { int minimumPrice = Integer.MAX_VALUE; for (Product product : productMap.values()) { diff --git a/src/main/java/view/OutputView.java b/src/main/java/view/OutputView.java index 3b53a8313..7847ce472 100644 --- a/src/main/java/view/OutputView.java +++ b/src/main/java/view/OutputView.java @@ -39,6 +39,5 @@ public static void printPurchaseProduct(InputAmount inputAmount) { System.out.println(); System.out.println(String.format("투입 금액: %d" , inputAmount.getMoney())); System.out.println("구매할 상품명을 입력해 주세요."); - } } From 20491324569a0f66d654b8b874b0653ade22ab4f Mon Sep 17 00:00:00 2001 From: junsoo Date: Mon, 20 Nov 2023 21:46:01 +0900 Subject: [PATCH 18/20] =?UTF-8?q?feat:=20=EB=82=A8=EC=9D=80=20=EA=B8=88?= =?UTF-8?q?=EC=95=A1=EC=9D=B4=20=EC=9E=90=ED=8C=90=EA=B8=B0=EA=B0=80=20?= =?UTF-8?q?=EB=B3=B4=EC=9C=A0=ED=95=98=EA=B3=A0=20=EC=9E=88=EB=8A=94=20?= =?UTF-8?q?=EA=B8=88=EC=95=A1=EB=B3=B4=EB=8B=A4=20=ED=81=B4=20=EB=95=8C,?= =?UTF-8?q?=20=EC=9E=90=ED=8C=90=EA=B8=B0=EA=B0=80=20=EB=B3=B4=EC=9C=A0?= =?UTF-8?q?=ED=95=9C=20=EA=B8=88=EC=95=A1=EC=9C=BC=EB=A1=9C=20=EC=9E=94?= =?UTF-8?q?=EB=8F=88=EC=9D=84=20=EB=B0=98=ED=99=98=20=EB=B0=9B=EB=8A=94?= =?UTF-8?q?=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/VendingMachineController.java | 2 +- src/main/java/vendingmachine/CoinCounter.java | 19 ++++++++++++++++--- src/main/java/view/OutputView.java | 19 +++++++++++++++++-- 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/src/main/java/controller/VendingMachineController.java b/src/main/java/controller/VendingMachineController.java index 8e8f04aac..2ef0ac156 100644 --- a/src/main/java/controller/VendingMachineController.java +++ b/src/main/java/controller/VendingMachineController.java @@ -20,7 +20,7 @@ public void run() { int remainder = RepeatInput.repeatWhenInvalid(() -> purchaseProcess(productsMap, inputAmount)); - // 입력값을 다시 받지 않는 오류 수정해야 함. + OutputView.printRemainChanges(new CoinCounter(), vendingMoney, remainder); } diff --git a/src/main/java/vendingmachine/CoinCounter.java b/src/main/java/vendingmachine/CoinCounter.java index 543825413..92377f9fc 100644 --- a/src/main/java/vendingmachine/CoinCounter.java +++ b/src/main/java/vendingmachine/CoinCounter.java @@ -5,13 +5,26 @@ public class CoinCounter { private final Map coinCounterMap = new EnumMap<>(Coin.class); + private final Map remainCounterMap = new EnumMap<>(Coin.class); public Map getCounter(MachineAmount amount) { - int targetAmount = amount.getMoney(); + int vendingMoney = amount.getMoney(); for (Coin coin : Coin.values()){ - int coinNumbers = targetAmount / coin.getAmount(); + int coinNumbers = vendingMoney / coin.getAmount(); coinCounterMap.put(coin, coinNumbers); - targetAmount %= coin.getAmount(); + vendingMoney %= coin.getAmount(); } return coinCounterMap; } + + public Map getRemainCounter(MachineAmount amount, int remainder) { + int vendingMoney = amount.getMoney(); + if (remainder >= vendingMoney) { + for (Coin remainderCoin : Coin.values()) { + int remainCoinNumbers = vendingMoney / remainderCoin.getAmount(); + remainCounterMap.put(remainderCoin, remainCoinNumbers); + vendingMoney %= remainderCoin.getAmount(); + } + } + return remainCounterMap; + } } diff --git a/src/main/java/view/OutputView.java b/src/main/java/view/OutputView.java index 7847ce472..a992c182c 100644 --- a/src/main/java/view/OutputView.java +++ b/src/main/java/view/OutputView.java @@ -21,7 +21,7 @@ public static void printVendingMachineCoinAmount(CoinCounter coinCounter, Machin for(Map.Entry entry : counterMap.entrySet()) { Coin coin = entry.getKey(); int count = entry.getValue(); - System.out.println(coin.displayCoinName() + " : " + count + "개"); + System.out.println(coin.displayCoinName() + " - " + count + "개"); } } @@ -37,7 +37,22 @@ public static void printInputAmount() { public static void printPurchaseProduct(InputAmount inputAmount) { System.out.println(); - System.out.println(String.format("투입 금액: %d" , inputAmount.getMoney())); + System.out.println(String.format("투입 금액: %d원" , inputAmount.getMoney())); System.out.println("구매할 상품명을 입력해 주세요."); } + + public static void printRemainChanges(CoinCounter coinCounter, MachineAmount amount, int remainder) { + System.out.println(); + System.out.println(String.format("투입 금액: %d원", remainder)); + System.out.println("잔돈"); + + Map counterMap = coinCounter.getRemainCounter(amount, remainder); + for(Map.Entry entry : counterMap.entrySet()) { + Coin coin = entry.getKey(); + int count = entry.getValue(); + if (count != 0) { + System.out.println(coin.displayCoinName() + " - " + count + "개"); + } + } + } } From aeb671c6ec5843e04ea7bbedfff2ddec9d20e6ac Mon Sep 17 00:00:00 2001 From: junsoo Date: Mon, 20 Nov 2023 21:46:39 +0900 Subject: [PATCH 19/20] =?UTF-8?q?docs:=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=20=EB=AA=A9=EB=A1=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/README.md b/src/main/README.md index cb7623607..01532af68 100644 --- a/src/main/README.md +++ b/src/main/README.md @@ -13,12 +13,11 @@ - [X] 상품명, 가격, 수량은 쉼표로, 개별 상품은 대괄호([])로 묶어 세미콜론(;)으로 구분한다. - [X] 정규식으로 매칭되나 체크 - - [] 투입 금액을 입력 받는다. + - [X] 투입 금액을 입력 받는다. - [X] 공백일 수 없다 - [X] 0보다 작을 경우에 예외 처리 - [X] 문자열이 들어올 수 없다 - - [] 투입 금액이 0일 때 - - [] 남은 금액이 최저 금액보다 적을 떄, 잔돈을 돌려받는다. + - [X] 남은 금액이 최저 금액보다 적을 떄, 잔돈을 돌려받는다. - [] 모든 상품이 소진된 경우, 잔돈을 돌려받는다. - [X] 구매할 상품명을 입력 받는다. From 78c6f22e6e4d679aabf77a93f0030c69f85aa481 Mon Sep 17 00:00:00 2001 From: junsoo Date: Mon, 20 Nov 2023 21:56:20 +0900 Subject: [PATCH 20/20] =?UTF-8?q?feat:=20=EC=83=81=ED=92=88=20=EC=88=98?= =?UTF-8?q?=EB=9F=89=EC=9D=B4=200=EB=B3=B4=EB=8B=A4=20=EC=9E=91=EC=9D=84?= =?UTF-8?q?=20=EB=95=8C=20=EC=9C=A0=ED=9A=A8=EC=84=B1=20=EA=B2=80=EC=82=AC?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/README.md | 2 +- .../java/controller/VendingMachineController.java | 7 +++---- src/main/java/utils/ErrorMessages.java | 1 + src/main/java/vendingmachine/Product.java | 11 ++++++++++- src/main/java/view/OutputView.java | 3 ++- 5 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/main/README.md b/src/main/README.md index 01532af68..42f1a8fec 100644 --- a/src/main/README.md +++ b/src/main/README.md @@ -18,7 +18,7 @@ - [X] 0보다 작을 경우에 예외 처리 - [X] 문자열이 들어올 수 없다 - [X] 남은 금액이 최저 금액보다 적을 떄, 잔돈을 돌려받는다. - - [] 모든 상품이 소진된 경우, 잔돈을 돌려받는다. + - [X] 모든 상품이 소진된 경우, 잔돈을 돌려받는다. - [X] 구매할 상품명을 입력 받는다. - [X] 공백일 수 없다. diff --git a/src/main/java/controller/VendingMachineController.java b/src/main/java/controller/VendingMachineController.java index 2ef0ac156..9ce8f67df 100644 --- a/src/main/java/controller/VendingMachineController.java +++ b/src/main/java/controller/VendingMachineController.java @@ -15,14 +15,10 @@ public void run() { OutputView.printVendingMachineCoinAmount(new CoinCounter(), vendingMoney); Products productsMap = RepeatInput.repeatWhenInvalid(this::productInformation); - InputAmount inputAmount = RepeatInput.repeatWhenInvalid(this::inputAmount); int remainder = RepeatInput.repeatWhenInvalid(() -> purchaseProcess(productsMap, inputAmount)); - OutputView.printRemainChanges(new CoinCounter(), vendingMoney, remainder); - - } private MachineAmount vendingMachineMoney() { @@ -51,6 +47,9 @@ private int purchaseProcess(Products products, InputAmount inputAmount) { OutputView.printPurchaseProduct(inputAmount); String purchaseName = InputView.readPurchaseName(products); int purchasePrice = products.findInputAmount(purchaseName); + + Product purchasedProduct = products.getProductMap().get(purchaseName); + purchasedProduct.decreaseQuantity(); inputAmount.subtractMoney(purchasePrice); } return inputAmount.getMoney(); diff --git a/src/main/java/utils/ErrorMessages.java b/src/main/java/utils/ErrorMessages.java index 722d6a922..9a14533fe 100644 --- a/src/main/java/utils/ErrorMessages.java +++ b/src/main/java/utils/ErrorMessages.java @@ -9,6 +9,7 @@ public enum ErrorMessages { VALIDATE_ORDER_FORMAT("[ERROR] 올바르지 않은 입력 형식 입니다."), VALIDATE_NEGATIVE("[ERROR] 투입 금액은 0보다 작을 수 없습니다."), VALIDATE_EXIST_NAME("[ERROR] 구매할 상품이 존재하지 않습니다."), + VALIDATE_NEGATIVE_QUANTITY("[ERROR] 상품 수량은 0보다 작을 수 없습니다."), ; private final String message; diff --git a/src/main/java/vendingmachine/Product.java b/src/main/java/vendingmachine/Product.java index 0ade34f04..7eb0a96bf 100644 --- a/src/main/java/vendingmachine/Product.java +++ b/src/main/java/vendingmachine/Product.java @@ -1,9 +1,11 @@ package vendingmachine; +import utils.ErrorMessages; + public class Product { private final String name; private final int price; - private final int quantity; + private int quantity; public Product(String name, int price, int quantity) { this.name = name; @@ -22,4 +24,11 @@ public int getPrice() { public int getQuantity() { return quantity; } + + public void decreaseQuantity() { + quantity--; + if (quantity < 0) { + throw new IllegalArgumentException(ErrorMessages.VALIDATE_NEGATIVE_QUANTITY.getErrorMessage()); + } + } } \ No newline at end of file diff --git a/src/main/java/view/OutputView.java b/src/main/java/view/OutputView.java index a992c182c..1482ddea0 100644 --- a/src/main/java/view/OutputView.java +++ b/src/main/java/view/OutputView.java @@ -9,6 +9,7 @@ public class OutputView { + private static final int ZERO = 0; public static void printVendingMachineMoney() { System.out.println("자판기가 보유하고 있는 금액을 입력해 주세요."); } @@ -50,7 +51,7 @@ public static void printRemainChanges(CoinCounter coinCounter, MachineAmount amo for(Map.Entry entry : counterMap.entrySet()) { Coin coin = entry.getKey(); int count = entry.getValue(); - if (count != 0) { + if (count != ZERO) { System.out.println(coin.displayCoinName() + " - " + count + "개"); } }