# 고민했던 점 & 조언을 얻고싶은 부분 ## 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 값을 받아 주문받은 쥬스를 제조하는 방식으로 변경되었습니다. - 이렇게 처리하는 방법에서 더 좋은 방법이 있는지 잘 떠오르지 않아 주디의 생각은 어떨지 궁금합니다!