์ฅฌ์ค๋ฅผ ์ ๋ ฅ๋ฐ์ ์ฌ๋ฃ๋ฅผ ํ์ธํ๊ณ ์ฌ๋ฃ์ ์ฌ๊ณ ๊ฐ ์์ผ๋ฉด ๋ ์ํผ๋๋ก ์ฅฌ์ค๋ฅผ ๋ง๋ค์ด ์ฃผ๋ ํ๋ก๊ทธ๋จ
ํ๋ก์ ํธ ์งํ ๊ธฐ๊ฐ | 23.05.08.(์) ~ 23.05.26.(๊ธ)
Yetti | Mary | yy-ss99 |
- 23/05/09 (ํ)
- ์ ์ฒด ๊ตฌ์กฐ์์ ํ์ํ ํ์ ๋ค ์ ์ธ ๋ฐ ํ์ผ๋ณ ์ ๋ฆฌ
- ์ฌ๊ณ ๋ฅผ ์กฐ์ ํ๋ ๊ธฐ๋ฅ ๊ตฌํ
- ์๋ฌ์ฒ๋ฆฌ๋ฅผ ์ํ ์๋ฌ ํ์ ๊ตฌํ
- 23/05/11 (๋ชฉ)
- ์ฅฌ์ค๋ฅผ ์ฃผ๋ฌธ๋ฐ๋ ๋ฉ์๋์ ๋ง๋๋ ๊ธฐ๋ฅ ๋ถ๋ฆฌ
- 23/05/12 (๊ธ)
- ๋ ์ํผ ๋ฐํ ๋ฉ์๋๋ฅผ ์ฐ์ฐ ํ๋กํผํฐ๋ก ์์
- 23/05/16 (ํ)
- ์ฅฌ์ค ์ฃผ๋ฌธ ๋ฒํผ ๋ฉ์๋ ๊ตฌํ
- alert ๋ฉ์๋ ๋ฐ ๊ณผ์ผ ์๋ ๋ ์ด๋ธ ๋ณ๊ฒฝ ๋ฉ์๋ ๊ตฌํ
- ์ฌ๋ฃ ๋ถ์กฑ alert์ ์ฌ๊ณ ์์ ๋ฒํผ์์ ํ๋ฉด ์ ํ ๊ธฐ๋ฅ ๊ตฌํ
- 23/05/23 (ํ)
- ์ฌ๊ณ ์ถ๊ฐ ํ๋ฉด ์ง์ ์ ๊ณผ์ผ์ ํ์ฌ ์ฌ๊ณ ์๋ ํ์ ๊ธฐ๋ฅ ๊ตฌํ
- Stepper๋ฅผ ์ด์ฉํ ์ฌ๊ณ ์์ ๊ธฐ๋ฅ ๊ตฌํ
๐ฃ์ฝ๋๋ ํ ๊ธ ์ฒ๋ฆฌ ๋์ด์์ต๋๋ค.
๐ ์ฒซ๋ฒ์งธ ๋ฐฉ์ - delegate pattern
-
์ฅ์
- ๊ฐ์ฒด ๊ฐ์ ๊ฒฐํฉ๋๋ฅผ ๋ฎ์ถ๋๋ฐ ํจ๊ณผ์ ์ ๋๋ค. ๊ฐ์ฒด๋ค์ ๋ ๋ฆฝ์ ์ผ๋ก ๊ฐ๋ฐ๋๊ณ ๋ณ๊ฒฝ๋ ์ ์์ผ๋ฉฐ, ๋ณ๊ฒฝ ์ฌํญ์ด ๋ค๋ฅธ ๊ฐ์ฒด์ ๋ฏธ์น๋ ์ํฅ์ด ์ต์ํ๋ฉ๋๋ค.
- ์ฝ๋์ ์ ์ง๋ณด์์ฑ๊ณผ ํ์ฅ์ฑ์ ํฅ์์ํต๋๋ค.
delegate pattern
์ฌ์ฉ ์ ๊ธฐ๋ฅ์ ํ์ฅํ๊ฑฐ๋ ๋ณ๊ฒฝ์์protocol
์extension
์ ์์ ํ๊ฑฐ๋ ํด๋น ๊ฐ์ฒด์ ์ ์ฉํ๋ ๋ฐฉ์์ผ๋ก ์ฝ๊ฒ ์์ ํ ์ ์์ต๋๋ค. protocol
๊ณผextension
์ผ๋ก ๊ตฌํ๋๊ธฐ ๋๋ฌธ์ ๋ช ํํ๊ฒ ์ ์ํ๊ณ ๋ฌธ์ํ ํ ์ ์์ด ๊ฐ๋ฐ์๋ค์ด ์ํธ์์ฉ์ ์ฝ๊ฒ ํ์ ํ ์ ์์ต๋๋ค.
-
๋จ์
- ์ํฉ์ ๋ฐ๋ผ ๊ฐ์ฒด ๊ฐ์ ์๋ฐฉํฅ ์์กด์ฑ์ด ์๊ธธ ์ ์๊ณ ๊ธฐ๋ฅ์ด ๋ถ์ฐ ๋จ์ผ๋ก ๊ฐ์ฒด ๊ฐ์ ๊ด๊ณ ํ์ ์ด ์ด๋ ค์์ง๋๋ค.
์ฝ๋
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])
}
}
}
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)
}
...
}
๐ ๋๋ฒ์งธ ๋ฐฉ์ - closure
-
์ฅ์
- ๊ฐ๋จํ๊ฒ ๊ตฌํํ ์ ์์ต๋๋ค.
-
๋จ์
- ์ฌ๋ฌ ๊ฐ๋ฅผ ์ฌ์ฉํ๋ ค๊ณ ํ ์๋ก ์ฝ๋๊ฐ ์กฐ๋ฐํด์ ธ์ ๊ฐ๋ ์ฑ์ ํด์น ๋งํ ์ฐ๋ ค๊ฐ ์์ต๋๋ค.
์ฝ๋
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])
}
}
...
}
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)
}
...
}
๐ ์ธ๋ฒ์งธ ๋ฐฉ์ - notification
-
์ฅ์
- ๋ค์์ ๊ฐ์ฒด์ ๋์์ ์ด๋ฒคํธ๋ฅผ ์ ๋ฌํ ์ ์์ต๋๋ค.
- ์ฌ๋ฌ๊ฐ์ง ์ค์ ํด์ค ํ์์์ด ์งง์ ์ฝ๋๋ก ์ฝ๊ฒ ๊ตฌํํ ์ ์์ต๋๋ค.
-
๋จ์
- ์ค๋ฅ์ ์ถ์ ์ด ์ฝ์ง ์์ต๋๋ค. ์๋ํ๋ฉด
notificationName
๋๋userInfo
์key
๊ฐ์ดString
๊ฐ์ผ๋ก ๋ค์ด๊ฐ๊ฒ ๋๋๋ฐ ์ด ๋ถ๋ถ์ ์คํ๊ฐ ๋์post
ํ๋ ๋ถ๋ถ๊ณผaddObserver
๋ถ๋ถ์ด ๋ฌ๋ผ์ง๊ฒ ๋๋๋ผ๋ ์ปดํ์ผ์ด๋ ๋ฐํ์์์ ์๋ฌ๋ฅผ ๋ฑ์ด์ฃผ์ง ์๊ธฐ ๋๋ฌธ์ ์ง์ ๋์ผ๋ก ๋ฐ๊ฒฌํ์ง ์๋ ์ด์ ๋ ธํฐํผ์ผ์ด์ ์์ ๋๋ ์๋ฌ์ธ์ง ์ธ์งํ๊ธฐ ์ฝ์ง ์์ต๋๋ค. post
๊ฐ ๋ ํ์ ๋ค์post
ํ ๋ถ๋ถ์ผ๋ก ์ ๋ณด๋ฅผ ๋ฐ์์ฌ ์ ์์ต๋๋ค.
- ์ค๋ฅ์ ์ถ์ ์ด ์ฝ์ง ์์ต๋๋ค. ์๋ํ๋ฉด
์ฝ๋
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])
}
}
}
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)
}
...
}
โ ์ฝ๋๋ก ์ง์ ๊ตฌํํด๋ณด๊ณ ์ฅ๋จ์ ์ ๊ณ ๋ คํ ๊ฒฐ๊ณผ delegate pattern
์ ์ฌ์ฉํ๊ธฐ๋ก ๊ฒฐ์ ํ์ต๋๋ค.
๐ ๊ณ ๋ฏผํ๋ ์ :๋ค๋น๊ฒ์ด์
vs ๋ชจ๋ฌ
๊ณผ์ผ์ ์ฌ๊ณ ๊ฐ ๋ถ์กฑํ ๊ฒฝ์ฐ๋ JuiceOrderViewController
์์ ์ฌ๊ณ ์์ ๋ฒํผ์ ํฐ์นํ ๊ฒฝ์ฐ์ ChangeStockViewController
์์ ๊ณผ์ผ์ ์ฌ๊ณ ๋ฅผ ์ถ๊ฐํ ๋ค JuiceOrderViewController
๋ก ๋์๊ฐ๋ ํ๋ฉด ์ ํ์ ์ด๋ค ๋ฐฉ์์ด ์ข์์ง ๊ณ ๋ฏผํ์ต๋๋ค.
- ๋ค๋น๊ฒ์ด์
์ธํฐํ์ด์ค ํน์ง
Navigation Controller
๋ ์ฃผ๋ก ๊ณ์ธต์ ๊ตฌ์กฐ์ ํ๋ฉด์ ํ์ ์ํด ์ฌ์ฉ๋๋ ๋๋ฆด ๋ค์ด ์ธํฐํ์ด์ค(๊ฐ ์ ํํ ์ ์๋ ํญ๋ชฉ์ ๋ํ ์ธ๋ถํญ๋ชฉ์ด ์กด์ฌํ๋ ์ธํฐํ์ด์ค)์ ๋๋ค.- ๋ทฐ ์ปจํธ๋กค๋ฌ ์คํ์ ๋ฐ๋ผ ํ๋ฉด์ ์คํ์ ํธ์(
push
)ํ๊ฑฐ๋ ํ(pop
)ํ๋ ๋ฐฉ์์ผ๋ก ํ๋ฉด ์ ํ์ ํฉ๋๋ค.
- ๋ชจ๋ฌ ํน์ง
- ํ๋ฉด์ ๋ค๋ฅธ ํ๋ฉด์์ ๋์์ ์ฌ์ฉ์์ ์ด๋ชฉ์ ๋๊ธฐ ์ํด ์ฌ์ฉํฉ๋๋ค.
- ํ์ฌ ๋ทฐ ์ปจํธ๋กค๋ฌ ์์ ๊ฒน์ณ์ ธ์ ํ์๋๋ฉฐ ๋ค๋ฅธ ๋ทฐ ์ปจํธ๋กค๋ฌ๋ก ์ด๋ํ๊ธฐ ์ํด์๋ ๋ซ์์ผ ํฉ๋๋ค.
- ๋ชจ๋ฌ์ ์ผ๋ฟ์ ํตํด ํ์ธ/์ทจ์ ์ค ํ๋๋ฅผ ์ ํํ๊ฑฐ๋ ์ก์ ์ํธ์์ ์ ํ์ ํ๋ ๋ฑ์ ํน์ ์ ํ์ ์๋ฃ ํด์ผํ๋ค๋ ํน์ง์ด ์์ต๋๋ค.
โ ๋ค๋น๊ฒ์ด์ ์ธํฐํ์ด์ค๋ ์ฃผ๋ก ์ฑ์ ๋ฉ์ธ ํ์ ํ๋ฆ๊ณผ ํ๋ฉด ์ ํ์ ๊ด๋ฆฌํ๋ ๋ฐ ์ฌ์ฉ๋๊ณ , ๋ชจ๋ฌ์ ์ถ๊ฐ ์ ๋ณด๋ ์์ ์์ ์ ํ์ํ ํ๋ฉด ์ ํ์ ์ฌ์ฉ๋ฉ๋๋ค.
ChangeStockViewController
๋ ์ฅฌ์ค ์ฃผ๋ฌธ ๊ณผ๋ ๊ด๊ณ์์ด ์ฌ๊ณ ๋ฅผ ์์ ํ๋ ํ๋ฉด์ ๋์ฐ๋ ์ญํ ์
๋๋ค. ์ด๋ ํ๋ฆ์ ์ฐ๊ฒฐ๋์ง ์๊ธฐ ๋๋ฌธ์ ๋ชจ๋ฌ๋ก ํ๋ฉด์ ํ์ ํ๋ ๊ฒ์ด ๋ ์ ์ ํ๋ค๊ณ ํ๋จํ์ต๋๋ค.
๋ง์ฝ ์ฌ๊ณ ์ถ๊ฐ ๋ทฐ์ปจํธ๋กค๋ฌ๊ฐ ์๋ โ์ฃผ๋ฌธ์ ํ์ธ์ค์
๋๋คโฆโ ๋ฉ์์ง๋ฅผ ๋์์ฃผ๋ ๋ทฐ์ปจํธ๋กค๋ฌ๋ก ํ๋ฉด์ ํ์ ํ๋ค๋ฉด ์ฅฌ์ค ์ฃผ๋ฌธ๊ณผ ๊ฐ์ ํ๋ฆ์ด๊ธฐ ๋๋ฌธ์ ์ด๋ด ๋์๋ ๋ค๋น๊ฒ์ด์
์ธํฐํ์ด์ค ๋ฐฉ์์ด ๋ ์ ์ ํ ๊ฒ ๊ฐ์ต๋๋ค.
๐ ๋ฌธ์ ์
JuiceOrderViewController
์๋ ์ฅฌ์ค๋ฅผ ์ฃผ๋ฌธํ๋ ์ฌ๋ฌ๊ฐ์ ๋ฒํผ์ด ์๊ณ , ๋ฒํผ์ ํด๋ฆญํ๋ฉด placeAnOrder(for:)
๋ฉ์๋๋ฅผ ํธ์ถํ๊ฒ ํ๊ธฐ ์ํด ๊ฐ๊ฐ์ IBAction์ ๋ง๋ค์ด์ฃผ์์ต๋๋ค. ํ์ง๋ง ์ด๋ ๊ฒ ๊ตฌํํ๋ ์ฝ๋๊ฐ ์ค๋ณต๋๋ ๋ฌธ์ ์ ์ด ์์์ต๋๋ค.
์ฝ๋
@IBAction private func hitStrawberryJuiceOrderButton(_ sender: UIButton) {
placeAnOrder(for: .strawberryJuice)
}
@IBAction private func hitBananaJuiceOrderButton(_ sender: UIButton) {
placeAnOrder(for: .bananaJuice)
}
...
๐ ํด๊ฒฐ๋ฐฉ๋ฒ ์ฒซ๋ฒ์งธ
์ฒซ๋ฒ์งธ๋ก ์ฐพ์๋ ํด๊ฒฐ์ฑ
์ tag
๋ฅผ ์ด์ฉํ๋ ๋ฐฉ์์ด์๊ณ ์ด๋ฅผ ์ด์ฉํ๋ฉด ์ฌ๋ฌ๊ฐ์ ๋ฒํผ์ ํ๋์ IBAction์ผ๋ก ์ฒ๋ฆฌํ ์ ์์ด ์ค๋ณต๋๋ ์ฝ๋๋ฅผ ์ค์ผ ์ ์์์ต๋๋ค. ํ์ง๋ง ์ด๋ค ๋ฒํผ์ด tag
๊ฐ ๋ช์ธ์ง ํ ๋์ ์๊ธฐ ์ด๋ ค์ ๊ณ , ๊ฐ ๋ฒํผ์ ํ๊ทธ๋ฅผ ํ๋ํ๋ ์ง์ ํด์ฃผ์ด์ผํด์ ํ์ฅ์ฑ์ด ์ข์ง ์๋ค๊ณ ํ๋จํ์์ต๋๋ค.
์ฝ๋
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)
}
๐ ์ต์ข
ํด๊ฒฐ๋ฐฉ๋ฒ
์ต์ข
์ ์ผ๋ก ์ฌ๋ฌ๊ฐ์ ๋ฒํผ์ ํ๋์ IBAction์ผ๋ก ๋ฌถ์ด์ฃผ๊ณ , ๋ฒํผ์ title
์ ๊ธฐ์ค์ผ๋ก ์ฅฌ์ค๋ฅผ ๋ฐํํด์ฃผ๋๋ก ์์ ํ์์ต๋๋ค. tag
๋ฐฉ๋ฒ๊ณผ๋ ๋ฌ๋ฆฌ title
์ด ๋ฌธ์์ด์ด๊ธฐ ๋๋ฌธ์ ์ด๋ค ๋ฒํผ์ธ์ง ํ ๋์ ์๊ธฐ ์ฌ์ ํด๋น ๋ฐฉ๋ฒ์ผ๋ก ์ฑํํ์์ต๋๋ค.
์ฝ๋
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)
}
๐ ๋ฌธ์ ์
์ฅฌ์ค๋ฅผ ์ฃผ๋ฌธํ๋ ๋ฒํผ์ title์ ๋ฐ๋ผ ์ฅฌ์ค๋ฅผ ๋ฐํํด์ฃผ๋ searchJuice
๋ฉ์๋๋ฅผ ๋ง๋ค์ด์ฃผ์์ต๋๋ค. ํ์ง๋ง switch๋ฌธ ์์ ๋ฒํผ์ ํ์ดํ์ ๋ฌธ์์ด๋ก ์ง์ ์์ฑํด์ฃผ๋ ๋งค์ง๋ฆฌํฐ๋ด์ด ๋์ด ๋ฌธ์์ด์ ์๋ฏธ๋ฅผ ํ ๋์ ์๊ธฐ ์ด๋ ค์ ์ต๋๋ค.
์ฝ๋
private func searchJuice(by buttonTitle: String) -> Juice? {
switch buttonTitle {
case "๋ธ๊ธฐ์ฅฌ์ค ์ฃผ๋ฌธ":
return .strawberryJuice
case "๋ฐ๋๋์ฅฌ์ค ์ฃผ๋ฌธ":
return .bananaJuice
...
default:
return nil
}
}
๐ ํด๊ฒฐ๋ฐฉ๋ฒ
๋งค์ง๋ฆฌํฐ๋ด์ ํด๊ฒฐํ๊ธฐ ์ํด Juiceํ์
์ ์ฐ๊ด๊ฐ ํ์ฉ, ์ฐ์ฐ ํ๋กํผํฐ ํ์ฉ ๋ฑ ๋ค์ํ ๋ฐฉ๋ฒ์ ์๊ฐํด๋ดค์ง๋ง ์ฝ๋๊ฐ ๊ธธ์ด์ ธ ์คํ๋ ค ๊ฐ๋
์ฑ์ด ๋จ์ด์ง ๊ฒ ๊ฐ์์ต๋๋ค. ๋ค๋ฅธ ๋ฐฉ๋ฒ์ ์ฐพ๋ค๊ฐ case๊ฐ ์๋ enum์ ํ์ฉํ๋ ๋ฐฉ๋ฒ์ ์๊ฒ ๋์์ต๋๋ค.
ํด๋น ๋ฐฉ๋ฒ์ ์ด๊ฑฐํ์ด์ง๋ง case๊ฐ ์๊ธฐ ๋๋ฌธ์ ์ด๊ธฐํ๋ ์๋๊ณ , ์์ํ namespace๋ก์๋ง ์๋ ๊ฐ๋ฅํ๋ค๋ ์ฅ์ ์ด ์์ต๋๋ค.
์ฅฌ์ค๋ฉ์ด์ปค์ ์ ์ฉ์ ButtonTitle
์ด๊ฑฐํ์ ํ์
ํ๋กํผํฐ๋ก ๊ฐ ๋ฒํผ์ ํ์ดํ์ธ String๊ฐ์ ํ ๋นํด์ฃผ์๊ณ ๊ทธ ๊ฐ์ ๊ฐ์ ธ์ switch๋ฌธ์์ ํธ์ถํด์ค ์ ์๋๋ก ํ์์ต๋๋ค.
์ฝ๋
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
}
}
๐ ๋ฌธ์ ์
Cannot use instance member 'initialStock' within property initializer; property initializers run before 'self' is available
์ด๊ธฐ๊ฐ์ ์ฃผ๋ ค๋ ์ํฉ์์ ์ด๋์
๋ผ์ด์ ๊ฐ ์คํ๋๊ธฐ ์ ์ .self์ ์ ๊ทผํด์ ๊ฐ์ ๊ฐ์ ธ์ค๋ ค๊ณ ํด์ ์ด๋ฐ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค.
์ฝ๋
let initialStock = 10
var fruitStock: [Fruits: Int] = [
.strawberry: initialStock,
.banana: initialStock,
.pineapple: initialStock,
.mango: initialStock,
.kiwi: initialStock
]
๐ ํด๊ฒฐ๋ฐฉ๋ฒ ์ฒซ๋ฒ์งธ
-
์ฒซ๋ฒ์งธ ๋ฐฉ์ :
static
์ฌ์ฉstatic
ย ํค์๋ ์ฅ์ static
์ ํด๋น ๊ตฌ์กฐ์ฒด์ ์ธ์คํด์ค๋ ํด๋์ค๊ฐ ์์ฑ๋์ง ์์๋ ์ ๊ทผ์ด ๊ฐ๋ฅํ๋ค๋ ์ฅ์ ๋๋ฌธ์ ์ ์ญ์ ์ธ ๊ธฐ๋ฅ์ ์ ๊ณต ํ ์ ์์ต๋๋ค.- ํด๋์ค๋ ๊ตฌ์กฐ์ฒด์ ์ธ์คํด์ค์๋ ๋
๋ฆฝ์ ์ธ ๊ฐ์ ์ ์ฅํ ํ์๊ฐ ์๋ ๊ฒฝ์ฐย
static
ย ํค์๋๋ฅผ ์ฌ์ฉํ์ฌ ์ ์ญ์ผ๋ก ์ ์ํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฒด์์ ์ฌ์ฉํ๋ ์ค์ ๊ฐ์ด๋ ์์ ๊ฐ์ ์ ์ํ ๋ ์ ์ฉํฉ๋๋ค.
static
ย ํค์๋ ๋จ์ static
์ผ๋ก ์ ์ธ๋๋ฉด ํ๋กํผํฐ๋ ๋ฉ์๋๋ ์ค๋ฒ๋ผ์ด๋ฉ์ด ๋ถ๊ฐ๋ฅํฉ๋๋ค.static
ย ํค์๋๋ฅผ ์ฌ์ฉํ์ฌ ์ ์ธ๋ ํ๋กํผํฐ๋ ๋ฉ์๋๋ ํด๋์ค๋ ๊ตฌ์กฐ์ฒด ๋ด๋ถ์์๋ง ์ฌ์ฉ ๊ฐ๋ฅํ๊ธฐ ๋๋ฌธ์, ๋ค๋ฅธ ๋ชจ๋์์ ์ ๊ทผํ๊ธฐ ์ด๋ ต์ต๋๋ค. ์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด์๋ยpublic static
๊ณผ ๊ฐ์ด ์ ์ธํด์ผ ํฉ๋๋ค.static
ย ํค์๋๋ฅผ ์ฌ์ฉํ์ฌ ์ ์ธ๋ ํ๋กํผํฐ๋ ๋ฉ์๋๋ ๋ฉ๋ชจ๋ฆฌ ๋ด์ ๋ฑ ํ ๋ฒ๋ง ํ ๋น๋๋ฏ๋ก, ๋ฐํ์ ๋์ ๊ฐ์ด ๋ณ๊ฒฝ๋ ๊ฒฝ์ฐ ๋ค๋ฅธ ์ธ์คํด์ค๋ ์ค๋ ๋์์๋ ๋ณ๊ฒฝ๋ ๊ฐ์ด ๋ฐ์๋ฉ๋๋ค.- ์ข
๋ฃ์๊น์ง ๋ฉ๋ชจ๋ฆฌ๊ฐ ํ ๋น๋ ์ฑ๋ก ์กด์ฌํ๋ฏ๋ก ๋ง์ย
static
ย ์์ฑ์ ํ๋ก๊ทธ๋จ ํผํฌ๋จผ์ค์ ์ ์ํฅ์ ์ค ์๋ ์์ต๋๋ค.
โ
stactic
์ฅ๋จ์ ์ ๊ณ ๋ คํ์ ๋ ์ง๊ธ ํ์ฌ์ ์ฝ๋์ ์ ์ ํ ๋ ์ข์ ๋ฐฉ์์ด ์์ ๊ฒ์ด๋ผ๊ณ ํ๋จํ์ต๋๋ค.
์ฝ๋
static let initialStock = 10
var fruitStock: [Fruits: Int] = [
.strawberry: initialStock,
.banana: initialStock,
.pineapple: initialStock,
.mango: initialStock,
.kiwi: initialStock
]
๐ ํด๊ฒฐ๋ฐฉ๋ฒ ๋๋ฒ์งธ
-
๋ ๋ฒ์งธ ๋ฐฉ์
lazy
ย ํค์๋ ์ฌ์ฉlazy
ํค์๋ ํน์ง- ํ๋กํผํฐ๊ฐ ์ฒ์ ์ฌ์ฉ๋๊ธฐ ์ ๊น์ง๋ ๋ฉ๋ชจ๋ฆฌ์ ์ฌ๋ผ๊ฐ์ง ์์ต๋๋ค. ๊ทธ๋์ ์๊ฐ์ด ์ค๋ ์์๋๋ ์์
์ย
lazy
ย ๋ฅผ ๋ถ์ด๋ฉด ์ค์ ์์ ์ด ์งํ๋๊ธฐ ์ ๊น์ง๋ ์คํ๋์ง ์์ ํจ์จ์ ์ ๋๋ค. ์์ ์ด ๋ค๋ฅธ ์์ ์ ์์กด์ ์ธ ๊ฒฝ์ฐ์ ์ฌ์ฉํฉ๋๋ค.
โ
initialStock
์ ์ ์ญ์ ์ผ๋ก ์ ๊ทผํ ํ์์๊ณ ,ยfruitStock
๋ฅผ ์ด๊ธฐํ ํ ๋๋ง ํ์ํ๋ค๊ณ ํ๋จํ์ต๋๋ค. ๊ทธ๋์ยstatic let initialStock
์ ํ์ฉํ๋ ๋์ ์ยfruitStock
๋ฅผยlazy var
๋ก ๋ง๋ค์ด ์ ๊ทผ ์์ ๊ฐ์ ํ ๋นํ๋๋ก ์์ ํ์์ต๋๋ค. - ํ๋กํผํฐ๊ฐ ์ฒ์ ์ฌ์ฉ๋๊ธฐ ์ ๊น์ง๋ ๋ฉ๋ชจ๋ฆฌ์ ์ฌ๋ผ๊ฐ์ง ์์ต๋๋ค. ๊ทธ๋์ ์๊ฐ์ด ์ค๋ ์์๋๋ ์์
์ย
์ฝ๋
private let initialStock = 10
private(set) lazy var fruitStock: [Fruits: Int] = [
.strawberry: initialStock,
.banana: initialStock,
.pineapple: initialStock,
.mango: initialStock,
.kiwi: initialStock
]
๐ ์ต์ข
ํด๊ฒฐ๋ฐฉ๋ฒ
-
init
๋ฉ์๋ ํ์ฉlazy
๋ ํ๋กํผํฐ์ ์ด๊ธฐํ ๊ณผ์ ์ด ๋ณต์กํ๊ฑฐ๋ ๋ค๋ฅธ ๊ฐ์ ์์กด์ฑ์ ๊ฐ์ง๊ณ ์๋ ๊ฒฝ์ฐ ์ด๊ธฐํ ๋ ๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ๊ฐ๋ฅ์ฑ์ด ์์ด์ ์ฝ๋์ ๋ณต์ก์ฑ์ ์ฆ๊ฐ์ํจ๋ค๋ ๋จ์ ์ด ์๋ค๊ณ ์๊ฐํ์ต๋๋ค. ๋ค๋ฅธ ๋ฐฉ์์ด ์์ง ์์๊น ๊ณ ๋ฏผํ๋ ์ค์init
๋ฉ์๋๋ฅผ ํ์ฉํ๋ ๊ฒ์ด ์ข๋ค๋ ์๊ฐ์ด ๋ค์์ต๋๋ค.initialStock
์ ์ด๊ธฐ๊ฐ์ ๋ณ๊ฒฝ๋ ์ ์์ ๊ฒ ๊ฐ์init
๋ฉ์๋์ ๋งค๊ฐ๋ณ์๋ก ๋ฐ์์ฃผ์๊ณ ,fruitStock
์initialStock
ํ๋กํผํฐ๋ฅผ ํตํด ์ด๊ธฐ ์ฌ๊ณ ๋ฅผ ์ค์ ํ๋๋ก ๊ตฌํํ์์ต๋๋ค.
โ
lazy
ํค์๋๋ฅผ ์ฌ์ฉํ๋ฉดfruitStock
์ด ์ฒ์ ์ฌ์ฉ๋ ๋ ์ด๊ธฐํ๋์์ง๋ง ๋ณ๊ฒฝ๋ ์ฝ๋์์๋FruitStore
์ธ์คํด์ค๊ฐ ์์ฑ๋ ๋ ๋ง๋ค์ด์ง๊ธฐ ๋๋ฌธ์ ๋ ์ผ์ฐ ์ด๊ธฐํํ๊ฒ ๋ฉ๋๋ค.
์ฝ๋
init(initialStock: Int = 10) {
self.fruitStock = [.strawberry: initialStock,
.banana: initialStock,
.pineapple: initialStock,
.kiwi: initialStock,
.mango: initialStock]
}
๐ ๋ฌธ์ ์
Result Type์ success๋ถ๋ถ์ Bool๊ฐ์ ๋ฃ์ด์ฃผ์์ง๋ง ์ค์ง์ ์ผ๋ก ๋ฐํ๋๋ true๊ฐ์ ์ฌ์ฉํ์ง ์๋๋ค๋ ๋ฌธ์ ๊ฐ ์์์ต๋๋ค. ๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ๋ค์ด๊ฐ๋ ๊ฐ์ด true์ด๋ false์ด๋ ํ๋ก๊ทธ๋จ ์คํ์๋ ๋ฌธ์ ๊ฐ ์์๊ณ ๊ฒฐ๊ณผ์ ์ผ๋ก success์ true๊ฐ์ ์ธ๋ชจ์๋ ๊ฐ์ด ๋์์ต๋๋ค.
์ฝ๋
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)
}
๐ ํด๊ฒฐ๋ฐฉ๋ฒ
ํน์ ํ ๊ฐ์ด ๋ฐํ๋์ด์ผ ํ๋ค๋ ๊ณ ์ ๊ด๋
๋๋ฌธ์ ์ฌ๋ฌ ๊ฐ์ ๋ฃ์ด ์๋ํด๋ณด์์ง๋ง ๊ฒฐ๊ตญ ๋ชจ๋ ๋ถํ์ํ ๊ฐ์ด ๋์ด๋ฒ๋ ธ๊ณ ๊ฒฐ๊ณผ์ ์ผ๋ก๋ Void ๋ฐํ ๊ฐ์ ์ด์ฉํด success๋์๋ค๋ ์๋ฏธ๋ง ๋ฐํ๋ ์ ์๋๋ก ์ฝ๋๋ฅผ ์์ ํ์์ต๋๋ค.
์ฝ๋
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(())
}
๐ ๋ฌธ์ ์
Juice
ํ์
์ recipe
ํ๋กํผํฐ๋ ์ฅฌ์ค๋ฅผ ๋ง๋ค ๋ ํ์ํ ๊ณผ์ผ์ ์ข
๋ฅ์ ์๋์ ๊ฐ์ด ๋ฐํํด์ฃผ์ด์ผํ๊ณ , ํ์ํ ๊ณผ์ผ์ ์ข
๋ฅ๊ฐ 2๊ฐ ์ด์์ผ ์ ์์ผ๋ ํํ์ ๋ฐฐ์ด ํ์
์ผ๋ก ์ค์ ํด์ฃผ์์ต๋๋ค.
ํ์ง๋ง ์ด๋ ๊ฒ ๊ตฌํํ๋ฉด recipe
ํ๋กํผํฐ๋ฅผ ๋งค๊ฐ๋ณ์๋ก ๋ฐ๋ ๋ฉ์๋์ ์ ์ ๋ถ๋ถ์ด ๊ธธ์ด์ ธ ๊ฐ๋
์ฑ์ด ๋จ์ด์ก์ต๋๋ค.
์ฝ๋
private func checkFruitStock(_ recipe: [(name: Fruits, quantity: Int)]) -> Result<Void, StockError> {}
๐ ํด๊ฒฐ๋ฐฉ๋ฒ
typealias
๋ฅผ ์ด์ฉํ์ฌ ํํ ๋ฐฐ์ด ํ์
์ ์ ์ํ์๋๋ ์ฝ๋๊ฐ ํจ์ฌ ๊น๋ํด์ก๊ณ , naming์ ํตํด ํํ ๋ฐฐ์ด ํ์
์ด recipe
์ ํ์
์ด๋ผ๋ ๊ฒ์ด ์กฐ๊ธ ๋ ๋ช
ํํด์ง๋ ํจ๊ณผ๋ฅผ ์ป์์ต๋๋ค.
์ฝ๋
typealias Recipe = (name: Fruits, quantity: Int)
private func checkFruitStock(_ recipe: [Recipe]) -> Result<Void, StockError> {}
๐ ๋ฌธ์ ์
receiveRecipe
๋ ๋งค๊ฐ๋ณ์๋ฅผ ๋ฐ์ง ์๊ณ ์ ํด์ง ์ฅฌ์ค๊ฐ ์๋ค๋ฉด ๊ทธ ๋ค์ ๋ฉ์๋๊ฐ ์คํ๋์ด ํด๋น ์ผ์ด์ค์ ๊ฐ๋ง ๊ฐ์ ธ์ค๋ ์ญํ ์ ํ์์ต๋๋ค. ๋ก์ง ์์ ํฐ ๋ฌธ์ ๋ ์์์ง๋ง ๊ตณ์ด ๋ฉ์๋๊น์ง ์ฌ์ฉํ์ฌ ๋ ์ํผ์ ๋ฐํ๊ฐ๋ง์ ๊ฐ์ ธ์ฌ ํ์๋ ์์์ต๋๋ค.
์ฝ๋
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)]
}
}
๐ ํด๊ฒฐ๋ฐฉ๋ฒ
๊ฒฐ๊ณผ์ ์ผ๋ก receiveRecipe
๋ฉ์๋๋ฅผ recipe
์ฐ์ฐ ํ๋กํผํฐ๋ก ๋ณ๊ฒฝ๋ก ๋ณ๊ฒฝํด์ฃผ์์ต๋๋ค.
์ฝ๋
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)]
}
}
- ๊ทธ๋ผ์ด๋ ๋ฃฐ๋ก ์ ํ ์๊ฐ์ ์ ๋ชจ์ด๋ ค ๋ ธ๋ ฅํ์ต๋๋ค.
- ์๋ก ๋ชจ๋ฅด๋ ๋ถ๋ถ์ ๋ํด ์์ ๋กญ๊ฒ ์ง๋ฌธ ํ์ต๋๋ค.
- ํ์์๊ฒ ์๋ ๋ถ๋ถ์ ๋ํด์ ์์ธํ๊ฒ ์ค๋ช ํ์ต๋๋ค.
- ํ ํ๋ก์ ํธ์ ์์์ ๋ง๊ฒ ํจ๊ป ๊ณ ๋ฏผํ๋ ๊ณผ์ ์์ ์ป๋ ๊ฒ ๋ง์์ต๋๋ค.
- ํ๋ก์ ํธ์ ์น์ค๋์ด ๊ฐ์ธ๊ณต๋ถ์ ๋ถ์กฑํจ์ด ์์์ต๋๋ค.
- Yetti: ๋ชจ๋ฅด๋ ๋ถ๋ถ์ ํ์คํ๊ฒ ์ดํดํ๋ ค๊ณ ๋ ธ๋ ฅํ๋ ๋ชจ์ต์ด ์ข์์ต๋๋ค! ๐
- Mary: ์ ํํ๊ฒ ์ดํดํ์๋ ค๋ ์ด์ ๋๋ถ์ ์ ๋ ๋ถ์กฑํ ๋ถ๋ถ์ด ๋ฌด์์ธ์ง ์๊ฒ ๋์ด ๊ณต๋ถ์ ๋ง์ ๋์์ด ๋์์ต๋๋ค ๐
- yyss99(์์ด): ๋ฐ๋ก ๊ณต๋ถํ ๊ฒ๋ค์ ์ ๊ณต์ ํด์ฃผ์๊ณ ์๊ธฐ ์ฝ๊ฒ ์ค๋ช ํด์ฃผ์ ์ ์ข์์ต๋๋ค. ๐
- Yetti: ์ด๋ป๊ฒ ํ๋ฉด ๋ ๋์ ์ฝ๋๊ฐ ๋ ์ง๋ฅผ ์ง์์ ์ผ๋ก ๊ณ ๋ฏผํ๋ ๋ชจ์ต์ด ์ข์์ต๋๋ค!๐
- yyss99(์์ด): ์์ ๋กญ๊ฒ ์ง๋ฌธํ๊ณ ๋ชจ๋ฅด๋ ๋ถ๋ถ์ ๋ํด ๊ณต์ ํด์ฃผ์ ์ ๊ฐ์ด ๋ฐฐ์ธ ์ ์๋ ๋ถ์๊ธฐ๋ฅผ ํ์ฑํด ์ฃผ์ ์ ์ ๋ง ์ข์์ต๋๋ค.๐
- Mary: ํ๋ก์ ํธ ์ ๋ฐ์ ์ธ ๋ถ์๊ธฐ๋ฅผ ์ ์ด๋์ด์ฃผ์ จ๋ ๊ฒ ๊ฐ์ต๋๋ค. ๋ํ ์ด์ ์ ์ผ๋ก ๊ณต๋ถํ์๋ ๋ชจ์ต์ด ์ข์์ต๋๋ค. ๐