From 7c70f78f2133faa35add838b1ec45e5b5b506d82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=97=B0=EC=A7=84?= Date: Thu, 21 Sep 2023 13:33:42 +0900 Subject: [PATCH 01/31] =?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=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 docs/README.md diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 000000000..ce7194894 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,18 @@ +## 기능 구현 목록 + +- [ ] 자판기 보유 금액을 입력한다. + - [ ] 10원 단위로 나누어 떨어지지 않을 경우 예외 발생 +- [ ] 입력받은 보유 금액에 따라 동전 개수 랜덤 생성 +- [ ] 자판기가 보유하고 있는 동전의 개수를 출력한다. +- [ ] 자판기에 상품을 입력한다. + - [ ] 상품의 가격이 100원이하일 경우 예외 + - [ ] 상품의 가격이 10원 단위로 나누어 떨어지지 않을 경우 예외 +- [ ] 사용자가 투입할 금액을 입력한다. +- [ ] 구매할 상품명 입력 + - [ ] 해당 상품이 존재하지 않을 경우 예외 +- [ ] 상품 구매 + - [ ] 금액 계산 + - [ ] 넣은 금액이 상품의 가격보다 작은 경우 예외 발생 + - [ ] 상품 개수 하나 줄이기 +- [ ] 남은 금액이 상품의 최저 가격보다 적거나, 모든 상품이 소진된 경우 종료 + - [ ] 잔돈 출력 \ No newline at end of file From 928dc98cde3499ffacc69404ad7ac5698cc69782 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=97=B0=EC=A7=84?= Date: Thu, 21 Sep 2023 13:41:33 +0900 Subject: [PATCH 02/31] =?UTF-8?q?feat(OutputView):=20=EC=9E=90=ED=8C=90?= =?UTF-8?q?=EA=B8=B0=20=EB=B3=B4=EC=9C=A0=20=EA=B8=88=EC=95=A1=20=EB=A9=94?= =?UTF-8?q?=EC=8B=9C=EC=A7=80=20=EC=B6=9C=EB=A0=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vendingmachine/constant/OutputMessage.java | 17 +++++++++++++++++ .../java/vendingmachine/view/OutputView.java | 10 ++++++++++ 2 files changed, 27 insertions(+) create mode 100644 src/main/java/vendingmachine/constant/OutputMessage.java create mode 100644 src/main/java/vendingmachine/view/OutputView.java diff --git a/src/main/java/vendingmachine/constant/OutputMessage.java b/src/main/java/vendingmachine/constant/OutputMessage.java new file mode 100644 index 000000000..cc4ad96a1 --- /dev/null +++ b/src/main/java/vendingmachine/constant/OutputMessage.java @@ -0,0 +1,17 @@ +package vendingmachine.constant; + +public enum OutputMessage { + + READ_MACHINE_CHANGE("자판기가 보유하고 있는 금액을 입력해 주세요."); + + private final String message; + + OutputMessage(String message) { + this.message = message; + } + + @Override + public String toString() { + return message; + } +} diff --git a/src/main/java/vendingmachine/view/OutputView.java b/src/main/java/vendingmachine/view/OutputView.java new file mode 100644 index 000000000..7f602ca08 --- /dev/null +++ b/src/main/java/vendingmachine/view/OutputView.java @@ -0,0 +1,10 @@ +package vendingmachine.view; + +import vendingmachine.constant.OutputMessage; + +public class OutputView { + + public void printChangeMessage() { + System.out.println(OutputMessage.READ_MACHINE_CHANGE); + } +} From 051a712a0835eb930dc1f84b70678264c4d670c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=97=B0=EC=A7=84?= Date: Thu, 21 Sep 2023 13:42:20 +0900 Subject: [PATCH 03/31] =?UTF-8?q?feat(InputView):=20=EC=9E=90=ED=8C=90?= =?UTF-8?q?=EA=B8=B0=20=EB=B3=B4=EC=9C=A0=20=EA=B8=88=EC=95=A1=20=EC=9E=85?= =?UTF-8?q?=EB=A0=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 2 +- src/main/java/vendingmachine/Application.java | 5 ++++- .../controller/MachineController.java | 19 +++++++++++++++++++ .../java/vendingmachine/view/InputView.java | 10 ++++++++++ 4 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 src/main/java/vendingmachine/controller/MachineController.java create mode 100644 src/main/java/vendingmachine/view/InputView.java diff --git a/docs/README.md b/docs/README.md index ce7194894..8021a5cce 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,6 +1,6 @@ ## 기능 구현 목록 -- [ ] 자판기 보유 금액을 입력한다. +- [x] 자판기 보유 금액을 입력한다. - [ ] 10원 단위로 나누어 떨어지지 않을 경우 예외 발생 - [ ] 입력받은 보유 금액에 따라 동전 개수 랜덤 생성 - [ ] 자판기가 보유하고 있는 동전의 개수를 출력한다. diff --git a/src/main/java/vendingmachine/Application.java b/src/main/java/vendingmachine/Application.java index 9d3be447b..fdb0a9dd1 100644 --- a/src/main/java/vendingmachine/Application.java +++ b/src/main/java/vendingmachine/Application.java @@ -1,7 +1,10 @@ package vendingmachine; +import vendingmachine.controller.MachineController; + public class Application { public static void main(String[] args) { - // TODO: 프로그램 구현 + MachineController controller = new MachineController(); + controller.start(); } } diff --git a/src/main/java/vendingmachine/controller/MachineController.java b/src/main/java/vendingmachine/controller/MachineController.java new file mode 100644 index 000000000..e567e8542 --- /dev/null +++ b/src/main/java/vendingmachine/controller/MachineController.java @@ -0,0 +1,19 @@ +package vendingmachine.controller; + +import vendingmachine.view.InputView; +import vendingmachine.view.OutputView; + +public class MachineController { + + private final InputView inputView = new InputView(); + private final OutputView outputView = new OutputView(); + + public void start() { + int change = readChangePrice(); + } + + public int readChangePrice() { + outputView.printChangeMessage(); + return inputView.readChangePrice(); + } +} diff --git a/src/main/java/vendingmachine/view/InputView.java b/src/main/java/vendingmachine/view/InputView.java new file mode 100644 index 000000000..e22a1832f --- /dev/null +++ b/src/main/java/vendingmachine/view/InputView.java @@ -0,0 +1,10 @@ +package vendingmachine.view; + +import camp.nextstep.edu.missionutils.Console; + +public class InputView { + + public int readChangePrice() { + return Integer.parseInt(Console.readLine()); + } +} From 58ee8ae2a7c735eb398d0fe3ebbadf18f54b4b5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=97=B0=EC=A7=84?= Date: Thu, 21 Sep 2023 14:13:49 +0900 Subject: [PATCH 04/31] =?UTF-8?q?feat(Coins):=20=EC=9E=85=EB=A0=A5?= =?UTF-8?q?=EB=B0=9B=EC=9D=80=20=EB=B3=B4=EC=9C=A0=20=EA=B8=88=EC=95=A1?= =?UTF-8?q?=EC=97=90=20=EB=94=B0=EB=9D=BC=20=EB=8F=99=EC=A0=84=20=EA=B0=9C?= =?UTF-8?q?=EC=88=98=20=EB=9E=9C=EB=8D=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/vendingmachine/Coin.java | 16 ---------- .../controller/MachineController.java | 3 +- src/main/java/vendingmachine/domain/Coin.java | 31 +++++++++++++++++++ .../java/vendingmachine/domain/Coins.java | 30 ++++++++++++++++++ 4 files changed, 63 insertions(+), 17 deletions(-) delete mode 100644 src/main/java/vendingmachine/Coin.java create mode 100644 src/main/java/vendingmachine/domain/Coin.java create mode 100644 src/main/java/vendingmachine/domain/Coins.java diff --git a/src/main/java/vendingmachine/Coin.java b/src/main/java/vendingmachine/Coin.java deleted file mode 100644 index c76293fbc..000000000 --- a/src/main/java/vendingmachine/Coin.java +++ /dev/null @@ -1,16 +0,0 @@ -package vendingmachine; - -public enum Coin { - COIN_500(500), - COIN_100(100), - COIN_50(50), - COIN_10(10); - - private final int amount; - - Coin(final int amount) { - this.amount = amount; - } - - // 추가 기능 구현 -} diff --git a/src/main/java/vendingmachine/controller/MachineController.java b/src/main/java/vendingmachine/controller/MachineController.java index e567e8542..826a9b791 100644 --- a/src/main/java/vendingmachine/controller/MachineController.java +++ b/src/main/java/vendingmachine/controller/MachineController.java @@ -1,5 +1,6 @@ package vendingmachine.controller; +import vendingmachine.domain.Coins; import vendingmachine.view.InputView; import vendingmachine.view.OutputView; @@ -9,7 +10,7 @@ public class MachineController { private final OutputView outputView = new OutputView(); public void start() { - int change = readChangePrice(); + new Coins(readChangePrice()); } public int readChangePrice() { diff --git a/src/main/java/vendingmachine/domain/Coin.java b/src/main/java/vendingmachine/domain/Coin.java new file mode 100644 index 000000000..94910110a --- /dev/null +++ b/src/main/java/vendingmachine/domain/Coin.java @@ -0,0 +1,31 @@ +package vendingmachine.domain; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +public enum Coin { + COIN_500(500), + COIN_100(100), + COIN_50(50), + COIN_10(10); + + private final int amount; + + Coin(final int amount) { + this.amount = amount; + } + + public static List getCoinKind() { + return Arrays.stream(Coin.values()) + .map(coin -> coin.amount) + .collect(Collectors.toList()); + } + + public static Coin getCoin(int value) { + return Arrays.stream(Coin.values()) + .filter(coin -> coin.amount == value) + .findAny() + .orElseThrow(() -> new IllegalArgumentException("")); + } +} diff --git a/src/main/java/vendingmachine/domain/Coins.java b/src/main/java/vendingmachine/domain/Coins.java new file mode 100644 index 000000000..9e1defdca --- /dev/null +++ b/src/main/java/vendingmachine/domain/Coins.java @@ -0,0 +1,30 @@ +package vendingmachine.domain; + +import camp.nextstep.edu.missionutils.Randoms; + +import java.util.EnumMap; +import java.util.Map; + +public class Coins { + + private static final int DEFAULT = 0; + private final Map elements; + + public Coins(int price) { + this.elements = new EnumMap<>(Coin.class); + Coin.getCoinKind() + .forEach(value -> elements.put(Coin.getCoin(value), DEFAULT)); + createRandomCoins(price); + } + + private void createRandomCoins(int price) { + while (price > 0) { + int value = Randoms.pickNumberInList(Coin.getCoinKind()); + if (value <= price) { + price -= value; + Coin coin = Coin.getCoin(value); + elements.put(coin, elements.get(coin)+1); + } + } + } +} From ca552489b6c98b76f55b6104295fecc096f9d6a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=97=B0=EC=A7=84?= Date: Thu, 21 Sep 2023 14:24:53 +0900 Subject: [PATCH 05/31] =?UTF-8?q?feat(Coins):=20=EC=9E=90=ED=8C=90?= =?UTF-8?q?=EA=B8=B0=EA=B0=80=20=EB=B3=B4=EC=9C=A0=ED=95=98=EA=B3=A0=20?= =?UTF-8?q?=EC=9E=88=EB=8A=94=20=EB=8F=99=EC=A0=84=20=EA=B0=9C=EC=88=98=20?= =?UTF-8?q?=EC=B6=9C=EB=A0=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 4 ++-- .../java/vendingmachine/constant/OutputMessage.java | 4 +++- src/main/java/vendingmachine/domain/Coin.java | 4 ++++ src/main/java/vendingmachine/domain/Coins.java | 12 ++++++++++++ src/main/java/vendingmachine/view/OutputView.java | 6 ++++++ 5 files changed, 27 insertions(+), 3 deletions(-) diff --git a/docs/README.md b/docs/README.md index 8021a5cce..81fcf18ea 100644 --- a/docs/README.md +++ b/docs/README.md @@ -2,8 +2,8 @@ - [x] 자판기 보유 금액을 입력한다. - [ ] 10원 단위로 나누어 떨어지지 않을 경우 예외 발생 -- [ ] 입력받은 보유 금액에 따라 동전 개수 랜덤 생성 -- [ ] 자판기가 보유하고 있는 동전의 개수를 출력한다. +- [x] 입력받은 보유 금액에 따라 동전 개수 랜덤 생성 +- [x] 자판기가 보유하고 있는 동전의 개수를 출력한다. - [ ] 자판기에 상품을 입력한다. - [ ] 상품의 가격이 100원이하일 경우 예외 - [ ] 상품의 가격이 10원 단위로 나누어 떨어지지 않을 경우 예외 diff --git a/src/main/java/vendingmachine/constant/OutputMessage.java b/src/main/java/vendingmachine/constant/OutputMessage.java index cc4ad96a1..ee9021e72 100644 --- a/src/main/java/vendingmachine/constant/OutputMessage.java +++ b/src/main/java/vendingmachine/constant/OutputMessage.java @@ -2,7 +2,9 @@ public enum OutputMessage { - READ_MACHINE_CHANGE("자판기가 보유하고 있는 금액을 입력해 주세요."); + READ_MACHINE_CHANGE("자판기가 보유하고 있는 금액을 입력해 주세요."), + CHANGE_MESSAGE("자판기가 보유한 동전"), + CHANGE("%d원 - %d개\n"); private final String message; diff --git a/src/main/java/vendingmachine/domain/Coin.java b/src/main/java/vendingmachine/domain/Coin.java index 94910110a..3a3dd1911 100644 --- a/src/main/java/vendingmachine/domain/Coin.java +++ b/src/main/java/vendingmachine/domain/Coin.java @@ -28,4 +28,8 @@ public static Coin getCoin(int value) { .findAny() .orElseThrow(() -> new IllegalArgumentException("")); } + + public int getPrice() { + return this.amount; + } } diff --git a/src/main/java/vendingmachine/domain/Coins.java b/src/main/java/vendingmachine/domain/Coins.java index 9e1defdca..a2d3186b4 100644 --- a/src/main/java/vendingmachine/domain/Coins.java +++ b/src/main/java/vendingmachine/domain/Coins.java @@ -1,6 +1,7 @@ package vendingmachine.domain; import camp.nextstep.edu.missionutils.Randoms; +import vendingmachine.constant.OutputMessage; import java.util.EnumMap; import java.util.Map; @@ -27,4 +28,15 @@ private void createRandomCoins(int price) { } } } + + public String getChangeCoins() { + StringBuilder sb = new StringBuilder(); + elements.keySet() + .forEach(value -> { + String message = OutputMessage.CHANGE.toString(); + sb.append(String.format(message, value.getPrice(), elements.get(value))); + } + ); + return sb.toString(); + } } diff --git a/src/main/java/vendingmachine/view/OutputView.java b/src/main/java/vendingmachine/view/OutputView.java index 7f602ca08..f5534c687 100644 --- a/src/main/java/vendingmachine/view/OutputView.java +++ b/src/main/java/vendingmachine/view/OutputView.java @@ -1,10 +1,16 @@ package vendingmachine.view; import vendingmachine.constant.OutputMessage; +import vendingmachine.domain.Coins; public class OutputView { public void printChangeMessage() { System.out.println(OutputMessage.READ_MACHINE_CHANGE); } + + public void printChange(Coins coins) { + System.out.println(OutputMessage.CHANGE_MESSAGE); + System.out.println(coins.getChangeCoins()); + } } From 9c6fe5f9c6e0eb37a4cb8d4d7631b394edec06d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=97=B0=EC=A7=84?= Date: Thu, 21 Sep 2023 14:26:39 +0900 Subject: [PATCH 06/31] =?UTF-8?q?feat(OutputView):=20=EC=83=81=ED=92=88=20?= =?UTF-8?q?=EC=9E=85=EB=A0=A5=20=EB=A9=94=EC=8B=9C=EC=A7=80=20=EC=B6=9C?= =?UTF-8?q?=EB=A0=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/vendingmachine/constant/OutputMessage.java | 3 ++- src/main/java/vendingmachine/view/OutputView.java | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/vendingmachine/constant/OutputMessage.java b/src/main/java/vendingmachine/constant/OutputMessage.java index ee9021e72..6778fd0f5 100644 --- a/src/main/java/vendingmachine/constant/OutputMessage.java +++ b/src/main/java/vendingmachine/constant/OutputMessage.java @@ -4,7 +4,8 @@ public enum OutputMessage { READ_MACHINE_CHANGE("자판기가 보유하고 있는 금액을 입력해 주세요."), CHANGE_MESSAGE("자판기가 보유한 동전"), - CHANGE("%d원 - %d개\n"); + CHANGE("%d원 - %d개\n"), + READ_PRODUCT("상품명과 가격, 수량을 입력해 주세요."); private final String message; diff --git a/src/main/java/vendingmachine/view/OutputView.java b/src/main/java/vendingmachine/view/OutputView.java index f5534c687..b9530d813 100644 --- a/src/main/java/vendingmachine/view/OutputView.java +++ b/src/main/java/vendingmachine/view/OutputView.java @@ -13,4 +13,8 @@ public void printChange(Coins coins) { System.out.println(OutputMessage.CHANGE_MESSAGE); System.out.println(coins.getChangeCoins()); } + + public void printProduct() { + System.out.println(OutputMessage.READ_PRODUCT); + } } From 768cf7bf0f2a63746cc6c5ca4a565c94afb3a7aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=97=B0=EC=A7=84?= Date: Thu, 21 Sep 2023 15:00:49 +0900 Subject: [PATCH 07/31] =?UTF-8?q?feat(InputView):=20=EC=83=81=ED=92=88=20?= =?UTF-8?q?=EC=9E=85=EB=A0=A5=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/vendingmachine/domain/Product.java | 36 +++++++++++++++++++ .../java/vendingmachine/view/InputView.java | 14 ++++++++ 2 files changed, 50 insertions(+) create mode 100644 src/main/java/vendingmachine/domain/Product.java diff --git a/src/main/java/vendingmachine/domain/Product.java b/src/main/java/vendingmachine/domain/Product.java new file mode 100644 index 000000000..c746c2733 --- /dev/null +++ b/src/main/java/vendingmachine/domain/Product.java @@ -0,0 +1,36 @@ +package vendingmachine.domain; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +public class Product { + + private static int NAME_INDEX = 0; + private static int PRICE_INDEX = 1; + private static int QUANTITY_INDEX = 2; + private static final String PRODUCT_REGEX = "^\\[|\\]$"; + private static final String PRODUCT_DELIMITER = ","; + private static final String BLANK = ""; + + private final String name; + private final int price; + private final int quantity; + + public Product(String message) { + List productInformation = parseString(message); + this.name = productInformation.get(NAME_INDEX); + this.price = Integer.parseInt(productInformation.get(PRICE_INDEX)); + this.quantity = Integer.parseInt(productInformation.get(QUANTITY_INDEX)); + } + + private List parseString(String message) { + String product = message.replaceAll(PRODUCT_REGEX, BLANK); + return Arrays.stream(product.split(PRODUCT_DELIMITER)).collect(Collectors.toList()); + } + + @Override + public String toString() { + return name + "\n" + price + "\n" + quantity; + } +} diff --git a/src/main/java/vendingmachine/view/InputView.java b/src/main/java/vendingmachine/view/InputView.java index e22a1832f..71e1c989f 100644 --- a/src/main/java/vendingmachine/view/InputView.java +++ b/src/main/java/vendingmachine/view/InputView.java @@ -1,10 +1,24 @@ package vendingmachine.view; import camp.nextstep.edu.missionutils.Console; +import vendingmachine.domain.Product; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; public class InputView { + private static final String PRODUCT_DELIMITER = ";"; + public int readChangePrice() { return Integer.parseInt(Console.readLine()); } + + public List readProducts() { + String input = Console.readLine(); + return Arrays.stream(input.split(PRODUCT_DELIMITER)) + .map(Product::new) + .collect(Collectors.toList()); + } } From 275bf4d5f47c7532eb71fa9b044e370367e829fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=97=B0=EC=A7=84?= Date: Thu, 21 Sep 2023 15:10:38 +0900 Subject: [PATCH 08/31] =?UTF-8?q?feat(Products):=20=EC=83=81=ED=92=88?= =?UTF-8?q?=EB=93=A4=EC=9D=84=20=EA=B4=80=EB=A6=AC=ED=95=98=EB=8A=94=20?= =?UTF-8?q?=EA=B0=9D=EC=B2=B4=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 2 +- src/main/java/vendingmachine/domain/Products.java | 13 +++++++++++++ src/main/java/vendingmachine/view/InputView.java | 8 ++++---- 3 files changed, 18 insertions(+), 5 deletions(-) create mode 100644 src/main/java/vendingmachine/domain/Products.java diff --git a/docs/README.md b/docs/README.md index 81fcf18ea..698ca30d9 100644 --- a/docs/README.md +++ b/docs/README.md @@ -4,7 +4,7 @@ - [ ] 10원 단위로 나누어 떨어지지 않을 경우 예외 발생 - [x] 입력받은 보유 금액에 따라 동전 개수 랜덤 생성 - [x] 자판기가 보유하고 있는 동전의 개수를 출력한다. -- [ ] 자판기에 상품을 입력한다. +- [x] 자판기에 상품을 입력한다. - [ ] 상품의 가격이 100원이하일 경우 예외 - [ ] 상품의 가격이 10원 단위로 나누어 떨어지지 않을 경우 예외 - [ ] 사용자가 투입할 금액을 입력한다. diff --git a/src/main/java/vendingmachine/domain/Products.java b/src/main/java/vendingmachine/domain/Products.java new file mode 100644 index 000000000..e524283ee --- /dev/null +++ b/src/main/java/vendingmachine/domain/Products.java @@ -0,0 +1,13 @@ +package vendingmachine.domain; + +import java.util.ArrayList; +import java.util.List; + +public class Products { + + private final List elements; + + public Products(List elements) { + this.elements = new ArrayList<>(elements); + } +} diff --git a/src/main/java/vendingmachine/view/InputView.java b/src/main/java/vendingmachine/view/InputView.java index 71e1c989f..64b790f64 100644 --- a/src/main/java/vendingmachine/view/InputView.java +++ b/src/main/java/vendingmachine/view/InputView.java @@ -2,9 +2,9 @@ import camp.nextstep.edu.missionutils.Console; import vendingmachine.domain.Product; +import vendingmachine.domain.Products; import java.util.Arrays; -import java.util.List; import java.util.stream.Collectors; public class InputView { @@ -15,10 +15,10 @@ public int readChangePrice() { return Integer.parseInt(Console.readLine()); } - public List readProducts() { + public Products readProducts() { String input = Console.readLine(); - return Arrays.stream(input.split(PRODUCT_DELIMITER)) + return new Products(Arrays.stream(input.split(PRODUCT_DELIMITER)) .map(Product::new) - .collect(Collectors.toList()); + .collect(Collectors.toList())); } } From eb4ed3dd2d48ae5f9f025d6993b4bfbf484f9a3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=97=B0=EC=A7=84?= Date: Thu, 21 Sep 2023 15:12:42 +0900 Subject: [PATCH 09/31] =?UTF-8?q?feat(OutputView):=20=ED=88=AC=EC=9E=85=20?= =?UTF-8?q?=EA=B8=88=EC=95=A1=20=EC=9E=85=EB=A0=A5=20=EC=95=88=EB=82=B4=20?= =?UTF-8?q?=EB=A9=94=EC=8B=9C=EC=A7=80=20=EC=B6=9C=EB=A0=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/vendingmachine/constant/OutputMessage.java | 3 ++- src/main/java/vendingmachine/view/OutputView.java | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/vendingmachine/constant/OutputMessage.java b/src/main/java/vendingmachine/constant/OutputMessage.java index 6778fd0f5..e95b43854 100644 --- a/src/main/java/vendingmachine/constant/OutputMessage.java +++ b/src/main/java/vendingmachine/constant/OutputMessage.java @@ -5,7 +5,8 @@ public enum OutputMessage { READ_MACHINE_CHANGE("자판기가 보유하고 있는 금액을 입력해 주세요."), CHANGE_MESSAGE("자판기가 보유한 동전"), CHANGE("%d원 - %d개\n"), - READ_PRODUCT("상품명과 가격, 수량을 입력해 주세요."); + READ_PRODUCT("상품명과 가격, 수량을 입력해 주세요."), + READ_INPUT_AMOUNT("투입 금액을 입력해 주세요."); private final String message; diff --git a/src/main/java/vendingmachine/view/OutputView.java b/src/main/java/vendingmachine/view/OutputView.java index b9530d813..aa42211d4 100644 --- a/src/main/java/vendingmachine/view/OutputView.java +++ b/src/main/java/vendingmachine/view/OutputView.java @@ -17,4 +17,8 @@ public void printChange(Coins coins) { public void printProduct() { System.out.println(OutputMessage.READ_PRODUCT); } + + public void printInputAmount() { + System.out.println(OutputMessage.READ_INPUT_AMOUNT); + } } From 901c05637f3bb3ee50e7825df10c47c154d613ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=97=B0=EC=A7=84?= Date: Thu, 21 Sep 2023 15:14:06 +0900 Subject: [PATCH 10/31] =?UTF-8?q?feat(InputView):=20=ED=88=AC=EC=9E=85=20?= =?UTF-8?q?=EA=B8=88=EC=95=A1=20=EC=9E=85=EB=A0=A5=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 2 +- src/main/java/vendingmachine/view/InputView.java | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index 698ca30d9..ef56eeb48 100644 --- a/docs/README.md +++ b/docs/README.md @@ -7,7 +7,7 @@ - [x] 자판기에 상품을 입력한다. - [ ] 상품의 가격이 100원이하일 경우 예외 - [ ] 상품의 가격이 10원 단위로 나누어 떨어지지 않을 경우 예외 -- [ ] 사용자가 투입할 금액을 입력한다. +- [x] 사용자가 투입할 금액을 입력한다. - [ ] 구매할 상품명 입력 - [ ] 해당 상품이 존재하지 않을 경우 예외 - [ ] 상품 구매 diff --git a/src/main/java/vendingmachine/view/InputView.java b/src/main/java/vendingmachine/view/InputView.java index 64b790f64..47897e4fe 100644 --- a/src/main/java/vendingmachine/view/InputView.java +++ b/src/main/java/vendingmachine/view/InputView.java @@ -21,4 +21,8 @@ public Products readProducts() { .map(Product::new) .collect(Collectors.toList())); } + + public int readInputAmount() { + return Integer.parseInt(Console.readLine()); + } } From b01eb7fc9a6cf94dd12057ad1988ad2b828dc756 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=97=B0=EC=A7=84?= Date: Thu, 21 Sep 2023 15:24:25 +0900 Subject: [PATCH 11/31] =?UTF-8?q?feat(MachineController):=20=EA=B2=8C?= =?UTF-8?q?=EC=9E=84=20=EC=A7=84=ED=96=89=20=EB=A9=94=EC=84=9C=EB=93=9C=20?= =?UTF-8?q?=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/MachineController.java | 22 ++++++++++++++++--- .../java/vendingmachine/domain/Money.java | 11 ++++++++++ .../service/MachineService.java | 18 +++++++++++++++ .../java/vendingmachine/view/InputView.java | 12 ++++++---- 4 files changed, 56 insertions(+), 7 deletions(-) create mode 100644 src/main/java/vendingmachine/domain/Money.java create mode 100644 src/main/java/vendingmachine/service/MachineService.java diff --git a/src/main/java/vendingmachine/controller/MachineController.java b/src/main/java/vendingmachine/controller/MachineController.java index 826a9b791..6e3859964 100644 --- a/src/main/java/vendingmachine/controller/MachineController.java +++ b/src/main/java/vendingmachine/controller/MachineController.java @@ -1,6 +1,9 @@ package vendingmachine.controller; import vendingmachine.domain.Coins; +import vendingmachine.domain.Money; +import vendingmachine.domain.Products; +import vendingmachine.service.MachineService; import vendingmachine.view.InputView; import vendingmachine.view.OutputView; @@ -8,13 +11,26 @@ public class MachineController { private final InputView inputView = new InputView(); private final OutputView outputView = new OutputView(); + private MachineService service; public void start() { - new Coins(readChangePrice()); + service = new MachineService(readChangePrice(), readProducts(), readMoney()); } - public int readChangePrice() { + private Coins readChangePrice() { outputView.printChangeMessage(); - return inputView.readChangePrice(); + Coins coins = inputView.readChangePrice(); + outputView.printChange(coins); + return coins; + } + + private Products readProducts() { + outputView.printProduct(); + return inputView.readProducts(); + } + + private Money readMoney() { + outputView.printInputAmount(); + return inputView.readInputAmount(); } } diff --git a/src/main/java/vendingmachine/domain/Money.java b/src/main/java/vendingmachine/domain/Money.java new file mode 100644 index 000000000..3e45f7baf --- /dev/null +++ b/src/main/java/vendingmachine/domain/Money.java @@ -0,0 +1,11 @@ +package vendingmachine.domain; + +public class Money { + + private int value; + + + public Money(int value) { + this.value = value; + } +} diff --git a/src/main/java/vendingmachine/service/MachineService.java b/src/main/java/vendingmachine/service/MachineService.java new file mode 100644 index 000000000..ea3e6acd2 --- /dev/null +++ b/src/main/java/vendingmachine/service/MachineService.java @@ -0,0 +1,18 @@ +package vendingmachine.service; + +import vendingmachine.domain.Coins; +import vendingmachine.domain.Money; +import vendingmachine.domain.Products; + +public class MachineService { + + private final Coins coins; + private final Products products; + private final Money money; + + public MachineService(Coins coins, Products products, Money money) { + this.coins = coins; + this.products = products; + this.money = money; + } +} diff --git a/src/main/java/vendingmachine/view/InputView.java b/src/main/java/vendingmachine/view/InputView.java index 47897e4fe..35553b3e4 100644 --- a/src/main/java/vendingmachine/view/InputView.java +++ b/src/main/java/vendingmachine/view/InputView.java @@ -1,6 +1,8 @@ package vendingmachine.view; import camp.nextstep.edu.missionutils.Console; +import vendingmachine.domain.Coins; +import vendingmachine.domain.Money; import vendingmachine.domain.Product; import vendingmachine.domain.Products; @@ -11,8 +13,9 @@ public class InputView { private static final String PRODUCT_DELIMITER = ";"; - public int readChangePrice() { - return Integer.parseInt(Console.readLine()); + public Coins readChangePrice() { + int input = Integer.parseInt(Console.readLine()); + return new Coins(input); } public Products readProducts() { @@ -22,7 +25,8 @@ public Products readProducts() { .collect(Collectors.toList())); } - public int readInputAmount() { - return Integer.parseInt(Console.readLine()); + public Money readInputAmount() { + int input = Integer.parseInt(Console.readLine()); + return new Money(input); } } From cfc210884b60c677e02c7e3c970c6d3921ca6c37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=97=B0=EC=A7=84?= Date: Thu, 21 Sep 2023 15:29:19 +0900 Subject: [PATCH 12/31] =?UTF-8?q?feat(Money):=20=ED=88=AC=EC=9E=85=20?= =?UTF-8?q?=EA=B8=88=EC=95=A1=20=EC=B6=9C=EB=A0=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/vendingmachine/constant/OutputMessage.java | 3 ++- src/main/java/vendingmachine/domain/Money.java | 7 ++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/main/java/vendingmachine/constant/OutputMessage.java b/src/main/java/vendingmachine/constant/OutputMessage.java index e95b43854..5f6bf17e3 100644 --- a/src/main/java/vendingmachine/constant/OutputMessage.java +++ b/src/main/java/vendingmachine/constant/OutputMessage.java @@ -6,7 +6,8 @@ public enum OutputMessage { CHANGE_MESSAGE("자판기가 보유한 동전"), CHANGE("%d원 - %d개\n"), READ_PRODUCT("상품명과 가격, 수량을 입력해 주세요."), - READ_INPUT_AMOUNT("투입 금액을 입력해 주세요."); + READ_INPUT_AMOUNT("투입 금액을 입력해 주세요."), + INPUT_AMOUNT("투입 금액: %d원"); private final String message; diff --git a/src/main/java/vendingmachine/domain/Money.java b/src/main/java/vendingmachine/domain/Money.java index 3e45f7baf..52e7e6a74 100644 --- a/src/main/java/vendingmachine/domain/Money.java +++ b/src/main/java/vendingmachine/domain/Money.java @@ -1,11 +1,16 @@ package vendingmachine.domain; +import vendingmachine.constant.OutputMessage; + public class Money { private int value; - public Money(int value) { this.value = value; } + + public String getInputAmount() { + return String.format(OutputMessage.INPUT_AMOUNT.toString() , value); + } } From b2b3ddc5b37873f5fe8c31bbc6deae2dd0fd1a67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=97=B0=EC=A7=84?= Date: Thu, 21 Sep 2023 15:33:58 +0900 Subject: [PATCH 13/31] =?UTF-8?q?feat(OutputView):=20=EC=83=81=ED=92=88=20?= =?UTF-8?q?=EA=B5=AC=EB=A7=A4=20=EB=A9=94=EC=84=B8=EC=A7=80=20=EC=B6=9C?= =?UTF-8?q?=EB=A0=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/vendingmachine/constant/OutputMessage.java | 3 ++- .../vendingmachine/controller/MachineController.java | 8 +++++++- .../java/vendingmachine/service/MachineService.java | 4 ++++ src/main/java/vendingmachine/view/OutputView.java | 11 ++++++++++- 4 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/main/java/vendingmachine/constant/OutputMessage.java b/src/main/java/vendingmachine/constant/OutputMessage.java index 5f6bf17e3..88e42574c 100644 --- a/src/main/java/vendingmachine/constant/OutputMessage.java +++ b/src/main/java/vendingmachine/constant/OutputMessage.java @@ -7,7 +7,8 @@ public enum OutputMessage { CHANGE("%d원 - %d개\n"), READ_PRODUCT("상품명과 가격, 수량을 입력해 주세요."), READ_INPUT_AMOUNT("투입 금액을 입력해 주세요."), - INPUT_AMOUNT("투입 금액: %d원"); + INPUT_AMOUNT("투입 금액: %d원"), + PURCHASE_GOODS("구매할 상품명을 입력해 주세요."); private final String message; diff --git a/src/main/java/vendingmachine/controller/MachineController.java b/src/main/java/vendingmachine/controller/MachineController.java index 6e3859964..48b1dd1e8 100644 --- a/src/main/java/vendingmachine/controller/MachineController.java +++ b/src/main/java/vendingmachine/controller/MachineController.java @@ -15,6 +15,7 @@ public class MachineController { public void start() { service = new MachineService(readChangePrice(), readProducts(), readMoney()); + purchaseGoods(); } private Coins readChangePrice() { @@ -30,7 +31,12 @@ private Products readProducts() { } private Money readMoney() { - outputView.printInputAmount(); + outputView.printInputAmountMessage(); return inputView.readInputAmount(); } + + private void purchaseGoods() { + outputView.printInputAmount(service.getMoney()); + outputView.printPurchaseGoods(); + } } diff --git a/src/main/java/vendingmachine/service/MachineService.java b/src/main/java/vendingmachine/service/MachineService.java index ea3e6acd2..48f1eaf99 100644 --- a/src/main/java/vendingmachine/service/MachineService.java +++ b/src/main/java/vendingmachine/service/MachineService.java @@ -15,4 +15,8 @@ public MachineService(Coins coins, Products products, Money money) { this.products = products; this.money = money; } + + public Money getMoney() { + return money; + } } diff --git a/src/main/java/vendingmachine/view/OutputView.java b/src/main/java/vendingmachine/view/OutputView.java index aa42211d4..485219fb3 100644 --- a/src/main/java/vendingmachine/view/OutputView.java +++ b/src/main/java/vendingmachine/view/OutputView.java @@ -2,6 +2,7 @@ import vendingmachine.constant.OutputMessage; import vendingmachine.domain.Coins; +import vendingmachine.domain.Money; public class OutputView { @@ -18,7 +19,15 @@ public void printProduct() { System.out.println(OutputMessage.READ_PRODUCT); } - public void printInputAmount() { + public void printInputAmountMessage() { System.out.println(OutputMessage.READ_INPUT_AMOUNT); } + + public void printInputAmount(Money money){ + System.out.println(money.getInputAmount()); + } + + public void printPurchaseGoods() { + System.out.println(OutputMessage.PURCHASE_GOODS); + } } From b8c28670fcb99c7e1d32e3958a1fe973b4023eb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=97=B0=EC=A7=84?= Date: Thu, 21 Sep 2023 15:50:23 +0900 Subject: [PATCH 14/31] =?UTF-8?q?feat(InputView):=20=EA=B5=AC=EB=A7=A4?= =?UTF-8?q?=ED=95=A0=20=EC=83=81=ED=92=88=EB=AA=85=20=EC=9E=85=EB=A0=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 2 +- src/main/java/vendingmachine/view/InputView.java | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index ef56eeb48..bc6dd90de 100644 --- a/docs/README.md +++ b/docs/README.md @@ -8,7 +8,7 @@ - [ ] 상품의 가격이 100원이하일 경우 예외 - [ ] 상품의 가격이 10원 단위로 나누어 떨어지지 않을 경우 예외 - [x] 사용자가 투입할 금액을 입력한다. -- [ ] 구매할 상품명 입력 +- [x] 구매할 상품명 입력 - [ ] 해당 상품이 존재하지 않을 경우 예외 - [ ] 상품 구매 - [ ] 금액 계산 diff --git a/src/main/java/vendingmachine/view/InputView.java b/src/main/java/vendingmachine/view/InputView.java index 35553b3e4..650040d8f 100644 --- a/src/main/java/vendingmachine/view/InputView.java +++ b/src/main/java/vendingmachine/view/InputView.java @@ -29,4 +29,8 @@ public Money readInputAmount() { int input = Integer.parseInt(Console.readLine()); return new Money(input); } + + public String readProduct() { + return Console.readLine(); + } } From ce0ec1ef348a613c9669c44c5ffc8db05702cf19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=97=B0=EC=A7=84?= Date: Thu, 21 Sep 2023 15:58:57 +0900 Subject: [PATCH 15/31] =?UTF-8?q?feat(Products):=20=EC=9E=85=EB=A0=A5?= =?UTF-8?q?=EB=B0=9B=EC=9D=80=20=EC=83=81=ED=92=88=EC=9D=B4=20=EC=9E=88?= =?UTF-8?q?=EB=8A=94=EC=A7=80=20=ED=99=95=EC=9D=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 3 ++- .../constant/ExceptionMessage.java | 19 +++++++++++++++++++ .../java/vendingmachine/domain/Product.java | 10 +++++++--- .../java/vendingmachine/domain/Products.java | 9 +++++++++ 4 files changed, 37 insertions(+), 4 deletions(-) create mode 100644 src/main/java/vendingmachine/constant/ExceptionMessage.java diff --git a/docs/README.md b/docs/README.md index bc6dd90de..1aab59acb 100644 --- a/docs/README.md +++ b/docs/README.md @@ -9,8 +9,9 @@ - [ ] 상품의 가격이 10원 단위로 나누어 떨어지지 않을 경우 예외 - [x] 사용자가 투입할 금액을 입력한다. - [x] 구매할 상품명 입력 - - [ ] 해당 상품이 존재하지 않을 경우 예외 + - [x] 해당 상품이 존재하지 않을 경우 예외 - [ ] 상품 구매 + - [x] 입력받은 상품이 있는지 확인 - [ ] 금액 계산 - [ ] 넣은 금액이 상품의 가격보다 작은 경우 예외 발생 - [ ] 상품 개수 하나 줄이기 diff --git a/src/main/java/vendingmachine/constant/ExceptionMessage.java b/src/main/java/vendingmachine/constant/ExceptionMessage.java new file mode 100644 index 000000000..9e573f411 --- /dev/null +++ b/src/main/java/vendingmachine/constant/ExceptionMessage.java @@ -0,0 +1,19 @@ +package vendingmachine.constant; + + +public enum ExceptionMessage { + + NOT_EXIST_PRODUCT("존재하지 않는 상품입니다."); + + private static final String PREFIX = "[ERROR] "; + private final String message; + + ExceptionMessage(String message) { + this.message = message; + } + + @Override + public String toString() { + return PREFIX + message; + } +} \ No newline at end of file diff --git a/src/main/java/vendingmachine/domain/Product.java b/src/main/java/vendingmachine/domain/Product.java index c746c2733..159ee3975 100644 --- a/src/main/java/vendingmachine/domain/Product.java +++ b/src/main/java/vendingmachine/domain/Product.java @@ -6,9 +6,9 @@ public class Product { - private static int NAME_INDEX = 0; - private static int PRICE_INDEX = 1; - private static int QUANTITY_INDEX = 2; + private static final int NAME_INDEX = 0; + private static final int PRICE_INDEX = 1; + private static final int QUANTITY_INDEX = 2; private static final String PRODUCT_REGEX = "^\\[|\\]$"; private static final String PRODUCT_DELIMITER = ","; private static final String BLANK = ""; @@ -29,6 +29,10 @@ private List parseString(String message) { return Arrays.stream(product.split(PRODUCT_DELIMITER)).collect(Collectors.toList()); } + public boolean isSameName(String name) { + return this.name.equals(name); + } + @Override public String toString() { return name + "\n" + price + "\n" + quantity; diff --git a/src/main/java/vendingmachine/domain/Products.java b/src/main/java/vendingmachine/domain/Products.java index e524283ee..03fa7031b 100644 --- a/src/main/java/vendingmachine/domain/Products.java +++ b/src/main/java/vendingmachine/domain/Products.java @@ -1,5 +1,7 @@ package vendingmachine.domain; +import vendingmachine.constant.ExceptionMessage; + import java.util.ArrayList; import java.util.List; @@ -10,4 +12,11 @@ public class Products { public Products(List elements) { this.elements = new ArrayList<>(elements); } + + public Product findByProductName(String name) { + return elements.stream() + .filter(value -> value.isSameName(name)) + .findAny() + .orElseThrow(() -> new IllegalArgumentException(ExceptionMessage.NOT_EXIST_PRODUCT.toString())); + } } From ec0389764a0bda275b31220f345a13b611d3e8b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=97=B0=EC=A7=84?= Date: Thu, 21 Sep 2023 16:04:36 +0900 Subject: [PATCH 16/31] =?UTF-8?q?feat(Product):=20=EC=83=81=ED=92=88=20?= =?UTF-8?q?=EA=B5=AC=EB=A7=A4=EC=8B=9C=20=EA=B5=AC=EB=A7=A4=ED=95=9C=20?= =?UTF-8?q?=EC=96=91=EB=A7=8C=ED=81=BC=20=EA=B0=9C=EC=88=98=20=EC=B0=A8?= =?UTF-8?q?=EA=B0=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 2 +- src/main/java/vendingmachine/domain/Product.java | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/docs/README.md b/docs/README.md index 1aab59acb..ad72eceb7 100644 --- a/docs/README.md +++ b/docs/README.md @@ -14,6 +14,6 @@ - [x] 입력받은 상품이 있는지 확인 - [ ] 금액 계산 - [ ] 넣은 금액이 상품의 가격보다 작은 경우 예외 발생 - - [ ] 상품 개수 하나 줄이기 + - [x] 상품 개수 하나 줄이기 - [ ] 남은 금액이 상품의 최저 가격보다 적거나, 모든 상품이 소진된 경우 종료 - [ ] 잔돈 출력 \ No newline at end of file diff --git a/src/main/java/vendingmachine/domain/Product.java b/src/main/java/vendingmachine/domain/Product.java index 159ee3975..da7f51292 100644 --- a/src/main/java/vendingmachine/domain/Product.java +++ b/src/main/java/vendingmachine/domain/Product.java @@ -12,10 +12,11 @@ public class Product { private static final String PRODUCT_REGEX = "^\\[|\\]$"; private static final String PRODUCT_DELIMITER = ","; private static final String BLANK = ""; + private static final int PURCHASE_QUANTITY = 1; private final String name; private final int price; - private final int quantity; + private int quantity; public Product(String message) { List productInformation = parseString(message); @@ -33,6 +34,10 @@ public boolean isSameName(String name) { return this.name.equals(name); } + public void purchase() { + this.quantity -= PURCHASE_QUANTITY; + } + @Override public String toString() { return name + "\n" + price + "\n" + quantity; From 6a3434a546bc2e6961d019a121990672c729cb2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=97=B0=EC=A7=84?= Date: Thu, 21 Sep 2023 16:07:46 +0900 Subject: [PATCH 17/31] =?UTF-8?q?feat(Money):=20=EC=83=81=ED=92=88=20?= =?UTF-8?q?=EA=B3=84=EC=82=B0=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 2 +- src/main/java/vendingmachine/domain/Money.java | 4 ++++ src/main/java/vendingmachine/domain/Product.java | 4 ++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index ad72eceb7..e4a429b4c 100644 --- a/docs/README.md +++ b/docs/README.md @@ -12,7 +12,7 @@ - [x] 해당 상품이 존재하지 않을 경우 예외 - [ ] 상품 구매 - [x] 입력받은 상품이 있는지 확인 - - [ ] 금액 계산 + - [x] 금액 계산 - [ ] 넣은 금액이 상품의 가격보다 작은 경우 예외 발생 - [x] 상품 개수 하나 줄이기 - [ ] 남은 금액이 상품의 최저 가격보다 적거나, 모든 상품이 소진된 경우 종료 diff --git a/src/main/java/vendingmachine/domain/Money.java b/src/main/java/vendingmachine/domain/Money.java index 52e7e6a74..3ca73a575 100644 --- a/src/main/java/vendingmachine/domain/Money.java +++ b/src/main/java/vendingmachine/domain/Money.java @@ -10,6 +10,10 @@ public Money(int value) { this.value = value; } + public void pay(int price) { + value -= price; + } + public String getInputAmount() { return String.format(OutputMessage.INPUT_AMOUNT.toString() , value); } diff --git a/src/main/java/vendingmachine/domain/Product.java b/src/main/java/vendingmachine/domain/Product.java index da7f51292..1a297b885 100644 --- a/src/main/java/vendingmachine/domain/Product.java +++ b/src/main/java/vendingmachine/domain/Product.java @@ -38,6 +38,10 @@ public void purchase() { this.quantity -= PURCHASE_QUANTITY; } + public int getPrice() { + return price; + } + @Override public String toString() { return name + "\n" + price + "\n" + quantity; From 552b5081219749ced88a3e7ce469f9109ce8272f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=97=B0=EC=A7=84?= Date: Thu, 21 Sep 2023 16:13:01 +0900 Subject: [PATCH 18/31] =?UTF-8?q?feat(Money):=20=EB=B3=B4=EC=9C=A0?= =?UTF-8?q?=ED=95=9C=20=EA=B8=88=EC=95=A1=EC=9D=B4=20=EC=83=81=ED=92=88?= =?UTF-8?q?=EC=9D=98=20=EA=B0=80=EA=B2=A9=EB=B3=B4=EB=8B=A4=20=EC=9E=91?= =?UTF-8?q?=EC=9D=80=20=EA=B2=BD=EC=9A=B0=20=EC=98=88=EC=99=B8=20=EB=B0=9C?= =?UTF-8?q?=EC=83=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 2 +- .../java/vendingmachine/constant/ExceptionMessage.java | 3 ++- src/main/java/vendingmachine/domain/Money.java | 8 ++++++++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/docs/README.md b/docs/README.md index e4a429b4c..762b3eaac 100644 --- a/docs/README.md +++ b/docs/README.md @@ -13,7 +13,7 @@ - [ ] 상품 구매 - [x] 입력받은 상품이 있는지 확인 - [x] 금액 계산 - - [ ] 넣은 금액이 상품의 가격보다 작은 경우 예외 발생 + - [x] 보유한 금액이 상품의 가격보다 작은 경우 예외 발생 - [x] 상품 개수 하나 줄이기 - [ ] 남은 금액이 상품의 최저 가격보다 적거나, 모든 상품이 소진된 경우 종료 - [ ] 잔돈 출력 \ No newline at end of file diff --git a/src/main/java/vendingmachine/constant/ExceptionMessage.java b/src/main/java/vendingmachine/constant/ExceptionMessage.java index 9e573f411..2c29e702e 100644 --- a/src/main/java/vendingmachine/constant/ExceptionMessage.java +++ b/src/main/java/vendingmachine/constant/ExceptionMessage.java @@ -3,7 +3,8 @@ public enum ExceptionMessage { - NOT_EXIST_PRODUCT("존재하지 않는 상품입니다."); + NOT_EXIST_PRODUCT("존재하지 않는 상품입니다."), + NOT_ENOUGH_MONEY("보유한 금액이 부족해 상품을 구매할 수 없습니다."); private static final String PREFIX = "[ERROR] "; private final String message; diff --git a/src/main/java/vendingmachine/domain/Money.java b/src/main/java/vendingmachine/domain/Money.java index 3ca73a575..0cb97c84a 100644 --- a/src/main/java/vendingmachine/domain/Money.java +++ b/src/main/java/vendingmachine/domain/Money.java @@ -1,5 +1,6 @@ package vendingmachine.domain; +import vendingmachine.constant.ExceptionMessage; import vendingmachine.constant.OutputMessage; public class Money { @@ -11,9 +12,16 @@ public Money(int value) { } public void pay(int price) { + validateLeftMoney(price); value -= price; } + public void validateLeftMoney(int price) { + if (price > value) { + throw new IllegalArgumentException(ExceptionMessage.NOT_ENOUGH_MONEY.toString()); + } + } + public String getInputAmount() { return String.format(OutputMessage.INPUT_AMOUNT.toString() , value); } From f45d11a6d5366c90343982b829f7686f69ab164f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=97=B0=EC=A7=84?= Date: Thu, 21 Sep 2023 16:15:58 +0900 Subject: [PATCH 19/31] =?UTF-8?q?feat(MachineService):=20=EC=83=81?= =?UTF-8?q?=ED=92=88=20=EA=B5=AC=EB=A7=A4=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/vendingmachine/controller/MachineController.java | 1 + src/main/java/vendingmachine/service/MachineService.java | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/src/main/java/vendingmachine/controller/MachineController.java b/src/main/java/vendingmachine/controller/MachineController.java index 48b1dd1e8..f5948a155 100644 --- a/src/main/java/vendingmachine/controller/MachineController.java +++ b/src/main/java/vendingmachine/controller/MachineController.java @@ -38,5 +38,6 @@ private Money readMoney() { private void purchaseGoods() { outputView.printInputAmount(service.getMoney()); outputView.printPurchaseGoods(); + service.purchaseProduct(inputView.readProduct()); } } diff --git a/src/main/java/vendingmachine/service/MachineService.java b/src/main/java/vendingmachine/service/MachineService.java index 48f1eaf99..9802adc8e 100644 --- a/src/main/java/vendingmachine/service/MachineService.java +++ b/src/main/java/vendingmachine/service/MachineService.java @@ -2,6 +2,7 @@ import vendingmachine.domain.Coins; import vendingmachine.domain.Money; +import vendingmachine.domain.Product; import vendingmachine.domain.Products; public class MachineService { @@ -16,6 +17,12 @@ public MachineService(Coins coins, Products products, Money money) { this.money = money; } + public void purchaseProduct(String name) { + Product product = products.findByProductName(name); + money.pay(product.getPrice()); + product.purchase(); + } + public Money getMoney() { return money; } From 86be7f1ea856497b5e86001b7774f21f7c934139 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=97=B0=EC=A7=84?= Date: Thu, 21 Sep 2023 16:39:43 +0900 Subject: [PATCH 20/31] =?UTF-8?q?feat(MachineService):=20=EB=82=A8?= =?UTF-8?q?=EC=9D=80=20=EA=B8=88=EC=95=A1=EC=9D=B4=20=EC=83=81=ED=92=88?= =?UTF-8?q?=EC=9D=98=20=EC=B5=9C=EC=A0=80=20=EA=B0=80=EA=B2=A9=EB=B3=B4?= =?UTF-8?q?=EB=8B=A4=20=EC=A0=81=EA=B1=B0=EB=82=98,=20=EB=AA=A8=EB=93=A0?= =?UTF-8?q?=20=EC=83=81=ED=92=88=EC=9D=B4=20=EC=86=8C=EC=A7=84=EB=90=9C=20?= =?UTF-8?q?=EA=B2=BD=EC=9A=B0=20=EC=A2=85=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 2 +- .../controller/MachineController.java | 4 +++- src/main/java/vendingmachine/domain/Money.java | 4 ++++ src/main/java/vendingmachine/domain/Product.java | 5 ++++- src/main/java/vendingmachine/domain/Products.java | 13 +++++++++++++ .../java/vendingmachine/service/MachineService.java | 4 ++++ 6 files changed, 29 insertions(+), 3 deletions(-) diff --git a/docs/README.md b/docs/README.md index 762b3eaac..3ed0e57d3 100644 --- a/docs/README.md +++ b/docs/README.md @@ -15,5 +15,5 @@ - [x] 금액 계산 - [x] 보유한 금액이 상품의 가격보다 작은 경우 예외 발생 - [x] 상품 개수 하나 줄이기 -- [ ] 남은 금액이 상품의 최저 가격보다 적거나, 모든 상품이 소진된 경우 종료 +- [x] 남은 금액이 상품의 최저 가격보다 적거나, 모든 상품이 소진된 경우 종료 - [ ] 잔돈 출력 \ No newline at end of file diff --git a/src/main/java/vendingmachine/controller/MachineController.java b/src/main/java/vendingmachine/controller/MachineController.java index f5948a155..baab015e5 100644 --- a/src/main/java/vendingmachine/controller/MachineController.java +++ b/src/main/java/vendingmachine/controller/MachineController.java @@ -15,7 +15,9 @@ public class MachineController { public void start() { service = new MachineService(readChangePrice(), readProducts(), readMoney()); - purchaseGoods(); + while (service.isOnSale()) { + purchaseGoods(); + } } private Coins readChangePrice() { diff --git a/src/main/java/vendingmachine/domain/Money.java b/src/main/java/vendingmachine/domain/Money.java index 0cb97c84a..20b955221 100644 --- a/src/main/java/vendingmachine/domain/Money.java +++ b/src/main/java/vendingmachine/domain/Money.java @@ -22,6 +22,10 @@ public void validateLeftMoney(int price) { } } + public boolean isEnoughMoney(int minPrice) { + return value >= minPrice; + } + public String getInputAmount() { return String.format(OutputMessage.INPUT_AMOUNT.toString() , value); } diff --git a/src/main/java/vendingmachine/domain/Product.java b/src/main/java/vendingmachine/domain/Product.java index 1a297b885..1c21ee4d9 100644 --- a/src/main/java/vendingmachine/domain/Product.java +++ b/src/main/java/vendingmachine/domain/Product.java @@ -38,10 +38,13 @@ public void purchase() { this.quantity -= PURCHASE_QUANTITY; } + public boolean isExist() { + return quantity >= PURCHASE_QUANTITY; + } + public int getPrice() { return price; } - @Override public String toString() { return name + "\n" + price + "\n" + quantity; diff --git a/src/main/java/vendingmachine/domain/Products.java b/src/main/java/vendingmachine/domain/Products.java index 03fa7031b..724fdc32a 100644 --- a/src/main/java/vendingmachine/domain/Products.java +++ b/src/main/java/vendingmachine/domain/Products.java @@ -19,4 +19,17 @@ public Product findByProductName(String name) { .findAny() .orElseThrow(() -> new IllegalArgumentException(ExceptionMessage.NOT_EXIST_PRODUCT.toString())); } + + public boolean isExistProduct() { + return elements.stream() + .anyMatch(Product::isExist); + } + + public int getMinPrice() { + return elements.stream() + .filter(Product::isExist) + .mapToInt(Product::getPrice) + .min() + .orElseThrow(() -> new IllegalArgumentException("")); + } } diff --git a/src/main/java/vendingmachine/service/MachineService.java b/src/main/java/vendingmachine/service/MachineService.java index 9802adc8e..d0a0f8118 100644 --- a/src/main/java/vendingmachine/service/MachineService.java +++ b/src/main/java/vendingmachine/service/MachineService.java @@ -23,6 +23,10 @@ public void purchaseProduct(String name) { product.purchase(); } + public boolean isOnSale() { + return products.isExistProduct() && money.isEnoughMoney(products.getMinPrice()); + } + public Money getMoney() { return money; } From 856590290b97a2395af85b6dbfd8c4170f4aab5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=97=B0=EC=A7=84?= Date: Thu, 21 Sep 2023 17:25:18 +0900 Subject: [PATCH 21/31] =?UTF-8?q?feat:=20=EC=9E=94=EB=8F=88=20=EC=B6=9C?= =?UTF-8?q?=EB=A0=A5=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 2 +- .../controller/MachineController.java | 1 + src/main/java/vendingmachine/domain/Coin.java | 2 + .../java/vendingmachine/domain/Coins.java | 48 ++++++++++++++++++- .../java/vendingmachine/domain/Money.java | 4 ++ .../service/MachineService.java | 4 ++ .../java/vendingmachine/view/OutputView.java | 4 ++ 7 files changed, 63 insertions(+), 2 deletions(-) diff --git a/docs/README.md b/docs/README.md index 3ed0e57d3..cf08e359e 100644 --- a/docs/README.md +++ b/docs/README.md @@ -16,4 +16,4 @@ - [x] 보유한 금액이 상품의 가격보다 작은 경우 예외 발생 - [x] 상품 개수 하나 줄이기 - [x] 남은 금액이 상품의 최저 가격보다 적거나, 모든 상품이 소진된 경우 종료 - - [ ] 잔돈 출력 \ No newline at end of file + - [x] 잔돈 출력 \ No newline at end of file diff --git a/src/main/java/vendingmachine/controller/MachineController.java b/src/main/java/vendingmachine/controller/MachineController.java index baab015e5..8e06b201f 100644 --- a/src/main/java/vendingmachine/controller/MachineController.java +++ b/src/main/java/vendingmachine/controller/MachineController.java @@ -18,6 +18,7 @@ public void start() { while (service.isOnSale()) { purchaseGoods(); } + outputView.printChange(service.calculateChange()); } private Coins readChangePrice() { diff --git a/src/main/java/vendingmachine/domain/Coin.java b/src/main/java/vendingmachine/domain/Coin.java index 3a3dd1911..f9db9bfcb 100644 --- a/src/main/java/vendingmachine/domain/Coin.java +++ b/src/main/java/vendingmachine/domain/Coin.java @@ -19,6 +19,7 @@ public enum Coin { public static List getCoinKind() { return Arrays.stream(Coin.values()) .map(coin -> coin.amount) + .sorted() .collect(Collectors.toList()); } @@ -27,6 +28,7 @@ public static Coin getCoin(int value) { .filter(coin -> coin.amount == value) .findAny() .orElseThrow(() -> new IllegalArgumentException("")); + } public int getPrice() { diff --git a/src/main/java/vendingmachine/domain/Coins.java b/src/main/java/vendingmachine/domain/Coins.java index a2d3186b4..25b50b391 100644 --- a/src/main/java/vendingmachine/domain/Coins.java +++ b/src/main/java/vendingmachine/domain/Coins.java @@ -39,4 +39,50 @@ public String getChangeCoins() { ); return sb.toString(); } -} + + public String getChange(int money) { + Map change = new EnumMap<>(Coin.class); + calculateChange(change, money); + StringBuilder sb = new StringBuilder(); + return makeScreen(change, sb); + } + + private void calculateChange(Map change, int money) { + for (Coin coin: Coin.values()) { + if (coin.getPrice() < money) { + int coinNumber = calculateCoinNumber(money, coin); + elements.put(coin, elements.get(coin) - coinNumber); + change.put(coin, coinNumber); + money -= coinNumber * coin.getPrice(); + } + if (money <= 0 || isExistChange()) { + break; + } + } + } + + private String makeScreen(Map change, StringBuilder sb) { + change.keySet() + .forEach(value -> { + String message = OutputMessage.CHANGE.toString(); + sb.append(String.format(message, value.getPrice(), change.get(value))); + } + ); + return sb.toString(); + } + + private boolean isExistChange() { + return elements.values() + .stream() + .mapToInt(i -> i) + .sum() <= 0; + } + + private int calculateCoinNumber(int money, Coin coin) { + int num = money % coin.getPrice(); + if (elements.get(coin) > num) { + return elements.get(coin); + } + return num; + } +} \ No newline at end of file diff --git a/src/main/java/vendingmachine/domain/Money.java b/src/main/java/vendingmachine/domain/Money.java index 20b955221..a6b90137b 100644 --- a/src/main/java/vendingmachine/domain/Money.java +++ b/src/main/java/vendingmachine/domain/Money.java @@ -29,4 +29,8 @@ public boolean isEnoughMoney(int minPrice) { public String getInputAmount() { return String.format(OutputMessage.INPUT_AMOUNT.toString() , value); } + + public int getValue() { + return value; + } } diff --git a/src/main/java/vendingmachine/service/MachineService.java b/src/main/java/vendingmachine/service/MachineService.java index d0a0f8118..4c2a227de 100644 --- a/src/main/java/vendingmachine/service/MachineService.java +++ b/src/main/java/vendingmachine/service/MachineService.java @@ -27,6 +27,10 @@ public boolean isOnSale() { return products.isExistProduct() && money.isEnoughMoney(products.getMinPrice()); } + public String calculateChange() { + return coins.getChange(money.getValue()); + } + public Money getMoney() { return money; } diff --git a/src/main/java/vendingmachine/view/OutputView.java b/src/main/java/vendingmachine/view/OutputView.java index 485219fb3..b672de56e 100644 --- a/src/main/java/vendingmachine/view/OutputView.java +++ b/src/main/java/vendingmachine/view/OutputView.java @@ -30,4 +30,8 @@ public void printInputAmount(Money money){ public void printPurchaseGoods() { System.out.println(OutputMessage.PURCHASE_GOODS); } + + public void printChange(String message) { + System.out.println(message); + } } From 5440687b4a5fa98feceac36bca5ab62a29dcf1e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=97=B0=EC=A7=84?= Date: Thu, 21 Sep 2023 17:37:52 +0900 Subject: [PATCH 22/31] =?UTF-8?q?feat(MachineController):=20=EC=98=A4?= =?UTF-8?q?=EB=A5=98=20=EB=B0=9C=EC=83=9D=20=EC=A7=80=EC=A0=90=EB=B6=80?= =?UTF-8?q?=ED=84=B0=20=EC=9E=AC=EC=8B=9C=EC=9E=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 2 +- .../vendingmachine/constant/Constant.java | 16 ++++++++ .../constant/ExceptionMessage.java | 3 +- .../controller/MachineController.java | 39 ++++++++++++++----- .../java/vendingmachine/domain/Coins.java | 8 ++++ .../java/vendingmachine/view/OutputView.java | 4 ++ 6 files changed, 61 insertions(+), 11 deletions(-) create mode 100644 src/main/java/vendingmachine/constant/Constant.java diff --git a/docs/README.md b/docs/README.md index cf08e359e..eaf49d96e 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,7 +1,7 @@ ## 기능 구현 목록 - [x] 자판기 보유 금액을 입력한다. - - [ ] 10원 단위로 나누어 떨어지지 않을 경우 예외 발생 + - [x] 10원 단위로 나누어 떨어지지 않을 경우 예외 발생 - [x] 입력받은 보유 금액에 따라 동전 개수 랜덤 생성 - [x] 자판기가 보유하고 있는 동전의 개수를 출력한다. - [x] 자판기에 상품을 입력한다. diff --git a/src/main/java/vendingmachine/constant/Constant.java b/src/main/java/vendingmachine/constant/Constant.java new file mode 100644 index 000000000..a125da453 --- /dev/null +++ b/src/main/java/vendingmachine/constant/Constant.java @@ -0,0 +1,16 @@ +package vendingmachine.constant; + +public enum Constant { + + PRICE_UNIT(10); + + private final int value; + + Constant(int value) { + this.value = value; + } + + public int getValue() { + return value; + } +} diff --git a/src/main/java/vendingmachine/constant/ExceptionMessage.java b/src/main/java/vendingmachine/constant/ExceptionMessage.java index 2c29e702e..23b48628c 100644 --- a/src/main/java/vendingmachine/constant/ExceptionMessage.java +++ b/src/main/java/vendingmachine/constant/ExceptionMessage.java @@ -4,7 +4,8 @@ public enum ExceptionMessage { NOT_EXIST_PRODUCT("존재하지 않는 상품입니다."), - NOT_ENOUGH_MONEY("보유한 금액이 부족해 상품을 구매할 수 없습니다."); + NOT_ENOUGH_MONEY("보유한 금액이 부족해 상품을 구매할 수 없습니다."), + INVALID_UNIT("10원 단위로 입력해야합니다."); private static final String PREFIX = "[ERROR] "; private final String message; diff --git a/src/main/java/vendingmachine/controller/MachineController.java b/src/main/java/vendingmachine/controller/MachineController.java index 8e06b201f..f8d88ea33 100644 --- a/src/main/java/vendingmachine/controller/MachineController.java +++ b/src/main/java/vendingmachine/controller/MachineController.java @@ -7,6 +7,8 @@ import vendingmachine.view.InputView; import vendingmachine.view.OutputView; +import java.util.function.Supplier; + public class MachineController { private final InputView inputView = new InputView(); @@ -22,25 +24,44 @@ public void start() { } private Coins readChangePrice() { - outputView.printChangeMessage(); - Coins coins = inputView.readChangePrice(); - outputView.printChange(coins); - return coins; + return readInput(() -> { + outputView.printChangeMessage(); + Coins coins = inputView.readChangePrice(); + outputView.printChange(coins); + return coins; + }); } private Products readProducts() { - outputView.printProduct(); - return inputView.readProducts(); + return readInput(() -> { + outputView.printProduct(); + return inputView.readProducts(); + }); } private Money readMoney() { - outputView.printInputAmountMessage(); - return inputView.readInputAmount(); + return readInput(() -> { + outputView.printInputAmountMessage(); + return inputView.readInputAmount(); + }); } private void purchaseGoods() { outputView.printInputAmount(service.getMoney()); outputView.printPurchaseGoods(); - service.purchaseProduct(inputView.readProduct()); + service.purchaseProduct(readProduct()); + } + + private String readProduct() { + return readInput(inputView::readProduct); + } + + private T readInput(Supplier supplier) { + try { + return supplier.get(); + } catch (IllegalArgumentException e) { + outputView.printExceptionMessage(e.getMessage()); + return supplier.get(); + } } } diff --git a/src/main/java/vendingmachine/domain/Coins.java b/src/main/java/vendingmachine/domain/Coins.java index 25b50b391..22b2ae13b 100644 --- a/src/main/java/vendingmachine/domain/Coins.java +++ b/src/main/java/vendingmachine/domain/Coins.java @@ -1,6 +1,8 @@ package vendingmachine.domain; import camp.nextstep.edu.missionutils.Randoms; +import vendingmachine.constant.Constant; +import vendingmachine.constant.ExceptionMessage; import vendingmachine.constant.OutputMessage; import java.util.EnumMap; @@ -13,11 +15,17 @@ public class Coins { public Coins(int price) { this.elements = new EnumMap<>(Coin.class); + validatePrice(price); Coin.getCoinKind() .forEach(value -> elements.put(Coin.getCoin(value), DEFAULT)); createRandomCoins(price); } + private void validatePrice(int price) { + if (price % Constant.PRICE_UNIT.getValue() != 0) { + throw new IllegalArgumentException(ExceptionMessage.INVALID_UNIT.toString()); + } + } private void createRandomCoins(int price) { while (price > 0) { int value = Randoms.pickNumberInList(Coin.getCoinKind()); diff --git a/src/main/java/vendingmachine/view/OutputView.java b/src/main/java/vendingmachine/view/OutputView.java index b672de56e..7e6ace3f4 100644 --- a/src/main/java/vendingmachine/view/OutputView.java +++ b/src/main/java/vendingmachine/view/OutputView.java @@ -34,4 +34,8 @@ public void printPurchaseGoods() { public void printChange(String message) { System.out.println(message); } + + public void printExceptionMessage(String message){ + System.out.println(message); + } } From 370148d3af5984c565886789d8adde546d6789be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=97=B0=EC=A7=84?= Date: Thu, 21 Sep 2023 17:45:54 +0900 Subject: [PATCH 23/31] =?UTF-8?q?feat(Price):=20=EC=83=81=ED=92=88=20?= =?UTF-8?q?=EA=B0=80=EA=B2=A9=20=EC=9E=85=EB=A0=A5=20=EC=98=A4=EB=A5=98=20?= =?UTF-8?q?=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 4 +-- .../vendingmachine/constant/Constant.java | 3 +- .../constant/ExceptionMessage.java | 3 +- .../java/vendingmachine/domain/Price.java | 35 +++++++++++++++++++ .../java/vendingmachine/domain/Product.java | 6 ++-- 5 files changed, 44 insertions(+), 7 deletions(-) create mode 100644 src/main/java/vendingmachine/domain/Price.java diff --git a/docs/README.md b/docs/README.md index eaf49d96e..2fec9c66b 100644 --- a/docs/README.md +++ b/docs/README.md @@ -5,8 +5,8 @@ - [x] 입력받은 보유 금액에 따라 동전 개수 랜덤 생성 - [x] 자판기가 보유하고 있는 동전의 개수를 출력한다. - [x] 자판기에 상품을 입력한다. - - [ ] 상품의 가격이 100원이하일 경우 예외 - - [ ] 상품의 가격이 10원 단위로 나누어 떨어지지 않을 경우 예외 + - [x] 상품의 가격이 100원이하일 경우 예외 + - [x] 상품의 가격이 10원 단위로 나누어 떨어지지 않을 경우 예외 - [x] 사용자가 투입할 금액을 입력한다. - [x] 구매할 상품명 입력 - [x] 해당 상품이 존재하지 않을 경우 예외 diff --git a/src/main/java/vendingmachine/constant/Constant.java b/src/main/java/vendingmachine/constant/Constant.java index a125da453..afe9e1b77 100644 --- a/src/main/java/vendingmachine/constant/Constant.java +++ b/src/main/java/vendingmachine/constant/Constant.java @@ -2,7 +2,8 @@ public enum Constant { - PRICE_UNIT(10); + PRICE_UNIT(10), + MIN_PRICE(100); private final int value; diff --git a/src/main/java/vendingmachine/constant/ExceptionMessage.java b/src/main/java/vendingmachine/constant/ExceptionMessage.java index 23b48628c..4f899427d 100644 --- a/src/main/java/vendingmachine/constant/ExceptionMessage.java +++ b/src/main/java/vendingmachine/constant/ExceptionMessage.java @@ -5,7 +5,8 @@ public enum ExceptionMessage { NOT_EXIST_PRODUCT("존재하지 않는 상품입니다."), NOT_ENOUGH_MONEY("보유한 금액이 부족해 상품을 구매할 수 없습니다."), - INVALID_UNIT("10원 단위로 입력해야합니다."); + INVALID_UNIT("10원 단위로 입력해야합니다."), + MIN_PRICE("상품의 가격은 100원 이상부터 입력할 수 있습니다."); private static final String PREFIX = "[ERROR] "; private final String message; diff --git a/src/main/java/vendingmachine/domain/Price.java b/src/main/java/vendingmachine/domain/Price.java new file mode 100644 index 000000000..0854b52b0 --- /dev/null +++ b/src/main/java/vendingmachine/domain/Price.java @@ -0,0 +1,35 @@ +package vendingmachine.domain; + +import vendingmachine.constant.Constant; +import vendingmachine.constant.ExceptionMessage; + +public class Price { + + private final int value; + + public Price(int value) { + validate(value); + this.value = value; + } + + private void validate(int value) { + validateUnit(value); + validateMinPrice(value); + } + + private void validateUnit(int value) { + if (value % Constant.PRICE_UNIT.getValue() != 0) { + throw new IllegalArgumentException(ExceptionMessage.INVALID_UNIT.toString()); + } + } + + private void validateMinPrice(int value) { + if (value < Constant.MIN_PRICE.getValue()) { + throw new IllegalArgumentException(ExceptionMessage.MIN_PRICE.toString()); + } + } + + public int getValue() { + return value; + } +} diff --git a/src/main/java/vendingmachine/domain/Product.java b/src/main/java/vendingmachine/domain/Product.java index 1c21ee4d9..532bbab38 100644 --- a/src/main/java/vendingmachine/domain/Product.java +++ b/src/main/java/vendingmachine/domain/Product.java @@ -15,13 +15,13 @@ public class Product { private static final int PURCHASE_QUANTITY = 1; private final String name; - private final int price; + private final Price price; private int quantity; public Product(String message) { List productInformation = parseString(message); this.name = productInformation.get(NAME_INDEX); - this.price = Integer.parseInt(productInformation.get(PRICE_INDEX)); + this.price = new Price(Integer.parseInt(productInformation.get(PRICE_INDEX))); this.quantity = Integer.parseInt(productInformation.get(QUANTITY_INDEX)); } @@ -43,7 +43,7 @@ public boolean isExist() { } public int getPrice() { - return price; + return price.getValue(); } @Override public String toString() { From ec97ffcacd5a6139336b0d07b14493a60a105396 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=97=B0=EC=A7=84?= Date: Thu, 21 Sep 2023 17:54:57 +0900 Subject: [PATCH 24/31] =?UTF-8?q?feat(OutputView):=20=EC=A4=84=20=EB=B0=94?= =?UTF-8?q?=EA=BF=88=20=EC=B6=9C=EB=A0=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/MachineController.java | 15 ++++++++++++--- src/main/java/vendingmachine/view/OutputView.java | 4 ++++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/main/java/vendingmachine/controller/MachineController.java b/src/main/java/vendingmachine/controller/MachineController.java index f8d88ea33..c0c438189 100644 --- a/src/main/java/vendingmachine/controller/MachineController.java +++ b/src/main/java/vendingmachine/controller/MachineController.java @@ -27,6 +27,7 @@ private Coins readChangePrice() { return readInput(() -> { outputView.printChangeMessage(); Coins coins = inputView.readChangePrice(); + outputView.printNewLine(); outputView.printChange(coins); return coins; }); @@ -35,14 +36,18 @@ private Coins readChangePrice() { private Products readProducts() { return readInput(() -> { outputView.printProduct(); - return inputView.readProducts(); + Products products = inputView.readProducts(); + outputView.printNewLine(); + return products; }); } private Money readMoney() { return readInput(() -> { outputView.printInputAmountMessage(); - return inputView.readInputAmount(); + Money money = inputView.readInputAmount(); + outputView.printNewLine(); + return money; }); } @@ -53,7 +58,11 @@ private void purchaseGoods() { } private String readProduct() { - return readInput(inputView::readProduct); + return readInput( () -> { + String product = inputView.readProduct(); + outputView.printNewLine(); + return product; + }); } private T readInput(Supplier supplier) { diff --git a/src/main/java/vendingmachine/view/OutputView.java b/src/main/java/vendingmachine/view/OutputView.java index 7e6ace3f4..f5a62ba56 100644 --- a/src/main/java/vendingmachine/view/OutputView.java +++ b/src/main/java/vendingmachine/view/OutputView.java @@ -38,4 +38,8 @@ public void printChange(String message) { public void printExceptionMessage(String message){ System.out.println(message); } + + public void printNewLine() { + System.out.println(); + } } From bff4db8c246a4390f39f00250688b6407c1cf011 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=97=B0=EC=A7=84?= Date: Thu, 21 Sep 2023 18:00:55 +0900 Subject: [PATCH 25/31] =?UTF-8?q?feat(MachineService):=20=EC=83=81?= =?UTF-8?q?=ED=92=88=EB=AA=85=EC=9C=BC=EB=A1=9C=20=EC=83=81=ED=92=88=20?= =?UTF-8?q?=EC=B0=BE=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vendingmachine/controller/MachineController.java | 11 ++++++----- .../java/vendingmachine/service/MachineService.java | 7 +++++-- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/main/java/vendingmachine/controller/MachineController.java b/src/main/java/vendingmachine/controller/MachineController.java index c0c438189..f30de98f7 100644 --- a/src/main/java/vendingmachine/controller/MachineController.java +++ b/src/main/java/vendingmachine/controller/MachineController.java @@ -2,6 +2,7 @@ import vendingmachine.domain.Coins; import vendingmachine.domain.Money; +import vendingmachine.domain.Product; import vendingmachine.domain.Products; import vendingmachine.service.MachineService; import vendingmachine.view.InputView; @@ -53,15 +54,15 @@ private Money readMoney() { private void purchaseGoods() { outputView.printInputAmount(service.getMoney()); - outputView.printPurchaseGoods(); service.purchaseProduct(readProduct()); } - private String readProduct() { - return readInput( () -> { - String product = inputView.readProduct(); + private Product readProduct() { + return readInput(() -> { + outputView.printPurchaseGoods(); + String productName = inputView.readProduct(); outputView.printNewLine(); - return product; + return service.findProductByName(productName); }); } diff --git a/src/main/java/vendingmachine/service/MachineService.java b/src/main/java/vendingmachine/service/MachineService.java index 4c2a227de..e6023c30a 100644 --- a/src/main/java/vendingmachine/service/MachineService.java +++ b/src/main/java/vendingmachine/service/MachineService.java @@ -17,8 +17,11 @@ public MachineService(Coins coins, Products products, Money money) { this.money = money; } - public void purchaseProduct(String name) { - Product product = products.findByProductName(name); + public Product findProductByName(String name) { + return products.findByProductName(name); + } + + public void purchaseProduct(Product product) { money.pay(product.getPrice()); product.purchase(); } From e6c33e7ec705fc1e77844686dcc78fda80f6b284 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=97=B0=EC=A7=84?= Date: Fri, 22 Sep 2023 13:20:33 +0900 Subject: [PATCH 26/31] =?UTF-8?q?test(Money):=20=EC=83=81=ED=92=88=20?= =?UTF-8?q?=EA=B5=AC=EB=A7=A4=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/MachineController.java | 7 +++++-- .../java/vendingmachine/domain/Product.java | 4 ---- .../java/vendingmachine/domain/MoneyTest.java | 21 +++++++++++++++++++ 3 files changed, 26 insertions(+), 6 deletions(-) create mode 100644 src/test/java/vendingmachine/domain/MoneyTest.java diff --git a/src/main/java/vendingmachine/controller/MachineController.java b/src/main/java/vendingmachine/controller/MachineController.java index f30de98f7..c3b5e31e1 100644 --- a/src/main/java/vendingmachine/controller/MachineController.java +++ b/src/main/java/vendingmachine/controller/MachineController.java @@ -53,8 +53,11 @@ private Money readMoney() { } private void purchaseGoods() { - outputView.printInputAmount(service.getMoney()); - service.purchaseProduct(readProduct()); + readInput(() -> { + outputView.printInputAmount(service.getMoney()); + service.purchaseProduct(readProduct()); + return null; + }); } private Product readProduct() { diff --git a/src/main/java/vendingmachine/domain/Product.java b/src/main/java/vendingmachine/domain/Product.java index 532bbab38..00fd370b9 100644 --- a/src/main/java/vendingmachine/domain/Product.java +++ b/src/main/java/vendingmachine/domain/Product.java @@ -45,8 +45,4 @@ public boolean isExist() { public int getPrice() { return price.getValue(); } - @Override - public String toString() { - return name + "\n" + price + "\n" + quantity; - } } diff --git a/src/test/java/vendingmachine/domain/MoneyTest.java b/src/test/java/vendingmachine/domain/MoneyTest.java new file mode 100644 index 000000000..bf3ad7ecb --- /dev/null +++ b/src/test/java/vendingmachine/domain/MoneyTest.java @@ -0,0 +1,21 @@ +package vendingmachine.domain; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +public class MoneyTest { + + private static final String ERROR_MESSAGE = "[ERROR]"; + + @Test + @DisplayName("남은 돈 보다 큰 돈을 내야할 경우 예외가 발생한다.") + void validateTest() { + Money money = new Money(1000); + + assertThatThrownBy(() -> money.pay(10000)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining(ERROR_MESSAGE); + } +} From 940faa692c6494778100376f5b475f783c7a3b37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=97=B0=EC=A7=84?= Date: Fri, 22 Sep 2023 13:23:45 +0900 Subject: [PATCH 27/31] =?UTF-8?q?test(Price):=20=EC=A0=9C=ED=92=88=20?= =?UTF-8?q?=EA=B0=80=EA=B2=A9=20=EC=9E=85=EB=A0=A5=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/vendingmachine/domain/PriceTest.java | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 src/test/java/vendingmachine/domain/PriceTest.java diff --git a/src/test/java/vendingmachine/domain/PriceTest.java b/src/test/java/vendingmachine/domain/PriceTest.java new file mode 100644 index 000000000..87646a170 --- /dev/null +++ b/src/test/java/vendingmachine/domain/PriceTest.java @@ -0,0 +1,29 @@ +package vendingmachine.domain; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +public class PriceTest { + + private static final String ERROR_MESSAGE = "[ERROR]"; + + @Test + @DisplayName("10원 단위로 가격을 입력하지 않을 경우 예외가 발생한다.") + void validateUnit() { + // given + assertThatThrownBy(() -> new Price(11)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining(ERROR_MESSAGE); + } + + @Test + @DisplayName("가격이 100원 이하일 경우 예외가 발생한다.") + void validateMinPrice() { + // given + assertThatThrownBy(() -> new Price(30)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining(ERROR_MESSAGE); + } +} From 1493d7ac1798002deda21b67f01d4a106070508c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=97=B0=EC=A7=84?= Date: Fri, 22 Sep 2023 13:45:20 +0900 Subject: [PATCH 28/31] =?UTF-8?q?feat(InputValidator):=20=EC=9E=85?= =?UTF-8?q?=EB=A0=A5=EA=B0=92=20=EA=B2=80=EC=A6=9D=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../constant/ExceptionMessage.java | 4 ++- .../validator/InputValidator.java | 25 +++++++++++++++++++ .../java/vendingmachine/view/InputView.java | 13 +++++++--- 3 files changed, 37 insertions(+), 5 deletions(-) create mode 100644 src/main/java/vendingmachine/validator/InputValidator.java diff --git a/src/main/java/vendingmachine/constant/ExceptionMessage.java b/src/main/java/vendingmachine/constant/ExceptionMessage.java index 4f899427d..0ac519b9c 100644 --- a/src/main/java/vendingmachine/constant/ExceptionMessage.java +++ b/src/main/java/vendingmachine/constant/ExceptionMessage.java @@ -6,7 +6,9 @@ public enum ExceptionMessage { NOT_EXIST_PRODUCT("존재하지 않는 상품입니다."), NOT_ENOUGH_MONEY("보유한 금액이 부족해 상품을 구매할 수 없습니다."), INVALID_UNIT("10원 단위로 입력해야합니다."), - MIN_PRICE("상품의 가격은 100원 이상부터 입력할 수 있습니다."); + MIN_PRICE("상품의 가격은 100원 이상부터 입력할 수 있습니다."), + INCORRECT_FORMAT("형식에 맞춰 입력해주십시오."), + NOT_INTEGER("숫자로 입력해야 합니다."),; private static final String PREFIX = "[ERROR] "; private final String message; diff --git a/src/main/java/vendingmachine/validator/InputValidator.java b/src/main/java/vendingmachine/validator/InputValidator.java new file mode 100644 index 000000000..b2e85351a --- /dev/null +++ b/src/main/java/vendingmachine/validator/InputValidator.java @@ -0,0 +1,25 @@ +package vendingmachine.validator; + +import vendingmachine.constant.ExceptionMessage; + +import java.util.regex.Pattern; + +public class InputValidator { + + private static final String FORMAT_REGEXP = "^[a-zA-Zㄱ-힣0-9,;\\[\\]]*$"; + private static final String NUMBER_REGEXP = "^\\d*$"; + + public void validateFormat(String input) { + if (!Pattern.matches(FORMAT_REGEXP, input)) { + ExceptionMessage exceptionMessage = ExceptionMessage.INCORRECT_FORMAT; + throw new IllegalArgumentException(exceptionMessage.toString()); + } + } + + public void validateIsNumber(String input) { + if (!Pattern.matches(NUMBER_REGEXP, input)) { + ExceptionMessage exceptionMessage = ExceptionMessage.NOT_INTEGER; + throw new IllegalArgumentException(exceptionMessage.toString()); + } + } +} \ No newline at end of file diff --git a/src/main/java/vendingmachine/view/InputView.java b/src/main/java/vendingmachine/view/InputView.java index 650040d8f..fc6e97af9 100644 --- a/src/main/java/vendingmachine/view/InputView.java +++ b/src/main/java/vendingmachine/view/InputView.java @@ -5,6 +5,7 @@ import vendingmachine.domain.Money; import vendingmachine.domain.Product; import vendingmachine.domain.Products; +import vendingmachine.validator.InputValidator; import java.util.Arrays; import java.util.stream.Collectors; @@ -12,22 +13,26 @@ public class InputView { private static final String PRODUCT_DELIMITER = ";"; + private final InputValidator inputValidator = new InputValidator(); public Coins readChangePrice() { - int input = Integer.parseInt(Console.readLine()); - return new Coins(input); + String input = Console.readLine(); + inputValidator.validateIsNumber(input); + return new Coins(Integer.parseInt(input)); } public Products readProducts() { String input = Console.readLine(); + inputValidator.validateFormat(input); return new Products(Arrays.stream(input.split(PRODUCT_DELIMITER)) .map(Product::new) .collect(Collectors.toList())); } public Money readInputAmount() { - int input = Integer.parseInt(Console.readLine()); - return new Money(input); + String input = Console.readLine(); + inputValidator.validateIsNumber(input); + return new Money(Integer.parseInt(input)); } public String readProduct() { From db6d890caf4d0926d162ba99447540a4944861be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=97=B0=EC=A7=84?= Date: Fri, 22 Sep 2023 13:49:06 +0900 Subject: [PATCH 29/31] =?UTF-8?q?test(InputValidator):=20=EC=9E=85?= =?UTF-8?q?=EB=A0=A5=EA=B0=92=20=EA=B2=80=EC=A6=9D=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vendingmachine/InputValidatorTest.java | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 src/test/java/vendingmachine/InputValidatorTest.java diff --git a/src/test/java/vendingmachine/InputValidatorTest.java b/src/test/java/vendingmachine/InputValidatorTest.java new file mode 100644 index 000000000..20dccd8f7 --- /dev/null +++ b/src/test/java/vendingmachine/InputValidatorTest.java @@ -0,0 +1,34 @@ +package vendingmachine; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import vendingmachine.validator.InputValidator; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy; + +public class InputValidatorTest { + + private static final String ERROR_MESSAGE = "[ERROR]"; + + private final InputValidator inputValidator = new InputValidator(); + + @DisplayName("형식에 맞추어 입력하지 않을 경우 예외 발생") + @Test + void formatException() { + String input = "(콜라,1000,2)"; + + assertThatThrownBy(() -> inputValidator.validateFormat(input)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining(ERROR_MESSAGE); + } + + @DisplayName("숫자가 아닐 경우 예외 발생") + @Test + void numberException() { + String input = "o"; + + assertThatThrownBy(() -> inputValidator.validateIsNumber(input)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining(ERROR_MESSAGE); + } +} From 238f450a1e4d555fc066993e061e529202e7b22e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=97=B0=EC=A7=84?= Date: Mon, 25 Sep 2023 17:08:17 +0900 Subject: [PATCH 30/31] =?UTF-8?q?refactor(Coins):=20=EA=B1=B0=EC=8A=A4?= =?UTF-8?q?=EB=A6=84=EB=8F=88=20=EA=B3=84=EC=82=B0=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/vendingmachine/domain/Coin.java | 4 ++++ src/main/java/vendingmachine/domain/Coins.java | 18 ++++++++++++------ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/main/java/vendingmachine/domain/Coin.java b/src/main/java/vendingmachine/domain/Coin.java index f9db9bfcb..3540fe1d6 100644 --- a/src/main/java/vendingmachine/domain/Coin.java +++ b/src/main/java/vendingmachine/domain/Coin.java @@ -34,4 +34,8 @@ public static Coin getCoin(int value) { public int getPrice() { return this.amount; } + + public boolean isChangeable(int price) { + return price > this.amount; + } } diff --git a/src/main/java/vendingmachine/domain/Coins.java b/src/main/java/vendingmachine/domain/Coins.java index 22b2ae13b..295c6fc5a 100644 --- a/src/main/java/vendingmachine/domain/Coins.java +++ b/src/main/java/vendingmachine/domain/Coins.java @@ -57,18 +57,24 @@ public String getChange(int money) { private void calculateChange(Map change, int money) { for (Coin coin: Coin.values()) { - if (coin.getPrice() < money) { - int coinNumber = calculateCoinNumber(money, coin); - elements.put(coin, elements.get(coin) - coinNumber); - change.put(coin, coinNumber); - money -= coinNumber * coin.getPrice(); - } + int coinNumber = returnChange(coin, money, change); + money -= coinNumber * coin.getPrice(); if (money <= 0 || isExistChange()) { break; } } } + private int returnChange(Coin coin, int money, Map change) { + int coinNumber = 0; + if (coin.isChangeable(money)) { + coinNumber = calculateCoinNumber(money, coin); + elements.put(coin, elements.get(coin) - coinNumber); + change.put(coin, coinNumber); + } + return coinNumber; + } + private String makeScreen(Map change, StringBuilder sb) { change.keySet() .forEach(value -> { From 055b294d93e55f9ce53027a74fa34ede5d8e9b25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=97=B0=EC=A7=84?= Date: Mon, 25 Sep 2023 17:13:51 +0900 Subject: [PATCH 31/31] =?UTF-8?q?refactor(Coin):=20getter=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/vendingmachine/domain/Coin.java | 8 ++++++++ src/main/java/vendingmachine/domain/Coins.java | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/main/java/vendingmachine/domain/Coin.java b/src/main/java/vendingmachine/domain/Coin.java index 3540fe1d6..5ba518ac4 100644 --- a/src/main/java/vendingmachine/domain/Coin.java +++ b/src/main/java/vendingmachine/domain/Coin.java @@ -38,4 +38,12 @@ public int getPrice() { public boolean isChangeable(int price) { return price > this.amount; } + + public int calculateTotalAmount(int count) { + return this.amount * count; + } + + public int calculateCoinCount(int money) { + return money % this.amount; + } } diff --git a/src/main/java/vendingmachine/domain/Coins.java b/src/main/java/vendingmachine/domain/Coins.java index 295c6fc5a..9d9dc7e3e 100644 --- a/src/main/java/vendingmachine/domain/Coins.java +++ b/src/main/java/vendingmachine/domain/Coins.java @@ -58,7 +58,7 @@ public String getChange(int money) { private void calculateChange(Map change, int money) { for (Coin coin: Coin.values()) { int coinNumber = returnChange(coin, money, change); - money -= coinNumber * coin.getPrice(); + money -= coin.calculateTotalAmount(coinNumber); if (money <= 0 || isExistChange()) { break; } @@ -93,7 +93,7 @@ private boolean isExistChange() { } private int calculateCoinNumber(int money, Coin coin) { - int num = money % coin.getPrice(); + int num = coin.calculateCoinCount(money); if (elements.get(coin) > num) { return elements.get(coin); }