Skip to content

Instantly share code, notes, and snippets.

@eofster
Last active April 25, 2016 09:11
Show Gist options
  • Save eofster/4d0386267ad7f6380afd422d4de68bee to your computer and use it in GitHub Desktop.
Save eofster/4d0386267ad7f6380afd422d4de68bee to your computer and use it in GitHub Desktop.
VendingMachine with extracted Inventory
struct Item {
let price: Int
let name: String
var count: Int
}
protocol Inventory {
func itemNamed(name: String) throws -> Item
func remove(item: Item) throws
}
class VendingMachine {
let inventory: Inventory
private(set) var coins: Int = 0
init(inventory: Inventory) {
self.inventory = inventory
}
func deposit(coins: Int) {
self.coins += coins
}
func dispense(item: Item) {
print("Dispensing \(item)")
}
func vend(itemNamed name: String) throws {
let item = try inventory.itemNamed(name)
try reduceCoinsBy(item.price)
try removeFromInventory(item)
dispense(item)
}
private func reduceCoinsBy(price: Int) throws {
try validatePrice(price)
coins -= price
}
private func removeFromInventory(item: Item) throws {
do {
try inventory.remove(item)
} catch {
deposit(item.price)
throw error
}
}
private func validatePrice(price: Int) throws {
guard coins >= price else {
throw VendingMachineError.InsufficientFunds(coinsNeeded: price - coins)
}
}
}
enum VendingMachineError: ErrorType {
case InsufficientFunds(coinsNeeded: Int)
}
class SimpleInventory: Inventory {
private var items = [
"Candy Bar": Item(price: 12, name: "Candy Bar", count: 1),
"Chips" : Item(price: 10, name: "Chips", count: 4),
"Pretzels" : Item(price: 7, name: "Pretzels", count: 11)
]
func itemNamed(name: String) throws -> Item {
if let item = items[name] {
return item
} else {
throw InventoryError.InvalidSelection
}
}
func remove(item: Item) throws {
try validateCount(item.count)
var item = item
item.count -= 1
items[item.name] = item
}
private func validateCount(count: Int) throws {
if count == 0 {
throw InventoryError.OutOfStock
}
}
}
enum InventoryError: ErrorType {
case InvalidSelection
case OutOfStock
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment