Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[스터디용 PR] 홍예슬 미션 제출 합니다. #184

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/main/java/vendingmachine/Application.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package vendingmachine;

import vendingmachine.controller.MainController;

public class Application {
public static void main(String[] args) {
// TODO: 프로그램 구현
MainController mainController = new MainController();
mainController.run();
}
}
16 changes: 0 additions & 16 deletions src/main/java/vendingmachine/Coin.java

This file was deleted.

91 changes: 91 additions & 0 deletions src/main/java/vendingmachine/controller/MainController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package vendingmachine.controller;

import vendingmachine.model.VendingMachine;
import vendingmachine.model.coin.Coins;
import vendingmachine.model.drink.Drinks;
import vendingmachine.model.user.UserMoney;
import vendingmachine.view.OutputView;

import static vendingmachine.model.coin.RandomCoins.makeRandomCoins;
import static vendingmachine.view.InputView.readDrinks;
import static vendingmachine.view.InputView.readMoney;
import static vendingmachine.view.InputView.readPurchase;
import static vendingmachine.view.OutputView.askDrinkFromUsers;
import static vendingmachine.view.OutputView.askMachineTotalMoney;
import static vendingmachine.view.OutputView.askPurchaseDrinkType;
import static vendingmachine.view.OutputView.askUserInputMoney;
import static vendingmachine.view.OutputView.printVendingMachineCoins;
import static vendingmachine.view.OutputView.println;
import static vendingmachine.view.OutputView.showBalance;

public class MainController {
// VendingMachineController vendingMachineController = new VendingMachineController();

public void run(){
Coins coins = askTotalMoney();
showCoins(coins);
Drinks drinks = askDrinks();
VendingMachine vendingMachine = new VendingMachine(coins, drinks);
UserMoney userMoney = askInputAmount();

makePurchase(vendingMachine, userMoney);
}

private Coins askTotalMoney(){
while (true){
try {
askMachineTotalMoney();
return new Coins(makeRandomCoins(readMoney()));
} catch (IllegalArgumentException exception) {
OutputView.errorMessage(exception.getMessage());
}
}
}

private void showCoins(Coins coins) {
printVendingMachineCoins(coins.coinsCount());
}

private Drinks askDrinks() {
while (true) {
try {
askDrinkFromUsers();
return new Drinks(readDrinks());
} catch (IllegalArgumentException exception) {
OutputView.errorMessage(exception.getMessage());
}
}
}

private UserMoney askInputAmount() {
while (true) {
try {
askUserInputMoney();
return new UserMoney(readMoney());
} catch (IllegalArgumentException exception) {
OutputView.errorMessage(exception.getMessage());
}
}
}

private void makePurchase(VendingMachine vendingMachine, UserMoney userMoney) {
while (vendingMachine.hasMoneyMoreThenMinimumPrice(userMoney)) {
showBalance(userMoney.getBalance());
String purchaseDrinkType = askPurchase();
userMoney.purchaseDrink(vendingMachine.getPrice(purchaseDrinkType));
println();
}
showBalance(userMoney.getBalance());
}

private String askPurchase() {
while (true) {
try {
askPurchaseDrinkType();
return readPurchase();
} catch (IllegalArgumentException exception) {
OutputView.errorMessage(exception.getMessage());
}
}
}
}
17 changes: 17 additions & 0 deletions src/main/java/vendingmachine/controller/handler/RetryHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package vendingmachine.controller.handler;

import vendingmachine.view.OutputView;

public abstract class RetryHandler<E> implements RetryHandlerController<E> {
@Override
public E process() {
try {
return doProcess();
} catch (IllegalArgumentException exception) {
OutputView.errorMessage(exception.getMessage());
return process();
}
}

protected abstract E doProcess();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package vendingmachine.controller.handler;

public interface RetryHandlerController<E> {
E process();
}
29 changes: 29 additions & 0 deletions src/main/java/vendingmachine/model/VendingMachine.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package vendingmachine.model;

import vendingmachine.model.coin.Coins;
import vendingmachine.model.drink.Drinks;
import vendingmachine.model.user.UserMoney;

import java.util.List;

public class VendingMachine {
private Coins moneyBox;
private Drinks drinks;

public VendingMachine(Coins moneyBox, Drinks drinks) {
this.moneyBox = moneyBox;
this.drinks = drinks;
}

public List<Integer> showCoinBox() {
return moneyBox.coinsCount();
}

public boolean hasMoneyMoreThenMinimumPrice(UserMoney userMoney) {
return userMoney.getBalance() >= drinks.cheapestDrink();
}

public int getPrice(String purchaseDrinkType) {
return drinks.getPriceFindByName(purchaseDrinkType);
}
}
29 changes: 29 additions & 0 deletions src/main/java/vendingmachine/model/coin/Coin.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package vendingmachine.model.coin;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

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<Integer> coinTypes(){
List<Integer> types = new ArrayList<>();
Arrays.stream(Coin.values())
.forEach(coin -> types.add(coin.amount));
return types;
}

public static Coin getCoinType(int amount){
return Coin.valueOf("COIN_" + amount);
}
}
30 changes: 30 additions & 0 deletions src/main/java/vendingmachine/model/coin/Coins.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package vendingmachine.model.coin;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class Coins {
private HashMap<Coin, Integer> coins;

public Coins(HashMap<Coin, Integer> coins) {
this.coins = coins;
}

public List<Integer> coinsCount() {
List<Integer> count = new ArrayList<>();
count.add(getCoinCount("COIN_500"));
count.add(getCoinCount("COIN_100"));
count.add(getCoinCount("COIN_50"));
count.add(getCoinCount("COIN_10"));
return count;
}

private Integer getCoinCount(String coinType) {
Integer coinCount = coins.get(Coin.valueOf(coinType));
if (coinCount == null) {
return 0;
}
return coinCount;
}
}
25 changes: 25 additions & 0 deletions src/main/java/vendingmachine/model/coin/RandomCoins.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package vendingmachine.model.coin;

import camp.nextstep.edu.missionutils.Randoms;

import java.util.HashMap;

public class RandomCoins {
public static HashMap<Coin, Integer> makeRandomCoins(int totalMoney){
HashMap<Coin, Integer> moneyBox = new HashMap<>();
while(totalMoney > 0){
int coin = Randoms.pickNumberInList(Coin.coinTypes());
Coin coinType = Coin.getCoinType(coin);
if (totalMoney >= coin) {
if (moneyBox.containsKey(Coin.getCoinType(coin))) {
moneyBox.put(coinType, moneyBox.get(coinType)+1);
}
if (!moneyBox.containsKey(Coin.getCoinType(coin))) {
moneyBox.put(coinType, 1);
}
totalMoney -= coin;
}
}
return moneyBox;
}
}
6 changes: 6 additions & 0 deletions src/main/java/vendingmachine/model/constants/Delimiter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package vendingmachine.model.constants;

public class Delimiter {
public static final String DRINK_TYPE_DELIMITER_SEMICOLON = ";";
public static final String DRINK_DETAIL_DELIMITER_COMMA = ",";
}
7 changes: 7 additions & 0 deletions src/main/java/vendingmachine/model/constants/Index.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package vendingmachine.model.constants;

public class Index {
public static Integer DRINK_TYPE_INDEX = 0;
public static Integer DRINK_PRICE_INDEX = 1;
public static Integer DRINK_COUNT_INDEX = 2;
}
21 changes: 21 additions & 0 deletions src/main/java/vendingmachine/model/drink/Drink.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package vendingmachine.model.drink;

public class Drink {
private String title;
private Integer price;
private Integer count;

public Drink(String title, Integer price, Integer count) {
this.title = title;
this.price = price;
this.count = count;
}

public Integer getPrice() {
return price;
}

public String getName() {
return title;
}
}
47 changes: 47 additions & 0 deletions src/main/java/vendingmachine/model/drink/Drinks.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package vendingmachine.model.drink;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Objects;

import static vendingmachine.model.constants.Delimiter.DRINK_DETAIL_DELIMITER_COMMA;
import static vendingmachine.model.constants.Delimiter.DRINK_TYPE_DELIMITER_SEMICOLON;
import static vendingmachine.model.constants.Index.DRINK_COUNT_INDEX;
import static vendingmachine.model.constants.Index.DRINK_PRICE_INDEX;
import static vendingmachine.model.constants.Index.DRINK_TYPE_INDEX;

public class Drinks {
List<Drink> drinks = new ArrayList<>();

public Drinks(String inputDrink) {
String[] drinkTypes = inputDrink.split(DRINK_TYPE_DELIMITER_SEMICOLON);

for(int i=0; i<drinkTypes.length; i++){
String[] drinkDetail = drinkTypes[i].split(DRINK_DETAIL_DELIMITER_COMMA);
String drinkType = drinkDetail[DRINK_TYPE_INDEX];
Integer drinkPrice = Integer.parseInt(drinkDetail[DRINK_PRICE_INDEX]);
Integer drinkCount = Integer.parseInt(drinkDetail[DRINK_COUNT_INDEX]);

drinks.add(new Drink(drinkType, drinkPrice, drinkCount));
}
}

public Integer cheapestDrink() {
Comparator<Drink> comparatorByAge = Comparator.comparingInt(Drink::getPrice);

Drink cheapestDrink = drinks.stream()
.min(comparatorByAge).orElseThrow(NoSuchElementException::new);
return cheapestDrink.getPrice();
}

public int getPriceFindByName(String purchaseDrinkType) {
for (Drink drink : drinks) {
if (Objects.equals(drink.getName(), purchaseDrinkType)) {
return drink.getPrice();
}
}
return 0;
}
}
17 changes: 17 additions & 0 deletions src/main/java/vendingmachine/model/user/UserMoney.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package vendingmachine.model.user;

public class UserMoney {
int money = 0;

public UserMoney(int money) {
this.money = money;
}

public int getBalance() {
return money;
}

public void purchaseDrink(int price) {
money -= price;
}
}
32 changes: 32 additions & 0 deletions src/main/java/vendingmachine/view/InputView.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package vendingmachine.view;

import camp.nextstep.edu.missionutils.Console;

import static vendingmachine.view.constants.Regex.REGEX_SELECT_BRACKETS;
import static vendingmachine.view.validate.CoinValidator.checkNumericInput;
import static vendingmachine.view.validate.DrinkValidator.checkDrinkInput;
import static vendingmachine.view.validate.DrinkValidator.checkOnlyKoreanLetter;

public class InputView {
public static String readLine(){
return Console.readLine();
}

public static int readMoney(){
String money = readLine();
checkNumericInput(money);
return Integer.parseInt(money);
}

public static String readDrinks() {
String drinks = readLine();
checkDrinkInput(drinks);
return drinks.replaceAll(REGEX_SELECT_BRACKETS, "");
}

public static String readPurchase() {
String purchase = readLine();
checkOnlyKoreanLetter(purchase);
return purchase;
}
}
Loading