Javaで作る自動販売機のサンプル（クラス分け）

前回書いた自動販売機：https://qiita.com/TakumiKondo/items/e93aa60031e2fe09d969
をクラス分けしました。

```Items.java
package vm;
 
import java.util.HashMap;
import java.util.Map;
 
public class Items {
    private Map<String, Integer> items; // 商品リスト
    private Map<String, Integer> availablePurchases; // 購入可能商品
 
    // コンストラクタ（商品リストの初期化）
    Items() {
        this.items = new HashMap<String, Integer>();
        items.put("コーラ", 100);
        items.put("オレンジジュース", 120);
        items.put("水", 80);
    }
 
    // 最低購入金額の取得
    int minPrice() {
        int minPrice = 0;
        int loopCount = 0;
        for (String itemKey : items.keySet()) {
            minPrice = validMinPrice(loopCount, minPrice, itemPrice(itemKey));
            loopCount++;
        }
        return minPrice;
    }
 
    // 最低購入金額の判定
    int validMinPrice(int loopCount, int minPrice, int price) {
        if (loopCount == 0 || minPrice > price) {
            minPrice = price;
        }
        return minPrice;
    }
 
    // 商品金額
    private int itemPrice(String itemKey) {
        return items.get(itemKey);
    }
 
    // 購入可能商品金額
    private int availablePurchasePrice(String itemKey) {
        return availablePurchases.get(itemKey);
    }
 
    // 購入可能商品リストの取得
    void createAvailablePurchases(int deposit) {
        availablePurchases = new HashMap<String, Integer>();
        for (String itemKey : items.keySet()) {
            addAvailablePurchase(deposit, itemKey);
        }
    }
 
    // 購入可能商品リストの追加
    private void addAvailablePurchase(int deposit, String itemKey) {
        if (deposit >= items.get(itemKey)) {
            availablePurchases.put(itemKey, items.get(itemKey));
        }
    }
 
    // 購入可能商品の表示
    void showAvailablePurchase() {
        for (String itemKey : availablePurchases.keySet()) {
            System.out.println(itemKey + ":" + items.get(itemKey) + "円");
        }
    }
 
    // 購入可能商品であるかの判定
    boolean isAvailablePurchase(String itemName, Deposit deposit) {
        return availablePurchases.containsKey(itemName);
    }
 
    // 販売価格
    int saleAmount(String itemName) {
        return availablePurchasePrice(itemName);
    }
}
```

```Deposit.java
package vm;
 
public class Deposit {
    private int deposit; // 入金額
 
    // コンストラクタ（初期値0円）
    Deposit() {
        deposit = 0;
    }
 
    // 入金
    void deposit(int amount) {
        deposit = deposit + amount;
    }
 
    // 現在入金額
    int amount() {
        return this.deposit;
    }
 
    // 課金
    void charge(int amount) {
        int charge = this.deposit - amount;
        this.deposit = charge;
    }
}
```

```VendingMachine.java
package vm;
 
public class VendingMachine {
    private Items items; // 商品
    private Deposit deposit; // 入金額
 
    // コンストラクタ
    VendingMachine() {
        items = new Items();
        deposit = new Deposit();
    }
 
    // 入金
    void deposit(int amount) {
        deposit.deposit(amount);
    }
 
    // 最低価格商品以上の入金があるか判定
    boolean hasMinDeposit() {
        if (deposit.amount() < items.minPrice()) {
            return false;
        }
        return true;
    }
 
    // 購入可能商品を表示
    void showAvailablePurchases() {
        items.createAvailablePurchases(deposit.amount());
        items.showAvailablePurchase();
    }
 
    // 購入可能商品であるか判定
    boolean isAvailablePurchases(String itemName) {
        return items.isAvailablePurchase(itemName, deposit);
    }
 
    // 購入商品を表示
    void selectItem(String itemName) {
        System.out.println(itemName + "です！");
    }
 
    // 課金
    void charge(String itemName) {
        int saleAmount = items.saleAmount(itemName);
        deposit.charge(saleAmount);
        System.out.println("おつりは、" + deposit.amount() + "円です。");
    }
}
```

```Main.java
package vm;
 
import java.util.Scanner;
 
/**
 * 自動販売機（Level6） 自動販売機クラスの作成
 */
public class Main {
    // メインロジック
    public static void main(String[] args) {
        // ①商品の初期化
        VendingMachine vendingMachine = new VendingMachine();
 
        // 購入最低金額の場合、追加入金
        Scanner scanner = new Scanner(System.in);
        do {
            // ②入金
            System.out.println("お金を入れて下さい。");
            int amount = scanner.nextInt();
            vendingMachine.deposit(amount);
 
            // ③金額チェック（最低購入金額）
        } while (!vendingMachine.hasMinDeposit());
 
        // ④購入可能商品を表示
        System.out.println("");
        System.out.println("購入可能な商品です。");
        vendingMachine.showAvailablePurchases();
 
        // ⑤商品を選択
        String itemName;
        do {
            System.out.println("");
            System.out.println("商品名を入力して下さい。");
            itemName = scanner.next();
        } while (!vendingMachine.isAvailablePurchases(itemName));
        vendingMachine.selectItem(itemName);
        scanner.close();
 
        // ⑥課金機能
        vendingMachine.charge(itemName);
    }
 
}
```