0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

本記事は、【Swift】自動販売機の例外処理を実装してみた の続きです。

前回までの記事で基本的な処理と例外処理を記述しましたが、
例外処理に改善点があったのでそちらについての対応を行いたいと思います。

前回までの内容をご存知ではない方はそちらをご覧ください。

##前回のおさらい

商品を購入する際の処理で、在庫の確認とお金が足りるかを確認しています。

どちらかの結果がNGだったら例外処理を行うわけですが、
if文を2回使って処理を記述するのはあまりきれいではない気がします。

また、各ケースにこの処理を記述するのは可読性やメンテナンス性が低くなります。
なので、新しい関数を定義しそちらで購入時のチェックを行う様にしたいと思います。

ViewController.swift

    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型を定義しました。
それと同時に購入処理のメソッドの変更と購入条件チェックメソッドを作成しました。
(別のケースはほぼ同じ処理なので省略しました。)

在庫管理メソッドは、購入条件メソッドと被っているので削除しました。

ViewController

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
        }
    }

実際の挙動は次のようになります。
スクリーンショット 2020-12-31 21.15.15.png

300円入れた後に緑茶を2本購入しました。
その後緑茶を購入すると、在庫は無いので在庫なしのエラーが出ます。
いろはすを購入するとお金が足りないので購入できないとエラーが出ます。

これで結構きれいなコードになったのではないでしょうか!?
独学の範囲内での修正ですのでもっといい修正があると思います。

いい案がありましたら教えていただけると嬉しいです。

以上、最後までご覧いただきありがとうございました。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?