経緯
shiracamus様からのアドバイスを元に、DDD(ドメイン駆動)的に書き直しました。
その際、ロジックの見直しも一部行い、よりシンプルになるように致しました。
処理フロー
・インスタンス生成
・商品リスト初期化(在庫補充)
・商品一覧表示(陳列商品の表示)
・商品選択(ユーザによる入力)
・入金(ユーザによる入力)
・販売(課金処理)
・おつり(返金処理)
動作イメージ
ソースコード
Main.java
package vm;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
// インスタンス生成
Store venderMachine = new Store();
@SuppressWarnings("resource")
Scanner scanner = new Scanner(System.in);
// 商品リスト初期化
Product water = new Product("水", 80);
Product coke = new Product("コーラ", 100);
Product orangejuice = new Product("オレンジジュース", 120);
venderMachine.addStock(water);
venderMachine.addStock(coke);
venderMachine.addStock(orangejuice);
// 商品一覧表示
System.out.println("≪販売中の商品です≫");
venderMachine.showProductList();
// 商品選択
Product purchase = null;
String purchaseSelectMessage = "購入する商品名を入力してください。";
int purchaseSelectCount = 0;
do {
if(purchaseSelectCount > 0) {
purchaseSelectMessage = "その商品の取り扱いはございません。販売中の商品からお選び下さい。";
}
System.out.println();
System.out.println(purchaseSelectMessage);
purchase = venderMachine.inStocker(scanner.next());
purchaseSelectCount++;
} while(!venderMachine.isExistsStock(purchase));
// 入金
String depositMessage = "入金して下さい。";
int depositCount = 0;
do {
if(depositCount > 0) {
depositMessage = "入金額が不足しています。不足分を追加してください。";
}
System.out.println();
System.out.println(depositMessage);
venderMachine.addDeposit(scanner.nextInt());
depositCount++;
} while(!venderMachine.isEnoughDeposit(purchase));
// 販売
System.out.println();
venderMachine.sale(purchase);
// おつり
System.out.println();
venderMachine.change();
}
}
Store.java
package vm;
public class Store {
private Stocker stocker;
private Casher casher;
Store() {
stocker = new Stocker();
casher = new Casher();
}
void addDeposit(int deposit) {
casher.addDeposit(deposit);
}
void addStock(Product product) {
stocker.add(product);
}
void change() {
System.out.println("おつりは、" + casher.change() + "円です。");
}
void showProductList() {
stocker.showProductList();
}
boolean isExistsStock(Product product) {
return stocker.isExistsProduct(product);
}
boolean isEnoughDeposit(Product purchase) {
return casher.isEnoughDeposit(purchase);
}
Product inStocker(String productName) {
return stocker.getProduct(productName);
}
void sale(Product purchase) {
casher.charge(purchase);
System.out.println(purchase.name() + "です!");
System.out.println("ご購入ありがとうございました。");
}
}
Casher.java
package vm;
public class Casher {
private int deposit;
private int change;
Casher(){
deposit = 0;
change = 0;
}
void addDeposit(int deposit) {
this.deposit += deposit;
}
void charge(Product purchase) {
change = deposit - purchase.price();
}
int change() {
return change;
}
public boolean isEnoughDeposit(Product product) {
if(deposit >= product.price()) {
return true;
}
return false;
}
}
Stocker.java
package vm;
import java.util.ArrayList;
import java.util.List;
public class Stocker {
private List<Product> productList;
Stocker() {
productList = new ArrayList<>();
}
void add(Product product) {
productList.add(product);
}
void showProductList() {
for(Product product: productList) {
System.out.println(product.info());
}
}
boolean isExistsProduct(Product product) {
for(Product stock: productList) {
if(stock.name().equals(product.name())){
return true;
}
}
return false;
}
Product getProduct(String productName) {
for(Product stock: productList) {
if(stock.name().equals(productName)){
return stock;
}
}
return new Product();
}
}
Product.java
package vm;
public class Product {
private String productName;
private int price;
Product(String productName, int price) {
this.productName = productName;
this.price = price;
}
Product() {
this.productName = "";
this.price = 0;
}
String name() {
return productName;
}
int price() {
return price;
}
String info() {
String formatStr = "%s : %d円";
return String.format(formatStr, productName, price);
}
}