---
# System prepended metadata

title: "\U0001F9C3 JuiceMaker"

---

<div align="center">
  <h1>🧃 JuiceMaker</h1>
</div>

## 👀 Preview

![](https://i.imgur.com/TRcCYML.gif)

## 🔑 Key Experience
* 타입의 캡슐화/은닉화
* 매서드의 기능단위 분리
* Alert Controller 활용
* Stepper 활용
* Modality 활용
* 화면 사이의 데이터 공유
* Auto Layout

## ✏️ 설명

| name                      | type        | 역할과 책임                           |
|:------------------------- | ----------- |:----------------------------------- |
| JuiceMaker                | struct      | 과일의 재고를 가지고 쥬스 제조             |
| Juice                     | enum        | 쥬스 종류, 종류에 따른 레시피             |
| FruitStore                | final class | 과일의 재고 관리                       |
| JuiceMakerError           | enum: Error | 재고 관련 Error                       |
| JuiceMakerViewController  | final class | 주문 버튼으로 주문을 받아 주스 제조, 재고 수정 |
| UpdateStockViewController | final class | 과일의 재고를 수정                      |
## 🤔 STEP 1의 고민

1. FruitStore를 `final class` VS `struct`?

- 재고를 관리하는 속성의 특성상 추후 여러 개의 JuiceMaker가 생긴다면 
  재고 관리를 함께 할 수도 있을 것 같아 Singleton 구현도 고려하였습니다.
- final class와 struct를 계속 고민하다가 결국 결론을 내리지 못했는데요,
  어떤 걸로 구현해도 문제가 되진 않을 것 같아서요.
  혹시 이 중에 문제가 되는 선택지가 있는지, 혹은 더 나은 선택지가 있다면 그 이유가 궁금합니다!

```swift
🐶🐶🐶
결론지으신 것 처럼 현재 스텝 단계에서는 두가지 모두 사용해도 괜찮습니다 :)
일단 유지하고, 다음 스텝에서 변경해야할 것 같다면 그 때 바꿔도 될 것 같아요.
나중에 싱글톤은 사용할 때에는 장단점을 잘 고려해보시고 사용하는게 좋습니다.
```
2. '갯수'를 나타내는 변수명 짓기

- JuiceMaker에서 requiredQuantity, FruitStore에서 과일을 사용하거나 추가할 때 
  quantity를 사용했는데 더 좋은 변수명 있을까요 ~?

```swift
🐶🐶🐶
quantity는 양을 의미해서 개수를 나타내기에는 애매한 것 같네요. 다른 변수명으로 개선해보면 좋을 것 같습니다!
```
## 🤔 STEP 2의 고민

### 1. IBOutlet Collection
각 과일의 재고를 나타내는 Label 5개를 하나씩 연결하여 사용하는 것보다
여러 Button을 하나의 action으로 연결하는 것처럼 다른 방법을 고민하게 되었어요!
* IBOutlet Collection를 적용하여 배열로 묶인 레이블들의 각 인덱스와 `FruitStore`의 `enum Fruit` `raw value`를 일치시켜 각 과일의 레이블에 변경된 재고를 표시하였습니다.
* 고민되는 것은 레이블의 인덱스가 어디에도 정확히 표시되지 않아 코드를 구현한 저희만 순서를 알 수 있기 때문에 추후 유지 보수가 어려울 것 같다는 우려가 되었어요.
* Label에 enum Fruit의 raw value와 같은 값으로 tag를 주는 것도 방법 중 하나로 고려해보았는데,
지금 이 코드로도 괜찮은지, tag를 주는 것이 해결책이 될 수 있을지, 또 다른 의견이 있으신지 궁금합니다!
```swift
🐶🐶🐶
말씀해주신 것 처럼 유지/보수에 취약해집니다. tag를 사용하는 것은 사실상 enum의 Int rawValue값을 UIView에게 옮기는 것 뿐이라 똑같은 이슈가 발생해요.🥲

IBOutlet Collection을 사용하고 싶다면, 과일 데이터 collection을 따로 만들어서
자료의 index를 이용하는게 현재 미션에서는 적합한 것 같아요.
현재 미션에서는 스토리보드를 사용해야하고 주문 버튼이 딱 맞게 떨어져 있어서,
IBOutlet Collection을 사용하기 어려울 거니 너무 신경쓰지 않아도 됩니다!
```

### 2. Modally vs Show
화면 이동 방식에 대해 고민을 했는데요,
처음엔 재고를 수정할 때만 잠시 보이는 화면으로 생각하여  Modally 방식으로 구현하려다가
* 이 프로젝트의 스토리보드는 가로로 고정이 되어 있고, 가로 화면에서의 Modally 방식은 원래 화면으로 돌아가도록 터치할 수 있는 빈 공간이 제공되지 않아서 버튼을 만들어야 했기 때문에 자동으로 backButton이 제공되는 Show 방식으로 구현하게 되었습니다.

STPE 3에서 '닫기' 버튼을 구현을 해야 해서 다시 Modally 방식으로 변경을 생각하고 있는데
* 저희는 가로 화면 고정과 버튼 생성을 기준으로 방식을 나눠 사용했지만, 실제 사용할 때는 어떤 기준으로 방식을 선택하는 게 좋을지 궁금합니다!

```swift
🐶🐶🐶
아무래도 닫기 버튼이 있어서 UX를 고려했을 때에는 Modally가 더 자연스럽게 느껴지는 것 같아요.
하지만 크게 상관없으니 두개 다 해봐서 차이점을 알아보는 것도 좋을 것 같네요 😊
```

### 3. 고차함수
FruitStore에서 과일의 재고를 [Fruit: UInt] 형태의 딕셔너리로 관리했었는데요,
처음에는 guard문을 활용하여 Optional binding에 실패했을 때 throw notExistFruit로 예외처리를 했습니다. 하지만, 실제로는 발생할 일이 없는 에러라서 조금 불필요하다고 느껴서 고차함수인 filter로 변경했어요.

#### filter
* 장점: 불필요한 Error를 만들지 않아도 됨
* 단점: 시간복잡도 O(과일의 개수)

#### guard문
* 장점: 시간복잡도 O(1)
* 단점: Optional 처리를 위해 불필요한 Error를 만들어 던져줘야함

과일의 개수가 많지 않은 점. 불필요한 Error를 위해 처리해주지 않고, 코드를 조금 더 깔끔하게 작성할 수 있는 점. 때문에 filter를 사용했는데요.
guard문이 더 좋을지. 아니면 더 좋은 방법이 있는지. 코리의 의견을 듣고 싶습니다 🐶
```swift
🐶🐶🐶
말씀하신 대로 현재 구조에서는 guard가 불필요해보이네요!
현재 미션 조건을 고려하면 filter 사용은 좋습니다! 다만 가독성이 조금 떨어져서
$0.key 나 $0.value가 무엇을 뜻하는지 정리해주면 좋을 것 같네요 :)
```

## 🤔 STEP 3의 고민

### 1. `IBOutlet` vs `IBOutlet Collection`
STEP2에서는 쥬스제조 화면에서 과일 재고에 대해 IBOutlet의 배열인 IBOutlet Collection을 사용했었는데요,
* 실제 과일 재고와 재고 레이블과 직접적으로 연결하기 힘든 점
* 추후 유지보수를 생각했을 떄, tag로는 충분하지 않은 점

을 이유로 JuiceMakerViewController, UpdateJuiceViewController에서 각 재고 관련 레이블들을 IBOutlet 여러개로 연결하여 구현했고 기존에 IBOutlet Collection도 IBOutlet으로 변경했습니다.
`*쥬스 주문` 버튼은 스토리보드에 적혀있는 버튼 text에 의존적이라는 단점이 있지만 일단은 IBOutlet Collection에서 변경하지 않았습니다.
스토리보드를 사용하면서 가장 힘들었던 부분이 코드가 스토리보드에 의존적이 된다는 부분이었는데요,
이를 해결하기 위해서는 어떠한 방법들이 있는지 가이드라인이라도 주실 수 있으실까요?
```swift
🐶🐶🐶
이번에 UpdateJuiceVC에서 IBOutlet으로 다 분리하신 부분 잘 구현하셨습니다! 👍
쥬스 주문 버튼같은 경우에도 현재는 스토리보드 의존도가 높기 때문에 모두 분리하는게 저는 좋아보입니다.

이를 해결하기 위해서는 뷰단을 코드로 만들어서 처리해야합니다.

모두 코드로 작성
코드 + XIB
스토리보드 + 코드
를 사용해서 의존도를 낮춰서 하나의 메소드로 여러 버튼을 처리하는 방법을 시도할 수는 있어보입니다!
```

### 2. 재고 추가 화면에서 닫기 버튼을 눌렀을 때, 초기 화면에 변경된 재고가 반영되지 않는 문제점
* 재고 추가 화면에서 닫기 버튼을 누르면 `fruitStore`에 저장되어 있는 재고가 초기 화면에 반영이 되지 않는 문제점이 발생하여
아래 방법을 통해 해결을 하긴 했는데, 혹시 더 좋은 방법이 있을까요?
```swift
override func viewWillAppear(_ animated: Bool)
```
```swift
updateStockViewController.modalPresentationStyle = .fullScreen
```
```swift
🐶🐶🐶
지금 viewWillAppear에서 구현한 부분도 깔끔하게 잘 구현하셨습니다!
protocol로 신호나 데이터 전달을 하는 방법도 있습니다 :)
```

## ⭐️ 배우고 느낀 점
### ✨ iyeah
[목표]
- [x] GIt과 친해지기
-> Xcode에서 Git을 사용하는 방법을 배웠다
- [x] Access Control, Nested Types, Type casting, Error Handling 처음 사용해 보기
-> 사용은 했지만 더 많은 공부가 필요하다
- [ ] 문제 해결 방법에 대해 혼자서도 고민해 보기
- [x] June에게 많이 배우고 도움이 되기 위해 노력하기
-> 많이 배운 건 확실한데 도움은 되지 못했던 것 같… 🥹

[배운 것]
* 매서드의 기능단위 분리
* 에러 처리
* self 키워드 사용 케이스
* Modality
* Alert Controller

[더 공부해야 할 것]
* Unit Test
* Naming
* Access Control
* ViewController Life Cycle

[느낀 점]
* 일단 아주 멋진 팀원 `june`을 만났다.
잘 풀어 표현해내지 못한 나의 생각과 의견을 경청해주고 여러 부분에서 많은 가르침을 받았다.
코드 컨벤션, 에러 처리, 유닛 테스트, git 사용법, 엄청난 양의 단축키까지!
내가 더 정신 바짝 차리고 흡수했다면 좋았을 걸 하는 아쉬움도 남는다.... 
* 더 공부하고 더 달려들었어야 한다는 생각이 든다.
뚝딱 뚝딱 잘하는 팀원에게 의지하여 완성하진 않았는가 하는 죄책감을 떨치기 어렵다.
대부분의 세션들은 프로젝트 진도에 맞춰 진행되기 때문에
프로젝트를 진행하며 세션에서 배운 것을 적용하며 나아가야 한다.
이미 놓쳐버린 부분들은 꼭 시간내서 복습하도록 하고, 앞으로는 진도에 잘 맞춰 예습과 적용을 해야겠다.

### 💡 june
* Swift에서 추구하는 명료성과 코드의 가독성을 위한 간결성을 동시에 만족시키는 것은 상당히 어려운 일이고 Swift 그만두는 날까지 가장 큰 숙제가 되지 않을까 싶다.
* IBAction, property, method 각각 네이밍 컨벤션이 있으며 따로 시간을 내어 이에 대한 정리를 해야할 것 같다고 느꼈다. (막상 프로젝트 진행하고 있을 때는 구현하기 바쁠테니 🥲)
* 스토리보드를 사용하면 협업 및 유지보수가 힘들어진다는 사실을 막연하게 알고 있었는데, 이번 프로젝트를 진행하면서 그 이유를 조금이나마 체감해본 것 같다는 생각이 든다. 코드가 스토리보드에 의존적이 된다던가... 배열(IBOutlet Collection)로 선언해도 인덱스 순서를 정하기 힘들다던가... 코드는 주석을 사용하여 의도를 드러낼 수 있지만 스토리보드는 그럴 수 없다는 것이 가장 큰 단점이지 않을까하는 생각이 든다.