This article is a continuation of [Swift] I implemented exception handling for vending machines.
In the previous articles, I described basic processing and exception handling, There was an improvement in exception handling, so I would like to deal with it.
If you do not know the contents up to the last time, please see there.
In the process of purchasing a product, we check inventory and check if we have enough money.
If either result is NG, exception handling will be performed. I feel that it is not very clean to describe the process using the if statement twice.
Also, ** Writing this process in each case is less readable and maintainable. ** ** So, I would like to define a new function and check it at the time of purchase.
ViewController.swift
    var irohasuStock = 3
    var ryokuchaStock = 2
    var gogothiStock = 1
    //Purchase process
    func buyDrink(product: Drink) {
        switch product {
        case .irohasu:
            if !inventoryControl(product: product) {
                print("no stock.")
                return
            }
            if inputMoney - 100 < 0 {
                print("I don't have enough money.")
                return
            }
            inputMoney -= 100
            inputMoneyLabel.text = "Amount of money:\(inputMoney)Circle"
            print("I bought I Lohas.")
        }
    }
    //Inventory control
    func inventoryControl(product: Drink) -> Bool {
        switch product {
        case .irohasu:
            if irohasuStock == 0 {
                return false
            }
            irohasuStock -= 1
            return true
        }
    }
First of all, I defined the enum type SomeError type to display the detailed error. At the same time, I changed the purchase processing method and created a purchase condition check method. (The other case is almost the same process, so I omitted it.)
The inventory management method has been deleted because it overlaps with the purchase condition method.
ViewController
enum SomeError: Error {
    case inventoryShortage   //out of stock
    case lackOfMoney   //Insufficient amount
}
    //Purchase process
    func buyDrink(product: Drink) {
        switch product {
        case .irohasu:
            do {
                try checkCondition(product: product, price: 100)
            } catch {
                print(error)
                return
            }
            inputMoney -= 100
            inputMoneyLabel.text = "Amount of money:\(inputMoney)Circle"
            print("I bought I Lohas.")
        }
    }
    //Purchase condition check
    func checkCondition(product: Drink, price: Int) throws {
        switch product {
        case .irohasu:
            if irohasuStock == 0 {
                throw SomeError.inventoryShortage(reason: "I Lohas is out of stock.")
            } else if inputMoney < price  {
                throw SomeError.lackOfMoney(reason: "\(inputMoney)I can't buy I Lohas because it only contains yen.")
            }
            irohasuStock -= 1
        }
    }
The actual behavior is as follows.

After putting in 300 yen, I bought two bottles of green tea. If you then buy green tea, you will get an out-of-stock error because it is out of stock. When I buy I Lohas, I don't have enough money, so I get an error if I can't buy it.
I think this is a pretty clean code! ?? Since it is a correction within the scope of self-study, I think there is a better correction.
I would be grateful if you could let me know if you have a good idea.
Thank you for watching until the end.
Recommended Posts