# 고민했던 점 & 조언을 얻고싶은 부분
## UI가 쥬스나 과일에 대한 정보를 가지게 할 수는 없을까?
### 1. 과일의 재고를 나타내는 레이블이 과일에 대한 정보를 가지지 않을때 있었던 문제
#### 변경전 코드
``` swift
func configureFruitCountLabels() {
guard let strawberryCount = fruitStore.fruitStock[Fruit.strawberry],
let bananaCount = fruitStore.fruitStock[Fruit.banana],
let kiwiCount = fruitStore.fruitStock[Fruit.kiwi],
let pineappleCount = fruitStore.fruitStock[Fruit.pineapple],
let mangoCount = fruitStore.fruitStock[Fruit.mango] else {
return
}
strawberryCountLabel.text = String(strawberryCount)
bananaCountLabel.text = String(bananaCount)
kiwiCountLabel.text = String(kiwiCount)
pineappleCountLabel.text = String(pineappleCount)
mangoCountLabel.text = String(mangoCount)
}
```
- 과일 재고의 변경이 어떤 label에 연결되는지 코드상에서 알 수 없으므로 일괄적으로 모든 label들의 데이터가 다시 할당되어야 했습니다.
#### 변경 후 코드
``` swift
...
fruitLabelsDictionary = [
.strawberry: strawberryCountLabel,
.banana: bananaCountLabel,
.kiwi: kiwiCountLabel,
.pineapple: pineappleCountLabel,
.mango: mangoCountLabel
]
...
func configureFruitCountLabels() {
for fruit in Fruit.allCases {
fruitLabelsDictionary[fruit]?.text = fruitStore.getStockCountToString(of: fruit)
}
}
func updateFruitCountLabels(juice: Juice) {
for fruit in juice.recipe.keys {
fruitLabelsDictionary[fruit]?.text = fruitStore.getStockCountToString(of: fruit)
}
}
```
- 해결책으로 `[Fruit: UILabel]` 타입의 딕셔너리를 정의해서, 모든 레이블의 업데이트가 필요할 때는 `configureFruitCountLabels`을 호출하고, 쥬스를 만들어서 일부 과일의 재고가 변경되었을 때는 `updateFruitCountLabels` 을 호출하여 재고가 변경된 과일에 해당하는 label만 변경되도록 구현하였습니다.
<br>
---
<br>
### 2. 쥬스를 주문하는 버튼이 어떤 쥬스인지에 대한 정보를 가지지 않을때 있었던 문제
#### 변경전 코드
``` swift
func decideJuice(by sender: UIButton) -> Juice? {
switch sender {
case strawberryJuiceButton:
return .strawberryJuice
case bananaJuiceButton:
return .bananaJuice
case kiwiJuiceButton:
return .kiwiJuice
case pineappleJuiceButton:
return .pineappleJuice
case strawberryBananaJuiceButton:
return .strawberryBananaJuice
case mangoJuiceButton:
return .mangoJuice
case mangoKiwiJuiceButton:
return .mangoKiwiJuice
default:
return nil
}
@IBAction func touchUpJuiceOrderButton(_ sender: UIButton) {
guard let juice = decideJuice(by: sender) else { return }
do {
try juiceMaker.makeJuice(for: juice)
} catch {
presentOrderFailureAlert()
return
}
presentOrderSuccessAlert(juice: juice)
print(fruitStore.fruitStock)
}
```
- 쥬스를 제조하는 7가지 버튼의 동작을 하나의 액션함수로 지정하다보니, 버튼마다 어떤 쥬스를 만들어야할지를 검사해 주는 로직이 항상 필요했습니다.
- 그래서 버튼이 버튼 나 자신이 어떤 쥬스를 만드는 버튼인지에 대한 정보를 모르기 때문에 어떤 쥬스를 만들어야할지 검사하는 부분이 매번 수행된 후에 쥬스 제조를 할 수가 있었습니다.
- 해결책으로는 UIButton을 상속받는 Custom Class를 만들어 저장 프로퍼티에 쥬스의 정보를 저장하는 방법을 고려했지만, 클래스를 정의하고 또 다시 해당 프로퍼티에 초기화를 해주는 작업이 **번거롭게 느껴졌습니다.**
<br>
#### 변경 후 코드
``` swift
func defineDictionary() {
juiceButtonsDictionary = [
strawberryJuiceButton: .strawberryJuice,
bananaJuiceButton: .bananaJuice,
kiwiJuiceButton: .kiwiJuice,
pineappleJuiceButton: .pineappleJuice,
mangoKiwiJuiceButton: .mangoKiwiJuice,
mangoJuiceButton: .mangoJuice,
strawberryBananaJuiceButton: .strawberryBananaJuice
]
}
@IBAction func touchUpJuiceOrderButton(_ sender: UIButton) {
guard let juice = juiceButtonsDictionary[sender] else { return }
do {
try juiceMaker.makeJuice(for: juice)
} catch {
presentOrderFailureAlert()
return
}
presentOrderSuccessAlert(juice: juice)
updateFruitCountLabels(juice: juice)
```
- 변경 후 바뀐 코드로 인해 매번 어떤 쥬스를 만들지 검사하던 `decideJuice()` 메서드가 사라지고,
딕셔너리로 바로 value 값을 받아 주문받은 쥬스를 제조하는 방식으로 변경되었습니다.
- 이렇게 처리하는 방법에서 더 좋은 방법이 있는지 잘 떠오르지 않아 주디의 생각은 어떨지 궁금합니다!