-
Notifications
You must be signed in to change notification settings - Fork 351
Expand file tree
/
Copy pathMainController.java
More file actions
93 lines (81 loc) · 3.39 KB
/
MainController.java
File metadata and controls
93 lines (81 loc) · 3.39 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
package vendingmachine.controller;
import vendingmachine.domain.*;
import vendingmachine.dto.ExchangeCoinsDto;
import vendingmachine.dto.ItemDto;
import vendingmachine.dto.OrderDetailDto;
import vendingmachine.dto.VendingMachineCoinsDto;
import vendingmachine.view.InputView;
import vendingmachine.view.OutputView;
import java.util.EnumMap;
import java.util.List;
import java.util.function.Supplier;
import java.util.stream.Collectors;
public class MainController {
private final InputView inputView;
private final OutputView outputView;
public MainController(InputView inputView, OutputView outputView) {
this.inputView = inputView;
this.outputView = outputView;
}
public void run() {
VendingMachineCoins coins = createVendingMachineAmount();
outputView.printVendingMachineAmount(VendingMachineCoinsDto.from(coins));
Items items = createItems();
InsertedAmount insertedAmount = createInsertedAmount();
outputView.printInputAmount(insertedAmount.provideAmount());
boolean canBuyMore = true;
while (canBuyMore) {
OrderDetailDto orderDetailDto = createOrderDetailDto(insertedAmount.provideAmount(), items);
insertedAmount.updateAmount(orderDetailDto.getUpdatedInputAmount());
outputView.printInputAmount(insertedAmount.provideAmount());
canBuyMore = canBuyMore(items, insertedAmount);
}
generateExchangeCoins(coins, insertedAmount);
}
private void generateExchangeCoins(VendingMachineCoins coins, InsertedAmount insertedAmount) {
long amount = insertedAmount.provideAmount();
EnumMap<Coin, Long> exchangeCoins = coins.generateExchangeCoins(amount);
ExchangeCoinsDto exchangeCoinsDto = ExchangeCoinsDto.from(exchangeCoins);
outputView.printExchangeCoins(exchangeCoinsDto);
}
private boolean canBuyMore(Items items, InsertedAmount amount) {
return amount.isEqualOrLargerThan(items.findPurchasableMinimumPrice()) && !items.hasNoQuantity();
}
private VendingMachineCoins createVendingMachineAmount() {
return readUserInput(() -> {
long amount = inputView.readVendingMachineAmount();
return VendingMachineCoins.from(amount);
});
}
private Items createItems() {
return readUserInput(() -> {
List<Item> items = inputView.readItems().stream()
.map(ItemDto::toItem)
.collect(Collectors.toList());
return Items.from(items);
});
}
private InsertedAmount createInsertedAmount() {
return readUserInput(() -> {
long amount = inputView.readInputAmount();
return InsertedAmount.from(amount);
});
}
private OrderDetailDto createOrderDetailDto(long inputAmount, Items items) {
return readUserInput(() -> {
String itemName = inputView.readOrderItemName();
Item orderItem = items.buyItem(itemName, inputAmount);
long updatedInputAmount = inputAmount - orderItem.providePrice();
return OrderDetailDto.of(itemName, updatedInputAmount);
});
}
private <T> T readUserInput(Supplier<T> supplier) {
while (true) {
try {
return supplier.get();
} catch (IllegalArgumentException e) {
outputView.printError(e.getMessage());
}
}
}
}