本記事は、【Swift】自動販売機の例外処理を実装してみた の続きです。
前回までの記事で基本的な処理と例外処理を記述しましたが、
例外処理に改善点があったのでそちらについての対応を行いたいと思います。
前回までの内容をご存知ではない方はそちらをご覧ください。
##前回のおさらい
商品を購入する際の処理で、在庫の確認とお金が足りるかを確認しています。
どちらかの結果がNGだったら例外処理を行うわけですが、
if文を2回使って処理を記述するのはあまりきれいではない気がします。
また、各ケースにこの処理を記述するのは可読性やメンテナンス性が低くなります。
なので、新しい関数を定義しそちらで購入時のチェックを行う様にしたいと思います。
var irohasuStock = 3
var ryokuchaStock = 2
var gogothiStock = 1
// 購入処理
func buyDrink(product: Drink) {
switch product {
case .irohasu:
if !inventoryControl(product: product) {
print("在庫がありません。")
return
}
if inputMoney - 100 < 0 {
print("お金が足りません。")
return
}
inputMoney -= 100
inputMoneyLabel.text = "金額:\(inputMoney)円"
print("いろはすを購入しました。")
}
}
// 在庫管理
func inventoryControl(product: Drink) -> Bool {
switch product {
case .irohasu:
if irohasuStock == 0 {
return false
}
irohasuStock -= 1
return true
}
}
##修正
まず初めに詳細のエラーを表示するために列挙型SomeError型を定義しました。
それと同時に購入処理のメソッドの変更と購入条件チェックメソッドを作成しました。
(別のケースはほぼ同じ処理なので省略しました。)
在庫管理メソッドは、購入条件メソッドと被っているので削除しました。
enum SomeError: Error {
case inventoryShortage // 在庫切れ
case lackOfMoney // 金額不足
}
// 購入処理
func buyDrink(product: Drink) {
switch product {
case .irohasu:
do {
try checkCondition(product: product, price: 100)
} catch {
print(error)
return
}
inputMoney -= 100
inputMoneyLabel.text = "金額:\(inputMoney)円"
print("いろはすを購入しました。")
}
}
//購入条件チェック
func checkCondition(product: Drink, price: Int) throws {
switch product {
case .irohasu:
if irohasuStock == 0 {
throw SomeError.inventoryShortage(reason: "いろはすの在庫がありません。")
} else if inputMoney < price {
throw SomeError.lackOfMoney(reason: "\(inputMoney)円しか入れられていないので、いろはすを購入できません。")
}
irohasuStock -= 1
}
}
300円入れた後に緑茶を2本購入しました。
その後緑茶を購入すると、在庫は無いので在庫なしのエラーが出ます。
いろはすを購入するとお金が足りないので購入できないとエラーが出ます。
これで結構きれいなコードになったのではないでしょうか!?
独学の範囲内での修正ですのでもっといい修正があると思います。
いい案がありましたら教えていただけると嬉しいです。
以上、最後までご覧いただきありがとうございました。