###### tags: `README` # ๐Ÿฅค์ฅฌ์Šค ๋ฉ”์ด์ปค > ์ฅฌ์Šค๋ฅผ ์ž…๋ ฅ๋ฐ›์•„ ์žฌ๋ฃŒ๋ฅผ ํ™•์ธํ•˜๊ณ  ์žฌ๋ฃŒ์˜ ์žฌ๊ณ ๊ฐ€ ์žˆ์œผ๋ฉด ๋ ˆ์‹œํ”ผ๋Œ€๋กœ ์ฅฌ์Šค๋ฅผ ๋งŒ๋“ค์–ด ์ฃผ๋Š” ํ”„๋กœ๊ทธ๋žจ **ํ”„๋กœ์ ํŠธ ์ง„ํ–‰ ๊ธฐ๊ฐ„** | 23.05.08.(์›”) ~ 23.05.26.(๊ธˆ) ## ๐Ÿ“š ๋ชฉ์ฐจ - [ํŒ€์›์†Œ๊ฐœ](#-ํŒ€์›-์†Œ๊ฐœ) - [ํƒ€์ž„๋ผ์ธ](#-ํƒ€์ž„๋ผ์ธ) - [์‹œ๊ฐํ™” ๊ตฌ์กฐ](#-์‹œ๊ฐํ™”-๊ตฌ์กฐ) - [์‹คํ–‰ ํ™”๋ฉด](#-์‹คํ–‰-ํ™”๋ฉด) - [ํŠธ๋Ÿฌ๋ธ” ์ŠˆํŒ…](#-ํŠธ๋Ÿฌ๋ธ”-์ŠˆํŒ…) - [ํŒ€ ํšŒ๊ณ ](#-ํŒ€-ํšŒ๊ณ ) - [์ฐธ๊ณ ์ž๋ฃŒ](#-์ฐธ๊ณ ์ž๋ฃŒ) ## ๐Ÿง‘โ€๐Ÿ’ป ํŒ€์› ์†Œ๊ฐœ | <img src="https://hackmd.io/_uploads/B1I0iwo42.jpg" width="100"/> | <img src="https://i.imgur.com/8mg0oKy.jpg" width="100" height="130"/> | <img src="https://hackmd.io/_uploads/BkLspwoVh.png" width="100" height="130"/>| | :-: | :-: | :-: | | [<img src="https://hackmd.io/_uploads/SJEQuLsEh.png" width="20"/> **Yetti**](https://github.com/iOS-Yetti) | [<img src="https://hackmd.io/_uploads/SJEQuLsEh.png" width="20"/> **Mary**](https://github.com/MaryJo-github) |[<img src="https://hackmd.io/_uploads/SJEQuLsEh.png" width="20"/> **yy-ss99**](https://github.com/yy-ss99) | ## โฐ ํƒ€์ž„๋ผ์ธ ###### ๋‚ ์งœ์™€ ์ค‘์š”ํ•œ ์ปค๋ฐ‹ ์œ„์ฃผ๋กœ ์ž‘์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. - **23/05/09 (ํ™”)** - ์ „์ฒด ๊ตฌ์กฐ์—์„œ ํ•„์š”ํ•œ ํƒ€์ž…๋“ค ์„ ์–ธ ๋ฐ ํŒŒ์ผ๋ณ„ ์ •๋ฆฌ - ์žฌ๊ณ ๋ฅผ ์กฐ์ ˆํ•˜๋Š” ๊ธฐ๋Šฅ ๊ตฌํ˜„ - ์—๋Ÿฌ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•œ ์—๋Ÿฌ ํƒ€์ž… ๊ตฌํ˜„ - **23/05/11 (๋ชฉ)** - ์ฅฌ์Šค๋ฅผ ์ฃผ๋ฌธ๋ฐ›๋Š” ๋ฉ”์„œ๋“œ์™€ ๋งŒ๋“œ๋Š” ๊ธฐ๋Šฅ ๋ถ„๋ฆฌ - **23/05/12 (๊ธˆ)** - ๋ ˆ์‹œํ”ผ ๋ฐ˜ํ™˜ ๋ฉ”์„œ๋“œ๋ฅผ ์—ฐ์‚ฐ ํ”„๋กœํผํ‹ฐ๋กœ ์ˆ˜์ • - **23/05/16 (ํ™”)** - ์ฅฌ์Šค ์ฃผ๋ฌธ ๋ฒ„ํŠผ ๋ฉ”์„œ๋“œ ๊ตฌํ˜„ - alert ๋ฉ”์„œ๋“œ ๋ฐ ๊ณผ์ผ ์ˆ˜๋Ÿ‰ ๋ ˆ์ด๋ธ” ๋ณ€๊ฒฝ ๋ฉ”์„œ๋“œ ๊ตฌํ˜„ - ์žฌ๋ฃŒ ๋ถ€์กฑ alert์™€ ์žฌ๊ณ  ์ˆ˜์ • ๋ฒ„ํŠผ์—์„œ ํ™”๋ฉด ์ „ํ™˜ ๊ธฐ๋Šฅ ๊ตฌํ˜„ - **23/05/23 (ํ™”)** - ์žฌ๊ณ  ์ถ”๊ฐ€ ํ™”๋ฉด ์ง„์ž…์‹œ ๊ณผ์ผ์˜ ํ˜„์žฌ ์žฌ๊ณ  ์ˆ˜๋Ÿ‰ ํ‘œ์‹œ ๊ธฐ๋Šฅ ๊ตฌํ˜„ - Stepper๋ฅผ ์ด์šฉํ•œ ์žฌ๊ณ  ์ˆ˜์ • ๊ธฐ๋Šฅ ๊ตฌํ˜„ ## ๐Ÿ” ์‹œ๊ฐํ™” ๊ตฌ์กฐ - UML ํด๋ž˜์Šค ๋‹ค์ด์–ด๊ทธ๋žจ ![](https://hackmd.io/_uploads/ry0Dr26S3.png) ## ๐Ÿ“ฑ์‹คํ–‰ํ™”๋ฉด - iPhone 14 Pro - iPhone SE(3generation) ## ๐Ÿ”จ ํŠธ๋Ÿฌ๋ธ” ์ŠˆํŒ… ๐Ÿ“ฃ์ฝ”๋“œ๋Š” ํ† ๊ธ€ ์ฒ˜๋ฆฌ ๋˜์–ด์žˆ์Šต๋‹ˆ๋‹ค. ### 1๏ธโƒฃ **๊ฐ’ ์ „๋‹ฌ ๋ฐฉ๋ฒ• ๊ฒฐ์ •ํ•˜๊ธฐ** ๐Ÿ”‘ **์ฒซ๋ฒˆ์งธ ๋ฐฉ์•ˆ - delegate pattern** - **์žฅ์ ** - ๊ฐ์ฒด ๊ฐ„์˜ ๊ฒฐํ•ฉ๋„๋ฅผ ๋‚ฎ์ถ”๋Š”๋ฐ ํšจ๊ณผ์ ์ž…๋‹ˆ๋‹ค. ๊ฐ์ฒด๋“ค์€ ๋…๋ฆฝ์ ์œผ๋กœ ๊ฐœ๋ฐœ๋˜๊ณ  ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ๋‹ค๋ฅธ ๊ฐ์ฒด์— ๋ฏธ์น˜๋Š” ์˜ํ–ฅ์ด ์ตœ์†Œํ™”๋ฉ๋‹ˆ๋‹ค. - ์ฝ”๋“œ์˜ ์œ ์ง€๋ณด์ˆ˜์„ฑ๊ณผ ํ™•์žฅ์„ฑ์„ ํ–ฅ์ƒ์‹œํ‚ต๋‹ˆ๋‹ค. `delegate pattern`์‚ฌ์šฉ ์‹œ ๊ธฐ๋Šฅ์„ ํ™•์žฅํ•˜๊ฑฐ๋‚˜ ๋ณ€๊ฒฝ์‹œ์— `protocol`์™€ `extension`์„ ์ˆ˜์ •ํ•˜๊ฑฐ๋‚˜ ํ•ด๋‹น ๊ฐ์ฒด์— ์ ์šฉํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์‰ฝ๊ฒŒ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. - `protocol`๊ณผ `extension`์œผ๋กœ ๊ตฌํ˜„๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋ช…ํ™•ํ•˜๊ฒŒ ์ •์˜ํ•˜๊ณ  ๋ฌธ์„œํ™” ํ•  ์ˆ˜ ์žˆ์–ด ๊ฐœ๋ฐœ์ž๋“ค์ด ์ƒํ˜ธ์ž‘์šฉ์„ ์‰ฝ๊ฒŒ ํŒŒ์•…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. - **๋‹จ์ ** - ์ƒํ™ฉ์— ๋”ฐ๋ผ ๊ฐ์ฒด ๊ฐ„์˜ ์–‘๋ฐฉํ–ฅ ์˜์กด์„ฑ์ด ์ƒ๊ธธ ์ˆ˜ ์žˆ๊ณ  ๊ธฐ๋Šฅ์ด ๋ถ„์‚ฐ ๋จ์œผ๋กœ ๊ฐ์ฒด ๊ฐ„์˜ ๊ด€๊ณ„ ํŒŒ์•…์ด ์–ด๋ ค์›Œ์ง‘๋‹ˆ๋‹ค. <details> <summary>์ฝ”๋“œ</summary> ```swift final class JuiceOrderViewController: UIViewController { ... private func presentChangeStockViewController() { guard let viewController = storyboard? .instantiateViewController(identifier: "ChangeStockViewController") as? ChangeStockViewController else { return } viewController.delegate = self viewController.modalPresentationStyle = .fullScreen present(viewController, animated: true) } ... } extension JuiceOrderViewController: StockDelegate { func getCurrentStock() -> [Int] { return Fruits.allCases.map { fruits in juiceMaker.fruitStore.bringQuantity(of: fruits) } } func addStock(quantities: [Int]) { for (index, fruit) in Fruits.allCases.enumerated() { juiceMaker.fruitStore.addStock(fruit: fruit, quantity: quantities[index]) } } } ``` ```swift protocol StockDelegate: AnyObject { func getCurrentStock() -> [Int] func addStock(quantities: [Int]) } final class ChangeStockViewController: UIViewController { ... weak var delegate: StockDelegate? ... private func initializeStockLabels() { guard let currentStock = delegate?.getCurrentStock() else { return } initialStock = currentStock for (index, label) in stockChangeLabels.enumerated() { label.text = "\(initialStock[index])" } } @IBAction private func hitDismissButton(_ sender: UIBarButtonItem) { delegate?.addStock(quantities: additionalStock) dismiss(animated: true) } ... } ``` </details> <br> ๐Ÿ”‘ **๋‘๋ฒˆ์งธ ๋ฐฉ์•ˆ - closure** - **์žฅ์ ** - ๊ฐ„๋‹จํ•˜๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. - **๋‹จ์ ** - ์—ฌ๋Ÿฌ ๊ฐœ๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๊ณ  ํ•  ์ˆ˜๋ก ์ฝ”๋“œ๊ฐ€ ์กฐ๋ฐ€ํ•ด์ ธ์„œ ๊ฐ€๋…์„ฑ์„ ํ•ด์น ๋งŒํ•œ ์šฐ๋ ค๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. <details> <summary>์ฝ”๋“œ</summary> ```swift final class JuiceOrderViewController: UIViewController { ... private func presentChangeStockViewController() { guard let viewController = storyboard? .instantiateViewController(identifier: "ChangeStockViewController") as? ChangeStockViewController else { return } viewController.getCurrentHandler = self.getCurrentStock viewController.addStockHandler = self.addStock viewController.modalPresentationStyle = .fullScreen present(viewController, animated: true) } private func getCurrentStock() -> [Int] { return Fruits.allCases.map { fruits in juiceMaker.fruitStore.bringQuantity(of: fruits) } } private func addStock(_ quantities: [Int]) { for (index, fruit) in Fruits.allCases.enumerated() { juiceMaker.fruitStore.addStock(fruit: fruit, quantity: quantities[index]) } } ... } ``` ```swift final class ChangeStockViewController: UIViewController { ... var getCurrentHandler: (() -> [Int])? var addStockHandler: ((_ quantities:[Int]) -> Void)? ... private func initializeStockLabels() { guard let currentStock = getCurrentHandler?() else { return } initialStock = currentStock for (index, label) in stockChangeLabels.enumerated() { label.text = "\(initialStock[index])" } } @IBAction private func hitDismissButton(_ sender: UIBarButtonItem) { addStockHandler?(additionalStock) dismiss(animated: true) } ... } ``` </details> <br> ๐Ÿ”‘ **์„ธ๋ฒˆ์งธ ๋ฐฉ์•ˆ - notification** - **์žฅ์ ** - ๋‹ค์ˆ˜์˜ ๊ฐ์ฒด์— ๋™์‹œ์— ์ด๋ฒคํŠธ๋ฅผ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. - ์—ฌ๋Ÿฌ๊ฐ€์ง€ ์„ค์ •ํ•ด์ค„ ํ•„์š”์—†์ด ์งง์€ ์ฝ”๋“œ๋กœ ์‰ฝ๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. - **๋‹จ์ ** - ์˜ค๋ฅ˜์˜ ์ถ”์ ์ด ์‰ฝ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์™œ๋ƒํ•˜๋ฉด `notificationName` ๋˜๋Š” `userInfo`์˜ `key`๊ฐ’์ด `String`๊ฐ’์œผ๋กœ ๋“ค์–ด๊ฐ€๊ฒŒ ๋˜๋Š”๋ฐ ์ด ๋ถ€๋ถ„์— ์˜คํƒ€๊ฐ€ ๋‚˜์„œ `post`ํ•˜๋Š” ๋ถ€๋ถ„๊ณผ `addObserver`๋ถ€๋ถ„์ด ๋‹ฌ๋ผ์ง€๊ฒŒ ๋˜๋”๋ผ๋„ ์ปดํŒŒ์ผ์ด๋‚˜ ๋Ÿฐํƒ€์ž„์—์„œ ์—๋Ÿฌ๋ฅผ ๋ฑ‰์–ด์ฃผ์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์ง์ ‘ ๋ˆˆ์œผ๋กœ ๋ฐœ๊ฒฌํ•˜์ง€ ์•Š๋Š” ์ด์ƒ ๋…ธํ‹ฐํ”ผ์ผ€์ด์…˜์—์„œ ๋‚˜๋Š” ์—๋Ÿฌ์ธ์ง€ ์ธ์ง€ํ•˜๊ธฐ ์‰ฝ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. - `post`๊ฐ€ ๋œ ํ›„์— ๋‹ค์‹œ `post`ํ•œ ๋ถ€๋ถ„์œผ๋กœ ์ •๋ณด๋ฅผ ๋ฐ›์•„์˜ฌ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. <details> <summary>์ฝ”๋“œ</summary> ```swift final class JuiceOrderViewController: UIViewController { ... override func viewDidLoad() { super.viewDidLoad() NotificationCenter.default.addObserver(self, selector: #selector(addStock(_:)), name: Notification.Name("changeStock"), object: nil) } ... @objc func addStock(_ notification: NSNotification) { guard let notifi = notification.userInfo?["additionalStock"] as? [Int] else { return } for (index, fruit) in Fruits.allCases.enumerated() { juiceMaker.fruitStore.addStock(fruit: fruit, quantity: notifi[index]) } } } ``` ```swift final class ChangeStockViewController: UIViewController { ... @IBAction private func hitDismissButton(_ sender: UIBarButtonItem) { NotificationCenter.default.post(name: Notification.Name("changeStock"), object: nil, userInfo: ["additionalStock": additionalStock]) dismiss(animated: true) } ... } ``` </details> <br> โ†’ **์ฝ”๋“œ๋กœ ์ง์ ‘ ๊ตฌํ˜„ํ•ด๋ณด๊ณ  ์žฅ๋‹จ์ ์„ ๊ณ ๋ คํ•œ ๊ฒฐ๊ณผ `delegate pattern`์„ ์‚ฌ์šฉํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.** ### **2๏ธโƒฃ ํ™”๋ฉด ์ „ํ™˜ ๋ฐฉ๋ฒ• ์„ ํƒํ•˜๊ธฐ** ๐Ÿ”’ **๊ณ ๋ฏผํ–ˆ๋˜ ์  :๋„ค๋น„๊ฒŒ์ด์…˜ vs ๋ชจ๋‹ฌ** <br> ๊ณผ์ผ์˜ ์žฌ๊ณ ๊ฐ€ ๋ถ€์กฑํ•  ๊ฒฝ์šฐ๋‚˜ `JuiceOrderViewController`์—์„œ ์žฌ๊ณ  ์ˆ˜์ • ๋ฒ„ํŠผ์„ ํ„ฐ์น˜ํ•  ๊ฒฝ์šฐ์— `ChangeStockViewController`์—์„œ ๊ณผ์ผ์˜ ์žฌ๊ณ ๋ฅผ ์ถ”๊ฐ€ํ•œ ๋’ค `JuiceOrderViewController`๋กœ ๋Œ์•„๊ฐ€๋Š” ํ™”๋ฉด ์ „ํ™˜์€ ์–ด๋–ค ๋ฐฉ์‹์ด ์ข‹์„์ง€ ๊ณ ๋ฏผํ–ˆ์Šต๋‹ˆ๋‹ค. - ๋„ค๋น„๊ฒŒ์ด์…˜ ์ธํ„ฐํŽ˜์ด์Šค ํŠน์ง• - `Navigation Controller`๋Š” ์ฃผ๋กœ ๊ณ„์ธต์  ๊ตฌ์กฐ์˜ ํ™”๋ฉด์ „ํ™˜์„ ์œ„ํ•ด ์‚ฌ์šฉ๋˜๋Š” ๋“œ๋ฆด ๋‹ค์šด ์ธํ„ฐํŽ˜์ด์Šค(๊ฐ ์„ ํƒํ•  ์ˆ˜ ์žˆ๋Š” ํ•ญ๋ชฉ์— ๋Œ€ํ•œ ์„ธ๋ถ€ํ•ญ๋ชฉ์ด ์กด์žฌํ•˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค)์ž…๋‹ˆ๋‹ค. - ๋ทฐ ์ปจํŠธ๋กค๋Ÿฌ ์Šคํƒ์— ๋”ฐ๋ผ ํ™”๋ฉด์„ ์Šคํƒ์— ํ‘ธ์‹œ(`push`)ํ•˜๊ฑฐ๋‚˜ ํŒ(`pop`)ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ํ™”๋ฉด ์ „ํ™˜์„ ํ•ฉ๋‹ˆ๋‹ค. - ๋ชจ๋‹ฌ ํŠน์ง• - ํ™”๋ฉด์„ ๋‹ค๋ฅธ ํ™”๋ฉด์œ„์— ๋„์›Œ์„œ ์‚ฌ์šฉ์ž์˜ ์ด๋ชฉ์„ ๋Œ๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. - ํ˜„์žฌ ๋ทฐ ์ปจํŠธ๋กค๋Ÿฌ ์œ„์— ๊ฒน์ณ์ ธ์„œ ํ‘œ์‹œ๋˜๋ฉฐ ๋‹ค๋ฅธ ๋ทฐ ์ปจํŠธ๋กค๋Ÿฌ๋กœ ์ด๋™ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋‹ซ์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค. - ๋ชจ๋‹ฌ์€ ์–ผ๋Ÿฟ์„ ํ†ตํ•ด ํ™•์ธ/์ทจ์†Œ ์ค‘ ํ•˜๋‚˜๋ฅผ ์„ ํƒํ•˜๊ฑฐ๋‚˜ ์•ก์…˜์‹œํŠธ์—์„œ ์„ ํƒ์„ ํ•˜๋Š” ๋“ฑ์˜ ํŠน์ • ์„ ํƒ์„ ์™„๋ฃŒ ํ•ด์•ผํ•œ๋‹ค๋Š” ํŠน์ง•์ด ์žˆ์Šต๋‹ˆ๋‹ค. โ†’ ๋„ค๋น„๊ฒŒ์ด์…˜ ์ธํ„ฐํŽ˜์ด์Šค๋Š” ์ฃผ๋กœ ์•ฑ์˜ ๋ฉ”์ธ ํƒ์ƒ‰ ํ๋ฆ„๊ณผ ํ™”๋ฉด ์ „ํ™˜์„ ๊ด€๋ฆฌํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๊ณ , ๋ชจ๋‹ฌ์€ ์ถ”๊ฐ€ ์ •๋ณด๋‚˜ ์ž„์‹œ ์ž‘์—…์— ํ•„์š”ํ•œ ํ™”๋ฉด ์ „ํ™˜์— ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. `ChangeStockViewController`๋Š” ์ฅฌ์Šค ์ฃผ๋ฌธ ๊ณผ๋Š” ๊ด€๊ณ„์—†์ด ์žฌ๊ณ ๋ฅผ ์ˆ˜์ •ํ•˜๋Š” ํ™”๋ฉด์„ ๋„์šฐ๋Š” ์—ญํ• ์ž…๋‹ˆ๋‹ค. ์ด๋Š” ํ๋ฆ„์ƒ ์—ฐ๊ฒฐ๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— **๋ชจ๋‹ฌ**๋กœ ํ™”๋ฉด์ „ํ™˜์„ ํ•˜๋Š” ๊ฒƒ์ด ๋” ์ ์ ˆํ•˜๋‹ค๊ณ  ํŒ๋‹จํ–ˆ์Šต๋‹ˆ๋‹ค. ๋งŒ์•ฝ ์žฌ๊ณ  ์ถ”๊ฐ€ ๋ทฐ์ปจํŠธ๋กค๋Ÿฌ๊ฐ€ ์•„๋‹Œ โ€œ์ฃผ๋ฌธ์„ ํ™•์ธ์ค‘์ž…๋‹ˆ๋‹คโ€ฆโ€ ๋ฉ”์‹œ์ง€๋ฅผ ๋„์›Œ์ฃผ๋Š” ๋ทฐ์ปจํŠธ๋กค๋Ÿฌ๋กœ ํ™”๋ฉด์ „ํ™˜์„ ํ•œ๋‹ค๋ฉด ์ฅฌ์Šค ์ฃผ๋ฌธ๊ณผ ๊ฐ™์€ ํ๋ฆ„์ด๊ธฐ ๋•Œ๋ฌธ์— ์ด๋Ÿด ๋•Œ์—๋Š” ๋„ค๋น„๊ฒŒ์ด์…˜ ์ธํ„ฐํŽ˜์ด์Šค ๋ฐฉ์‹์ด ๋” ์ ์ ˆํ•  ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. <br> ### **3๏ธโƒฃ ์—ฌ๋Ÿฌ๊ฐœ์˜ ๋ฒ„ํŠผ์„ ํ•œ ๊ฐœ์˜ IBAction์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๊ธฐ** ๐Ÿ”’ **๋ฌธ์ œ์ ** <br> `JuiceOrderViewController`์—๋Š” ์ฅฌ์Šค๋ฅผ ์ฃผ๋ฌธํ•˜๋Š” ์—ฌ๋Ÿฌ๊ฐœ์˜ ๋ฒ„ํŠผ์ด ์žˆ๊ณ , ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด `placeAnOrder(for:)`๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด ๊ฐ๊ฐ์˜ IBAction์„ ๋งŒ๋“ค์–ด์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด๋ ‡๊ฒŒ ๊ตฌํ˜„ํ•˜๋‹ˆ ์ฝ”๋“œ๊ฐ€ ์ค‘๋ณต๋˜๋Š” ๋ฌธ์ œ์ ์ด ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. <details> <summary>์ฝ”๋“œ</summary> ```swift @IBAction private func hitStrawberryJuiceOrderButton(_ sender: UIButton) { placeAnOrder(for: .strawberryJuice) } @IBAction private func hitBananaJuiceOrderButton(_ sender: UIButton) { placeAnOrder(for: .bananaJuice) } ... ``` </details> <br> ๐Ÿ”‘ **ํ•ด๊ฒฐ๋ฐฉ๋ฒ• ์ฒซ๋ฒˆ์งธ** <br> ์ฒซ๋ฒˆ์งธ๋กœ ์ฐพ์•˜๋˜ ํ•ด๊ฒฐ์ฑ…์€ `tag`๋ฅผ ์ด์šฉํ•˜๋Š” ๋ฐฉ์‹์ด์—ˆ๊ณ  ์ด๋ฅผ ์ด์šฉํ•˜๋ฉด ์—ฌ๋Ÿฌ๊ฐœ์˜ ๋ฒ„ํŠผ์„ ํ•˜๋‚˜์˜ IBAction์œผ๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด ์ค‘๋ณต๋˜๋Š” ์ฝ”๋“œ๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์–ด๋–ค ๋ฒ„ํŠผ์ด `tag`๊ฐ€ ๋ช‡์ธ์ง€ ํ•œ ๋ˆˆ์— ์•Œ๊ธฐ ์–ด๋ ค์› ๊ณ , ๊ฐ ๋ฒ„ํŠผ์˜ ํƒœ๊ทธ๋ฅผ ํ•˜๋‚˜ํ•˜๋‚˜ ์ง€์ •ํ•ด์ฃผ์–ด์•ผํ•ด์„œ ํ™•์žฅ์„ฑ์ด ์ข‹์ง€ ์•Š๋‹ค๊ณ  ํŒ๋‹จํ•˜์˜€์Šต๋‹ˆ๋‹ค. <details> <summary>์ฝ”๋“œ</summary> ```swift private func searchJuice(by tag: Int) -> Juice? { switch tag { case 1: return .strawberryJuice case 2: return .bananaJuice ... default: return nil } } @IBAction private func hitJuiceOrderButton(_ sender: UIButton) { guard let choosedJuice = searchJuice(by: sender.tag) else { return } placeAnOrder(for: choosedJuice) } ``` </details> <br> ๐Ÿ”‘ **์ตœ์ข… ํ•ด๊ฒฐ๋ฐฉ๋ฒ•** <br> ์ตœ์ข…์ ์œผ๋กœ ์—ฌ๋Ÿฌ๊ฐœ์˜ ๋ฒ„ํŠผ์„ ํ•˜๋‚˜์˜ IBAction์œผ๋กœ ๋ฌถ์–ด์ฃผ๊ณ , ๋ฒ„ํŠผ์˜ `title`์„ ๊ธฐ์ค€์œผ๋กœ ์ฅฌ์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•ด์ฃผ๋„๋ก ์ˆ˜์ •ํ•˜์˜€์Šต๋‹ˆ๋‹ค. `tag` ๋ฐฉ๋ฒ•๊ณผ๋Š” ๋‹ฌ๋ฆฌ `title`์ด ๋ฌธ์ž์—ด์ด๊ธฐ ๋•Œ๋ฌธ์— ์–ด๋–ค ๋ฒ„ํŠผ์ธ์ง€ ํ•œ ๋ˆˆ์— ์•Œ๊ธฐ ์‰ฌ์›Œ ํ•ด๋‹น ๋ฐฉ๋ฒ•์œผ๋กœ ์ฑ„ํƒํ•˜์˜€์Šต๋‹ˆ๋‹ค. <details> <summary>์ฝ”๋“œ</summary> ```swift private func searchJuice(by tag: Int) -> Juice? { switch tag { case 1: return .strawberryJuice case 2: return .bananaJuice ... default: return nil } } @IBAction private func hitJuiceOrderButton(_ sender: UIButton) { guard let choosedJuice = searchJuice(by: sender.tag) else { return } placeAnOrder(for: choosedJuice) } ``` </details> <br> ### **4๏ธโƒฃ ๋งค์ง๋ฆฌํ„ฐ๋Ÿด ์ œ๊ฑฐํ•˜๊ธฐ** ๐Ÿ”’ **๋ฌธ์ œ์ ** <br> ์ฅฌ์Šค๋ฅผ ์ฃผ๋ฌธํ•˜๋Š” ๋ฒ„ํŠผ์˜ title์— ๋”ฐ๋ผ ์ฅฌ์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•ด์ฃผ๋Š” `searchJuice`๋ฉ”์„œ๋“œ๋ฅผ ๋งŒ๋“ค์–ด์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ switch๋ฌธ ์•ˆ์— ๋ฒ„ํŠผ์˜ ํƒ€์ดํ‹€์„ ๋ฌธ์ž์—ด๋กœ ์ง์ ‘ ์ž‘์„ฑํ•ด์ฃผ๋‹ˆ ๋งค์ง๋ฆฌํ„ฐ๋Ÿด์ด ๋˜์–ด ๋ฌธ์ž์—ด์˜ ์˜๋ฏธ๋ฅผ ํ•œ ๋ˆˆ์— ์•Œ๊ธฐ ์–ด๋ ค์› ์Šต๋‹ˆ๋‹ค. <details> <summary>์ฝ”๋“œ</summary> ```swift private func searchJuice(by buttonTitle: String) -> Juice? { switch buttonTitle { case "๋”ธ๊ธฐ์ฅฌ์Šค ์ฃผ๋ฌธ": return .strawberryJuice case "๋ฐ”๋‚˜๋‚˜์ฅฌ์Šค ์ฃผ๋ฌธ": return .bananaJuice ... default: return nil } } ``` </details> <br> ๐Ÿ”‘ **ํ•ด๊ฒฐ๋ฐฉ๋ฒ•** <br> ๋งค์ง๋ฆฌํ„ฐ๋Ÿด์„ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด Juiceํƒ€์ž…์˜ ์—ฐ๊ด€๊ฐ’ ํ™œ์šฉ, ์—ฐ์‚ฐ ํ”„๋กœํผํ‹ฐ ํ™œ์šฉ ๋“ฑ ๋‹ค์–‘ํ•œ ๋ฐฉ๋ฒ•์„ ์ƒ๊ฐํ•ด๋ดค์ง€๋งŒ ์ฝ”๋“œ๊ฐ€ ๊ธธ์–ด์ ธ ์˜คํžˆ๋ ค ๊ฐ€๋…์„ฑ์ด ๋–จ์–ด์งˆ ๊ฒƒ ๊ฐ™์•˜์Šต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์„ ์ฐพ๋‹ค๊ฐ€ case๊ฐ€ ์—†๋Š” enum์„ ํ™œ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ํ•ด๋‹น ๋ฐฉ๋ฒ•์€ ์—ด๊ฑฐํ˜•์ด์ง€๋งŒ case๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์— ์ดˆ๊ธฐํ™”๋Š” ์•ˆ๋˜๊ณ , ์ˆœ์ˆ˜ํžˆ namespace๋กœ์„œ๋งŒ ์ž‘๋™ ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ์žฅ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ฅฌ์Šค๋ฉ”์ด์ปค์— ์ ์šฉ์€ `ButtonTitle` ์—ด๊ฑฐํ˜•์— ํƒ€์ž…ํ”„๋กœํผํ‹ฐ๋กœ ๊ฐ ๋ฒ„ํŠผ์˜ ํƒ€์ดํ‹€์ธ String๊ฐ’์„ ํ• ๋‹นํ•ด์ฃผ์—ˆ๊ณ  ๊ทธ ๊ฐ’์„ ๊ฐ€์ ธ์™€ switch๋ฌธ์—์„œ ํ˜ธ์ถœํ•ด์ค„ ์ˆ˜ ์žˆ๋„๋ก ํ•˜์˜€์Šต๋‹ˆ๋‹ค. <details> <summary>์ฝ”๋“œ</summary> ```swift private enum ButtonTitle { static let strawberryJuiceOrder = "๋”ธ๊ธฐ์ฅฌ์Šค ์ฃผ๋ฌธ" static let bananaJuiceOrder = "๋ฐ”๋‚˜๋‚˜์ฅฌ์Šค ์ฃผ๋ฌธ" ... } private func searchJuice(by buttonTitle: String) -> Juice? { switch buttonTitle { case ButtonTitle.strawberryJuiceOrder: return .strawberryJuice case ButtonTitle.bananaJuiceOrder: return .bananaJuice ... default: return nil } } ``` </details> <br> ### **5๏ธโƒฃ ์ด๋‹ˆ์…œ๋ผ์ด์ €๊ฐ€ ์‹คํ–‰๋˜๊ธฐ ์ „์— ๋‹ค๋ฅธ ํ”„๋กœํผํ‹ฐ์—์„œ ์ดˆ๊ธฐ๊ฐ’ ๋ฐ›๊ธฐ** ๐Ÿ”’ **๋ฌธ์ œ์ ** <br> `Cannot use instance member 'initialStock' within property initializer; property initializers run before 'self' is available` ์ดˆ๊ธฐ๊ฐ’์„ ์ฃผ๋ ค๋Š” ์ƒํ™ฉ์—์„œ ์ด๋‹ˆ์…œ๋ผ์ด์ €๊ฐ€ ์‹คํ–‰๋˜๊ธฐ ์ „์— .self์— ์ ‘๊ทผํ•ด์„œ ๊ฐ’์„ ๊ฐ€์ ธ์˜ค๋ ค๊ณ  ํ•ด์„œ ์ด๋Ÿฐ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. <details> <summary>์ฝ”๋“œ</summary> ``` swift let initialStock = 10 var fruitStock: [Fruits: Int] = [ .strawberry: initialStock, .banana: initialStock, .pineapple: initialStock, .mango: initialStock, .kiwi: initialStock ] ``` </details> <br> ๐Ÿ”‘ **ํ•ด๊ฒฐ๋ฐฉ๋ฒ• ์ฒซ๋ฒˆ์งธ** <br> - ์ฒซ๋ฒˆ์งธ ๋ฐฉ์•ˆ : `static` ์‚ฌ์šฉ `static`ย ํ‚ค์›Œ๋“œ ์žฅ์  - `static`์€ ํ•ด๋‹น ๊ตฌ์กฐ์ฒด์˜ ์ธ์Šคํ„ด์Šค๋‚˜ ํด๋ž˜์Šค๊ฐ€ ์ƒ์„ฑ๋˜์ง€ ์•Š์•„๋„ ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ์žฅ์  ๋•Œ๋ฌธ์— ์ „์—ญ์ ์ธ ๊ธฐ๋Šฅ์„ ์ œ๊ณต ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. - ํด๋ž˜์Šค๋‚˜ ๊ตฌ์กฐ์ฒด์˜ ์ธ์Šคํ„ด์Šค์™€๋Š” ๋…๋ฆฝ์ ์ธ ๊ฐ’์„ ์ €์žฅํ•  ํ•„์š”๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐย `static`ย ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ „์—ญ์œผ๋กœ ์ •์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ „์ฒด์—์„œ ์‚ฌ์šฉํ•˜๋Š” ์„ค์ •๊ฐ’์ด๋‚˜ ์ƒ์ˆ˜ ๊ฐ’์„ ์ •์˜ํ•  ๋•Œ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. `static`ย ํ‚ค์›Œ๋“œ ๋‹จ์  - `static`์œผ๋กœ ์„ ์–ธ๋˜๋ฉด ํ”„๋กœํผํ‹ฐ๋‚˜ ๋ฉ”์„œ๋“œ๋Š” ์˜ค๋ฒ„๋ผ์ด๋”ฉ์ด ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. - `static`ย ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์„ ์–ธ๋œ ํ”„๋กœํผํ‹ฐ๋‚˜ ๋ฉ”์„œ๋“œ๋Š” ํด๋ž˜์Šค๋‚˜ ๊ตฌ์กฐ์ฒด ๋‚ด๋ถ€์—์„œ๋งŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ๋‹ค๋ฅธ ๋ชจ๋“ˆ์—์„œ ์ ‘๊ทผํ•˜๊ธฐ ์–ด๋ ต์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š”ย `public static`๊ณผ ๊ฐ™์ด ์„ ์–ธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. - `static`ย ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์„ ์–ธ๋œ ํ”„๋กœํผํ‹ฐ๋‚˜ ๋ฉ”์„œ๋“œ๋Š” ๋ฉ”๋ชจ๋ฆฌ ๋‚ด์— ๋”ฑ ํ•œ ๋ฒˆ๋งŒ ํ• ๋‹น๋˜๋ฏ€๋กœ, ๋Ÿฐํƒ€์ž„ ๋™์•ˆ ๊ฐ’์ด ๋ณ€๊ฒฝ๋  ๊ฒฝ์šฐ ๋‹ค๋ฅธ ์ธ์Šคํ„ด์Šค๋‚˜ ์Šค๋ ˆ๋“œ์—์„œ๋„ ๋ณ€๊ฒฝ๋œ ๊ฐ’์ด ๋ฐ˜์˜๋ฉ๋‹ˆ๋‹ค. - ์ข…๋ฃŒ์‹œ๊นŒ์ง€ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ํ• ๋‹น๋œ ์ฑ„๋กœ ์กด์žฌํ•˜๋ฏ€๋กœ ๋งŽ์€ย `static`ย ์ƒ์„ฑ์‹œ ํ”„๋กœ๊ทธ๋žจ ํผํฌ๋จผ์Šค์— ์•…์˜ํ–ฅ์„ ์ค„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. โ†’`stactic` ์žฅ๋‹จ์ ์„ ๊ณ ๋ คํ–ˆ์„ ๋•Œ ์ง€๊ธˆ ํ˜„์žฌ์— ์ฝ”๋“œ์— ์ ์ ˆํ•œ ๋” ์ข‹์€ ๋ฐฉ์•ˆ์ด ์žˆ์„ ๊ฒƒ์ด๋ผ๊ณ  ํŒ๋‹จํ–ˆ์Šต๋‹ˆ๋‹ค. <details> <summary>์ฝ”๋“œ</summary> ```swift static let initialStock = 10 var fruitStock: [Fruits: Int] = [ .strawberry: initialStock, .banana: initialStock, .pineapple: initialStock, .mango: initialStock, .kiwi: initialStock ] ``` </details> <br> ๐Ÿ”‘ **ํ•ด๊ฒฐ๋ฐฉ๋ฒ• ๋‘๋ฒˆ์งธ** <br> - ๋‘ ๋ฒˆ์งธ ๋ฐฉ์•ˆ`lazy`ย ํ‚ค์›Œ๋“œ ์‚ฌ์šฉ `lazy` ํ‚ค์›Œ๋“œ ํŠน์ง• - ํ”„๋กœํผํ‹ฐ๊ฐ€ ์ฒ˜์Œ ์‚ฌ์šฉ๋˜๊ธฐ ์ „๊นŒ์ง€๋Š” ๋ฉ”๋ชจ๋ฆฌ์— ์˜ฌ๋ผ๊ฐ€์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์‹œ๊ฐ„์ด ์˜ค๋ž˜ ์†Œ์š”๋˜๋Š” ์ž‘์—…์—ย `lazy`ย ๋ฅผ ๋ถ™์ด๋ฉด ์‹ค์ œ ์ž‘์—…์ด ์ง„ํ–‰๋˜๊ธฐ ์ „๊นŒ์ง€๋Š” ์‹คํ–‰๋˜์ง€ ์•Š์•„ ํšจ์œจ์ ์ž…๋‹ˆ๋‹ค. ์ž‘์—…์ด ๋‹ค๋ฅธ ์ž‘์—…์— ์˜์กด์ ์ธ ๊ฒฝ์šฐ์— ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. โ†’ `initialStock`์€ ์ „์—ญ์ ์œผ๋กœ ์ ‘๊ทผํ•  ํ•„์š”์—†๊ณ ,ย `fruitStock`๋ฅผ ์ดˆ๊ธฐํ™” ํ•  ๋•Œ๋งŒ ํ•„์š”ํ•˜๋‹ค๊ณ  ํŒ๋‹จํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œย `static let initialStock`์„ ํ™œ์šฉํ•˜๋Š” ๋Œ€์‹ ์—ย `fruitStock`๋ฅผย `lazy var`๋กœ ๋งŒ๋“ค์–ด ์ ‘๊ทผ ์‹œ์— ๊ฐ’์„ ํ• ๋‹นํ•˜๋„๋ก ์ˆ˜์ •ํ•˜์˜€์Šต๋‹ˆ๋‹ค. <details> <summary>์ฝ”๋“œ</summary> ``` swift private let initialStock = 10 private(set) lazy var fruitStock: [Fruits: Int] = [ .strawberry: initialStock, .banana: initialStock, .pineapple: initialStock, .mango: initialStock, .kiwi: initialStock ] ``` </details> <br> ๐Ÿ”‘ **์ตœ์ข… ํ•ด๊ฒฐ๋ฐฉ๋ฒ•** <br> - `init` ๋ฉ”์„œ๋“œ ํ™œ์šฉ - `lazy`๋Š” ํ”„๋กœํผํ‹ฐ์˜ ์ดˆ๊ธฐํ™” ๊ณผ์ •์ด ๋ณต์žกํ•˜๊ฑฐ๋‚˜ ๋‹ค๋ฅธ ๊ฐ’์— ์˜์กด์„ฑ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๊ฒฝ์šฐ ์ดˆ๊ธฐํ™” ๋  ๋•Œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ์–ด์„œ ์ฝ”๋“œ์˜ ๋ณต์žก์„ฑ์„ ์ฆ๊ฐ€์‹œํ‚จ๋‹ค๋Š” ๋‹จ์ ์ด ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ๋ฐฉ์•ˆ์ด ์žˆ์ง€ ์•Š์„๊นŒ ๊ณ ๋ฏผํ•˜๋˜ ์ค‘์— `init`๋ฉ”์„œ๋“œ๋ฅผ ํ™œ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค๋Š” ์ƒ๊ฐ์ด ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. - `initialStock`์˜ ์ดˆ๊ธฐ๊ฐ’์€ ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™์•„ `init`๋ฉ”์„œ๋“œ์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋ฐ›์•„์ฃผ์—ˆ๊ณ , `fruitStock`์€ `initialStock`ํ”„๋กœํผํ‹ฐ๋ฅผ ํ†ตํ•ด ์ดˆ๊ธฐ ์žฌ๊ณ ๋ฅผ ์„ค์ •ํ•˜๋„๋ก ๊ตฌํ˜„ํ•˜์˜€์Šต๋‹ˆ๋‹ค. โ†’ `lazy`ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด `fruitStock`์ด ์ฒ˜์Œ ์‚ฌ์šฉ๋  ๋•Œ ์ดˆ๊ธฐํ™”๋˜์—ˆ์ง€๋งŒ ๋ณ€๊ฒฝ๋œ ์ฝ”๋“œ์—์„œ๋Š” `FruitStore` ์ธ์Šคํ„ด์Šค๊ฐ€ ์ƒ์„ฑ๋  ๋•Œ ๋งŒ๋“ค์–ด์ง€๊ธฐ ๋•Œ๋ฌธ์— ๋” ์ผ์ฐ ์ดˆ๊ธฐํ™”ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. <details> <summary>์ฝ”๋“œ</summary> ``` swift init(initialStock: Int = 10) { self.fruitStock = [.strawberry: initialStock, .banana: initialStock, .pineapple: initialStock, .kiwi: initialStock, .mango: initialStock] } ``` </details> ### 6๏ธโƒฃ **์˜ค๋ฅ˜ ์ฒ˜๋ฆฌ (Result type)** ๐Ÿ”’ **๋ฌธ์ œ์ ** <br> Result Type์˜ success๋ถ€๋ถ„์— Bool๊ฐ’์„ ๋„ฃ์–ด์ฃผ์—ˆ์ง€๋งŒ ์‹ค์งˆ์ ์œผ๋กœ ๋ฐ˜ํ™˜๋˜๋Š” true๊ฐ’์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ๋“ค์–ด๊ฐ€๋Š” ๊ฐ’์ด true์ด๋“  false์ด๋“  ํ”„๋กœ๊ทธ๋žจ ์‹คํ–‰์—๋Š” ๋ฌธ์ œ๊ฐ€ ์—†์—ˆ๊ณ  ๊ฒฐ๊ณผ์ ์œผ๋กœ success์˜ true๊ฐ’์€ ์“ธ๋ชจ์—†๋Š” ๊ฐ’์ด ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. <details> <summary>์ฝ”๋“œ</summary> ``` swift private func checkFruitStock(_ recipe: [Recipe]) -> Result<Bool, JuiceMakerError> { for fruit in recipe { guard let stock = fruitStore.fruitStock[fruit.name] else { return .failure(JuiceMakerError.notExistFruit) } guard stock >= fruit.quantity else { return .failure(JuiceMakerError.ingredientShortage) } } return .success(true) } ``` </details> <br> ๐Ÿ”‘ **ํ•ด๊ฒฐ๋ฐฉ๋ฒ•** <br> ํŠน์ •ํ•œ ๊ฐ’์ด ๋ฐ˜ํ™˜๋˜์–ด์•ผ ํ•œ๋‹ค๋Š” ๊ณ ์ •๊ด€๋… ๋•Œ๋ฌธ์— ์—ฌ๋Ÿฌ ๊ฐ’์„ ๋„ฃ์–ด ์‹œ๋„ํ•ด๋ณด์•˜์ง€๋งŒ ๊ฒฐ๊ตญ ๋ชจ๋‘ ๋ถˆํ•„์š”ํ•œ ๊ฐ’์ด ๋˜์–ด๋ฒ„๋ ธ๊ณ  ๊ฒฐ๊ณผ์ ์œผ๋กœ๋Š” Void ๋ฐ˜ํ™˜ ๊ฐ’์„ ์ด์šฉํ•ด success๋˜์—ˆ๋‹ค๋Š” ์˜๋ฏธ๋งŒ ๋ฐ˜ํ™˜๋  ์ˆ˜ ์žˆ๋„๋ก ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•˜์˜€์Šต๋‹ˆ๋‹ค. <details> <summary>์ฝ”๋“œ</summary> ``` swift private func checkFruitStock(_ recipe: [Recipe]) -> Result<Void, JuiceMakerError> { for fruit in recipe { guard let stock = fruitStore.fruitStock[fruit.name] else { return .failure(JuiceMakerError.notExistFruit) } guard stock >= fruit.quantity else { return .failure(JuiceMakerError.ingredientShortage) } } return .success(()) } ``` </details> <br> ### **7๏ธโƒฃ ๋ณต์žกํ•œ ํƒ€์ž…** ๐Ÿ”’ **๋ฌธ์ œ์ ** <br> `Juice` ํƒ€์ž…์˜ `recipe` ํ”„๋กœํผํ‹ฐ๋Š” ์ฅฌ์Šค๋ฅผ ๋งŒ๋“ค ๋•Œ ํ•„์š”ํ•œ ๊ณผ์ผ์˜ ์ข…๋ฅ˜์™€ ์ˆ˜๋Ÿ‰์„ ๊ฐ™์ด ๋ฐ˜ํ™˜ํ•ด์ฃผ์–ด์•ผํ•˜๊ณ , ํ•„์š”ํ•œ ๊ณผ์ผ์˜ ์ข…๋ฅ˜๊ฐ€ 2๊ฐœ ์ด์ƒ์ผ ์ˆ˜ ์žˆ์œผ๋‹ˆ ํŠœํ”Œ์˜ ๋ฐฐ์—ด ํƒ€์ž…์œผ๋กœ ์„ค์ •ํ•ด์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด๋ ‡๊ฒŒ ๊ตฌํ˜„ํ•˜๋ฉด `recipe` ํ”„๋กœํผํ‹ฐ๋ฅผ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋ฐ›๋Š” ๋ฉ”์„œ๋“œ์˜ ์ •์˜ ๋ถ€๋ถ„์ด ๊ธธ์–ด์ ธ ๊ฐ€๋…์„ฑ์ด ๋–จ์–ด์กŒ์Šต๋‹ˆ๋‹ค. <details> <summary>์ฝ”๋“œ</summary> ``` swift private func checkFruitStock(_ recipe: [(name: Fruits, quantity: Int)]) -> Result<Void, StockError> {} ``` </details> <br> ๐Ÿ”‘ **ํ•ด๊ฒฐ๋ฐฉ๋ฒ•** <br> `typealias` ๋ฅผ ์ด์šฉํ•˜์—ฌ ํŠœํ”Œ ๋ฐฐ์—ด ํƒ€์ž…์„ ์ •์˜ํ•˜์˜€๋”๋‹ˆ ์ฝ”๋“œ๊ฐ€ ํ›จ์”ฌ ๊น”๋”ํ•ด์กŒ๊ณ , naming์„ ํ†ตํ•ด ํŠœํ”Œ ๋ฐฐ์—ด ํƒ€์ž…์ด `recipe`์˜ ํƒ€์ž…์ด๋ผ๋Š” ๊ฒƒ์ด ์กฐ๊ธˆ ๋” ๋ช…ํ™•ํ•ด์ง€๋Š” ํšจ๊ณผ๋ฅผ ์–ป์—ˆ์Šต๋‹ˆ๋‹ค. <details> <summary>์ฝ”๋“œ</summary> ``` swift typealias Recipe = (name: Fruits, quantity: Int) private func checkFruitStock(_ recipe: [Recipe]) -> Result<Void, StockError> {} ``` </details> <br> ### **8๏ธโƒฃ ๋งค๊ฐœ๋ณ€์ˆ˜ ์—†์ด ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฉ”์„œ๋“œ** ๐Ÿ”’ **๋ฌธ์ œ์ ** <br> `receiveRecipe`๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋ฐ›์ง€ ์•Š๊ณ  ์ •ํ•ด์ง„ ์ฅฌ์Šค๊ฐ€ ์žˆ๋‹ค๋ฉด ๊ทธ ๋’ค์— ๋ฉ”์„œ๋“œ๊ฐ€ ์‹คํ–‰๋˜์–ด ํ•ด๋‹น ์ผ€์ด์Šค์˜ ๊ฐ’๋งŒ ๊ฐ€์ ธ์˜ค๋Š” ์—ญํ• ์„ ํ•˜์˜€์Šต๋‹ˆ๋‹ค. ๋กœ์ง ์ƒ์— ํฐ ๋ฌธ์ œ๋Š” ์—†์—ˆ์ง€๋งŒ ๊ตณ์ด ๋ฉ”์„œ๋“œ๊นŒ์ง€ ์‚ฌ์šฉํ•˜์—ฌ ๋ ˆ์‹œํ”ผ์˜ ๋ฐ˜ํ™˜๊ฐ’๋งŒ์„ ๊ฐ€์ ธ์˜ฌ ํ•„์š”๋Š” ์—†์—ˆ์Šต๋‹ˆ๋‹ค. <details> <summary>์ฝ”๋“œ</summary> ``` Swift func receiveRecipe() -> [Recipe] { switch self { case .strawberryJuice: return [(.strawberry, 16)] case .bananaJuice: return [(.banana, 2)] case .kiwiJuice: return [(.kiwi, 3)] case .pineappleJuice: return [(.pineapple, 2)] case .strawberryBananaJuice: return [(.strawberry, 10), (.banana, 1)] case .mangoJuice: return [(.mango, 3)] case .mangoKiwiJuice: return [(.mango, 2), (.kiwi, 1)] } } ``` </details> <br> ๐Ÿ”‘ **ํ•ด๊ฒฐ๋ฐฉ๋ฒ•** <br> ๊ฒฐ๊ณผ์ ์œผ๋กœ `receiveRecipe` ๋ฉ”์„œ๋“œ๋ฅผ `recipe` ์—ฐ์‚ฐ ํ”„๋กœํผํ‹ฐ๋กœ ๋ณ€๊ฒฝ๋กœ ๋ณ€๊ฒฝํ•ด์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค. <details> <summary>์ฝ”๋“œ</summary> ``` swift var recipe: [Recipe] { switch self { case .strawberryJuice: return [(.strawberry, 16)] case .bananaJuice: return [(.banana, 2)] case .kiwiJuice: return [(.kiwi, 3)] case .pineappleJuice: return [(.pineapple, 2)] case .strawberryBananaJuice: return [(.strawberry, 10), (.banana, 1)] case .mangoJuice: return [(.mango, 3)] case .mangoKiwiJuice: return [(.mango, 2), (.kiwi, 1)] } } ``` </details> <br> ## ๐Ÿ‘ฅ ํŒ€ ํšŒ๊ณ  ### ์šฐ๋ฆฌ ํŒ€์ด ์ž˜ํ•œ ์  - ๊ทธ๋ผ์šด๋“œ ๋ฃฐ๋กœ ์ •ํ•œ ์‹œ๊ฐ„์— ์ž˜ ๋ชจ์ด๋ ค ๋…ธ๋ ฅํ–ˆ์Šต๋‹ˆ๋‹ค. - ์„œ๋กœ ๋ชจ๋ฅด๋Š” ๋ถ€๋ถ„์— ๋Œ€ํ•ด ์ž์œ ๋กญ๊ฒŒ ์งˆ๋ฌธ ํ–ˆ์Šต๋‹ˆ๋‹ค. - ํŒ€์›์—๊ฒŒ ์•„๋Š” ๋ถ€๋ถ„์— ๋Œ€ํ•ด์„œ ์ž์„ธํ•˜๊ฒŒ ์„ค๋ช…ํ–ˆ์Šต๋‹ˆ๋‹ค. - ํŒ€ ํ”„๋กœ์ ํŠธ์˜ ์˜์˜์— ๋งž๊ฒŒ ํ•จ๊ป˜ ๊ณ ๋ฏผํ•˜๋Š” ๊ณผ์ •์—์„œ ์–ป๋Š” ๊ฒŒ ๋งŽ์•˜์Šต๋‹ˆ๋‹ค. ### ์šฐ๋ฆฌ ํŒ€์ด ๊ณ ์ณ์•ผ ํ•  ๋ถ€๋ถ„ - ํ”„๋กœ์ ํŠธ์— ์น˜์ค‘๋˜์–ด ๊ฐœ์ธ๊ณต๋ถ€์— ๋ถ€์กฑํ•จ์ด ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ### To. yyss99(์™€์ด) - Yetti: ๋ชจ๋ฅด๋Š” ๋ถ€๋ถ„์€ ํ™•์‹คํ•˜๊ฒŒ ์ดํ•ดํ•˜๋ ค๊ณ  ๋…ธ๋ ฅํ•˜๋Š” ๋ชจ์Šต์ด ์ข‹์•˜์Šต๋‹ˆ๋‹ค! ๐Ÿ‘ - Mary: ์ •ํ™•ํ•˜๊ฒŒ ์ดํ•ดํ•˜์‹œ๋ ค๋Š” ์—ด์ • ๋•๋ถ„์— ์ €๋„ ๋ถ€์กฑํ•œ ๋ถ€๋ถ„์ด ๋ฌด์—‡์ธ์ง€ ์•Œ๊ฒŒ ๋˜์–ด ๊ณต๋ถ€์— ๋งŽ์€ ๋„์›€์ด ๋˜์—ˆ์Šต๋‹ˆ๋‹ค ๐Ÿ‘ ### To. Mary(๋ฉ”๋ฆฌ) - yyss99(์™€์ด): ๋”ฐ๋กœ ๊ณต๋ถ€ํ•œ ๊ฒƒ๋“ค์„ ์ž˜ ๊ณต์œ ํ•ด์ฃผ์‹œ๊ณ  ์•Œ๊ธฐ ์‰ฝ๊ฒŒ ์„ค๋ช…ํ•ด์ฃผ์…”์„œ ์ข‹์•˜์Šต๋‹ˆ๋‹ค. ๐Ÿ˜† - Yetti: ์–ด๋–ป๊ฒŒ ํ•˜๋ฉด ๋” ๋‚˜์€ ์ฝ”๋“œ๊ฐ€ ๋ ์ง€๋ฅผ ์ง€์†์ ์œผ๋กœ ๊ณ ๋ฏผํ•˜๋Š” ๋ชจ์Šต์ด ์ข‹์•˜์Šต๋‹ˆ๋‹ค!๐Ÿ‘ ### To. Yetti(์˜ˆํ‹ฐ) - yyss99(์™€์ด): ์ž์œ ๋กญ๊ฒŒ ์งˆ๋ฌธํ•˜๊ณ  ๋ชจ๋ฅด๋Š” ๋ถ€๋ถ„์— ๋Œ€ํ•ด ๊ณต์œ ํ•ด์ฃผ์…”์„œ ๊ฐ™์ด ๋ฐฐ์šธ ์ˆ˜ ์žˆ๋Š” ๋ถ„์œ„๊ธฐ๋ฅผ ํ˜•์„ฑํ•ด ์ฃผ์…”์„œ ์ •๋ง ์ข‹์•˜์Šต๋‹ˆ๋‹ค.๐Ÿ˜† - Mary: ํ”„๋กœ์ ํŠธ ์ „๋ฐ˜์ ์ธ ๋ถ„์œ„๊ธฐ๋ฅผ ์ž˜ ์ด๋Œ์–ด์ฃผ์…จ๋˜ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ์—ด์ •์ ์œผ๋กœ ๊ณต๋ถ€ํ•˜์‹œ๋Š” ๋ชจ์Šต์ด ์ข‹์•˜์Šต๋‹ˆ๋‹ค. ๐Ÿ‘ ## ๐Ÿ“‘ ์ฐธ๊ณ ์ž๋ฃŒ - [Swift API Design Guidelines - Naming](https://www.swift.org/documentation/api-design-guidelines/#naming) - [Initialization](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/initialization/) - [Access control](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/accesscontrol/) - [Nested Type](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/nestedtypes/) - [Type Casting](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/typecasting/) - [Error Handling](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/errorhandling/) - [Protocol-Delegation](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/protocols#Delegation) - [Properties-Lazy Stored Properties](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/properties#Lazy-Stored-Properties)