diff --git a/JuiceMaker/JuiceMaker.xcodeproj/project.pbxproj b/JuiceMaker/JuiceMaker.xcodeproj/project.pbxproj index 6ddf01d1e..3377e1d96 100644 --- a/JuiceMaker/JuiceMaker.xcodeproj/project.pbxproj +++ b/JuiceMaker/JuiceMaker.xcodeproj/project.pbxproj @@ -7,6 +7,9 @@ objects = { /* Begin PBXBuildFile section */ + 1F055BB32A0A13B200B7D604 /* Fruit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F055BB22A0A13B200B7D604 /* Fruit.swift */; }; + 1F055BB52A0A13B900B7D604 /* Juice.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F055BB42A0A13B900B7D604 /* Juice.swift */; }; + 1F055BB72A0A140500B7D604 /* FruitStoreError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F055BB62A0A140500B7D604 /* FruitStoreError.swift */; }; C71CD66B266C7ACB0038B9CB /* FruitStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = C71CD66A266C7ACB0038B9CB /* FruitStore.swift */; }; C73DAF37255D0CDD00020D38 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C73DAF36255D0CDD00020D38 /* AppDelegate.swift */; }; C73DAF39255D0CDD00020D38 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C73DAF38255D0CDD00020D38 /* SceneDelegate.swift */; }; @@ -18,6 +21,9 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 1F055BB22A0A13B200B7D604 /* Fruit.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Fruit.swift; sourceTree = ""; }; + 1F055BB42A0A13B900B7D604 /* Juice.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Juice.swift; sourceTree = ""; }; + 1F055BB62A0A140500B7D604 /* FruitStoreError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FruitStoreError.swift; sourceTree = ""; }; C71CD66A266C7ACB0038B9CB /* FruitStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FruitStore.swift; sourceTree = ""; }; C73DAF33255D0CDD00020D38 /* JuiceMaker.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = JuiceMaker.app; sourceTree = BUILT_PRODUCTS_DIR; }; C73DAF36255D0CDD00020D38 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; @@ -56,6 +62,8 @@ children = ( C73DAF4B255D0D0400020D38 /* JuiceMaker.swift */, C71CD66A266C7ACB0038B9CB /* FruitStore.swift */, + 1F055BB22A0A13B200B7D604 /* Fruit.swift */, + 1F055BB42A0A13B900B7D604 /* Juice.swift */, ); path = Model; sourceTree = ""; @@ -90,6 +98,7 @@ isa = PBXGroup; children = ( C71CD66D266C7B470038B9CB /* Controller */, + D258ECA92A0B6D7F0022D05D /* Errors */, C71CD66F266C7B500038B9CB /* Model */, C71CD671266C7B570038B9CB /* View */, C73DAF44255D0CDF00020D38 /* Info.plist */, @@ -97,6 +106,14 @@ path = JuiceMaker; sourceTree = ""; }; + D258ECA92A0B6D7F0022D05D /* Errors */ = { + isa = PBXGroup; + children = ( + 1F055BB62A0A140500B7D604 /* FruitStoreError.swift */, + ); + path = Errors; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -167,7 +184,10 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 1F055BB32A0A13B200B7D604 /* Fruit.swift in Sources */, + 1F055BB72A0A140500B7D604 /* FruitStoreError.swift in Sources */, C71CD66B266C7ACB0038B9CB /* FruitStore.swift in Sources */, + 1F055BB52A0A13B900B7D604 /* Juice.swift in Sources */, C73DAF3B255D0CDD00020D38 /* ViewController.swift in Sources */, C73DAF37255D0CDD00020D38 /* AppDelegate.swift in Sources */, C73DAF39255D0CDD00020D38 /* SceneDelegate.swift in Sources */, diff --git a/JuiceMaker/JuiceMaker/Controller/AppDelegate.swift b/JuiceMaker/JuiceMaker/Controller/AppDelegate.swift index 862f72076..d82e8c143 100644 --- a/JuiceMaker/JuiceMaker/Controller/AppDelegate.swift +++ b/JuiceMaker/JuiceMaker/Controller/AppDelegate.swift @@ -9,27 +9,18 @@ import UIKit @main class AppDelegate: UIResponder, UIApplicationDelegate { - - func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { - // Override point for customization after application launch. return true } // MARK: UISceneSession Lifecycle func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { - // Called when a new scene session is being created. - // Use this method to select a configuration to create the new scene with. return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) } func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { - // Called when the user discards a scene session. - // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. - // Use this method to release any resources that were specific to the discarded scenes, as they will not return. + } - - } diff --git a/JuiceMaker/JuiceMaker/Controller/SceneDelegate.swift b/JuiceMaker/JuiceMaker/Controller/SceneDelegate.swift index 6b6ac34e9..95c3bac4b 100644 --- a/JuiceMaker/JuiceMaker/Controller/SceneDelegate.swift +++ b/JuiceMaker/JuiceMaker/Controller/SceneDelegate.swift @@ -10,42 +10,28 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { var window: UIWindow? - func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { - // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. - // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. - // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). guard let _ = (scene as? UIWindowScene) else { return } } func sceneDidDisconnect(_ scene: UIScene) { - // Called as the scene is being released by the system. - // This occurs shortly after the scene enters the background, or when its session is discarded. - // Release any resources associated with this scene that can be re-created the next time the scene connects. - // The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead). + } func sceneDidBecomeActive(_ scene: UIScene) { - // Called when the scene has moved from an inactive state to an active state. - // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. + } func sceneWillResignActive(_ scene: UIScene) { - // Called when the scene will move from an active state to an inactive state. - // This may occur due to temporary interruptions (ex. an incoming phone call). + } func sceneWillEnterForeground(_ scene: UIScene) { - // Called as the scene transitions from the background to the foreground. - // Use this method to undo the changes made on entering the background. + } func sceneDidEnterBackground(_ scene: UIScene) { - // Called as the scene transitions from the foreground to the background. - // Use this method to save data, release shared resources, and store enough scene-specific state information - // to restore the scene back to its current state. + } - - } diff --git a/JuiceMaker/JuiceMaker/Controller/ViewController.swift b/JuiceMaker/JuiceMaker/Controller/ViewController.swift index 19f26dc83..106599949 100644 --- a/JuiceMaker/JuiceMaker/Controller/ViewController.swift +++ b/JuiceMaker/JuiceMaker/Controller/ViewController.swift @@ -10,9 +10,6 @@ class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() - // Do any additional setup after loading the view. } - - } diff --git a/JuiceMaker/JuiceMaker/Errors/FruitStoreError.swift b/JuiceMaker/JuiceMaker/Errors/FruitStoreError.swift new file mode 100644 index 000000000..c8a9004e8 --- /dev/null +++ b/JuiceMaker/JuiceMaker/Errors/FruitStoreError.swift @@ -0,0 +1,11 @@ +// +// FruitStoreError.swift +// JuiceMaker +// +// Created by Minsup, Serena on 2023/05/09. +// + +enum FruitStoreError: Error { + case notFoundFruit(Fruit) + case notEnoughStock(Fruit) +} diff --git a/JuiceMaker/JuiceMaker/Model/Fruit.swift b/JuiceMaker/JuiceMaker/Model/Fruit.swift new file mode 100644 index 000000000..3906fe1e6 --- /dev/null +++ b/JuiceMaker/JuiceMaker/Model/Fruit.swift @@ -0,0 +1,18 @@ +// +// Fruit.swift +// JuiceMaker +// +// Created by Minsup, Serena on 2023/05/09. +// + +enum Fruit: String { + case strawberry = "딸기" + case banana = "바나나" + case pineapple = "파인애플" + case kiwi = "키위" + case mango = "망고" + + var name: String { + self.rawValue + } +} diff --git a/JuiceMaker/JuiceMaker/Model/FruitStore.swift b/JuiceMaker/JuiceMaker/Model/FruitStore.swift index ba8486d2b..16ee18948 100644 --- a/JuiceMaker/JuiceMaker/Model/FruitStore.swift +++ b/JuiceMaker/JuiceMaker/Model/FruitStore.swift @@ -4,9 +4,44 @@ // Copyright © yagom academy. All rights reserved. // -import Foundation +typealias Recipe = [Ingredient] +typealias Ingredient = (fruit: Fruit, amount: Int) -// 과일 저장소 타입 class FruitStore { + private var fruitStock: [Fruit: Int] + init(fruitStock: [Fruit: Int] = [ + .strawberry: 10, + .banana: 10, + .mango: 10, + .kiwi: 10, + .pineapple: 10 + ]) { + self.fruitStock = fruitStock + } + + func useValidStock(juiceRecipe: Recipe) throws { + try juiceRecipe.forEach { try validateStock(ingredient: $0) } + juiceRecipe.forEach { spendStock(of: $0.fruit, by: $0.amount)} + } + + private func validateStock(ingredient: Ingredient) throws { + guard let currentAmount = self.fruitStock[ingredient.fruit] else { + throw FruitStoreError.notFoundFruit(ingredient.fruit) + } + + guard currentAmount >= ingredient.amount else { + throw FruitStoreError.notEnoughStock(ingredient.fruit) + } + } + + private func spendStock(of fruit: Fruit, by amount: Int) { + if let currentAmount = self.fruitStock[fruit] { + fruitStock[fruit] = currentAmount - amount + } + } + + func updateStock(of fruit: Fruit, by amount: Int) { + self.fruitStock.updateValue(amount, forKey: fruit) + } } diff --git a/JuiceMaker/JuiceMaker/Model/Juice.swift b/JuiceMaker/JuiceMaker/Model/Juice.swift new file mode 100644 index 000000000..c38fe77b0 --- /dev/null +++ b/JuiceMaker/JuiceMaker/Model/Juice.swift @@ -0,0 +1,39 @@ +// +// Juice.swift +// JuiceMaker +// +// Created by Minsup, Serena on 2023/05/09. +// + +enum Juice: String { + case strawberryJuice = "딸기쥬스" + case bananaJuice = "바나나쥬스" + case kiwiJuice = "키위쥬스" + case pineappleJuice = "파인애플쥬스" + case strawberryBananaJuice = "딸바쥬스" + case mangoJuice = "망고쥬스" + case mangoKiwiJuice = "망고키위쥬스" + + var name: String { + self.rawValue + } + + var recipe: Recipe { + switch self { + case .strawberryJuice: + return [(fruit: .strawberry, amount: 16)] + case .bananaJuice: + return [(fruit: .banana, amount: 2)] + case .kiwiJuice: + return [(fruit: .kiwi, amount: 3)] + case .pineappleJuice: + return [(fruit: .pineapple, amount: 2)] + case .strawberryBananaJuice: + return [(fruit: .strawberry, amount: 10), (fruit: .banana, amount: 1)] + case .mangoJuice: + return [(fruit: .mango, amount: 3)] + case .mangoKiwiJuice: + return [(fruit: .mango, amount: 2), (fruit: .kiwi, amount: 1)] + } + } +} diff --git a/JuiceMaker/JuiceMaker/Model/JuiceMaker.swift b/JuiceMaker/JuiceMaker/Model/JuiceMaker.swift index 862a94f62..67be2a658 100644 --- a/JuiceMaker/JuiceMaker/Model/JuiceMaker.swift +++ b/JuiceMaker/JuiceMaker/Model/JuiceMaker.swift @@ -2,11 +2,24 @@ // JuiceMaker - JuiceMaker.swift // Created by yagom. // Copyright © yagom academy. All rights reserved. -// - -import Foundation +// -// 쥬스 메이커 타입 struct JuiceMaker { + private let fruitStore: FruitStore + + init(fruitStore: FruitStore) { + self.fruitStore = fruitStore + } + func makeJuice(juice: Juice) { + do { + try self.fruitStore.useValidStock(juiceRecipe: juice.recipe) + } catch FruitStoreError.notFoundFruit(let fruit) { + print("\(fruit.name)을/를 찾을 수 없습니다.") + } catch FruitStoreError.notEnoughStock(let fruit) { + print("\(fruit.name) 재고가 없습니다.") + } catch { + print("알 수 없는 에러") + } + } } diff --git a/JuiceMaker/JuiceMaker/View/Base.lproj/Main.storyboard b/JuiceMaker/JuiceMaker/View/Base.lproj/Main.storyboard index 1e3cfe4fc..b1cec0004 100644 --- a/JuiceMaker/JuiceMaker/View/Base.lproj/Main.storyboard +++ b/JuiceMaker/JuiceMaker/View/Base.lproj/Main.storyboard @@ -1,9 +1,9 @@ - + - + @@ -19,19 +19,19 @@ - + - + - + - + - + - + - + - + - +