윈디정 (윈터 디저트의 정석)
추운 바람 사이에 있는 따뜻한 정이 있는 음식을 주문 할 수 있다!
사라지는 겨울 간식을 독점하자. 내가 다 팔겟다. 틈새시장 공략.
2024.11.25 ~ 2024.11.29
BottomView
├── Button
│ ├── ButtonStack
│ ├── EmptyCartButton
│ └── PurchaseButton
├── Cart
│ ├── CartRowStackView
│ ├── CartTableView
│ └── CartTableViewCell
├── Label
│ ├── TotalPriceLabel
│ ├── TotalQuantityLabel
└── BottomView
BottomView라는 큰 틀 안에서 다시 하단 버튼, 장바구니, 레이블로 나누었다.
버튼은 추후 직원 호출과 같은 추가적인 버튼이 배치될 수 있어 미리 스택뷰에 넣었다.
최종적으로 뷰컨트롤러에서는 바텀뷰만 선언하여 사용하면 되었고,
MVC 패턴을 염두에 두었기에 사용자 인터랙션에 반응하여 데이터를 변경하는 로직은 컨트롤러에서, UI업데이트를 위한 로직은 뷰 내부에서 구현하기로 했다.
이를 위해 클로저 콜백을 활용하여 하단 버튼, 테이블뷰 셀 내부의 버튼 등의 액션을 컨트롤러에서 담당할 수 있게 하였고 UI업데이트 관련 사항은 점표기법으로 접근하여 사용하였다.
이번 프로젝트의 조건이 여럿 있었지만 가장 큰 문제는 하나의 뷰컨트롤러만을 사용하여야 한다는 것이었다.
때문에 역할을 나누기도 애매하고 서로의 작업을 합칠 때 발생할 컨플릭트도 문제였다.
나는 이전에 해왔던 것처럼 각자의 뷰를 만들고 추후 컨트롤러에서 합치자는 방식을 제안하고 그에 맞춰서 역할을 분리하자고 했었다.
MVC에 맞추어 상단뷰, 하단뷰, 데이터, 버튼 액션 등으로 나누고 뷰컨트롤러에서 합치는 작업만 따로 하면 될 거 같았다.
그러나 실제 역할 분배 회의에서 내가 참석을 못하면서 데이터와 버튼 액션에 대한 역할 분배가 되지 않았다.
또, 뷰를 만들고 하나로 합치자고 한 말은 각 뷰에 대해 서브클래스를 생성하자는 말이었으나 팀원들은 전부 뷰 컨트롤러에 각자의 뷰를 만들어왔다.
결과적으로 뷰 컨트롤러가 앱의 기능에 비해 엄청나게 비대해졌고 데이터와 액션은 마지막날 새벽이 되어서야 완성되었다.
비대한 컨트롤러 안에서 원하는 위치를 찾기 위해 탐색하는 시간이 길어졌고 이로 인한 시간 부족은 다시 또 안 좋은 코드를 만들어냈다.
이건 누구 하나의 잘못이라기보다 톱니바퀴가 맞물리듯 작은 불협화음이 하나씩 쌓여 스파게티를 만들어냈다. 사실상 제대로 된 해결은 이루어지지 않았고 프로젝트를 완성해냈다는 것에 의의가 있었다.
언젠가 리팩터링 해야지..하는 생각은 있지만 클린 코드에 나왔던 르블랑의 법칙처럼 아마 그 언젠가는 오지 않을 거란 생각도 든다.
다음부터는 좀 더 확실하게 의견을 교류하고 규칙을 맞춰야 한다는 생각만이라도 잘 가져가야지.
UIKit의 UITableView를 Swift UI의 List처럼 쓸 수 있을 거란 큰 착각을 했었다...
선언형 프로그래밍 언어가 얼마나 사용하기 쉬웠는지 역체감하는 과제였다. 현대적이고 간결한 언어 최고..
테이블 뷰의 셀을 재사용한다는 부분이 제일 이해가 안 되었다. 재사용 식별자는 단 하나뿐인데 이걸 이용해서 셀 자체를 재사용한다는 것을 셀 하나하나 모두 구별하여 그것들을 재사용한다는 것과 혼동했고 이해하는데 시간이 걸렸다.
또 커스텀 셀 이니셜라이저를 사용할 때 정해진 파라미터만 호출하는 이니셜라이저만이 행 추가 시 호출되었는데(원래 이런 건지 내가 잘못 사용한 건지는 아직 파악하지 못했다.) 새로운 행 생성 시 파라미터로 바로 데이터를 넣어주려고 했는데 계속해서 에러가 발생했었다.
해결을 위해서 셀을 추가할 때 새로운 데이터를 바로 넣어주지 않고 셀 내부의 값을 업데이트해주는 메서드를 따로 행의 데이터를 구성하는 메서드 내부에 넣어줘서 해결했다.
기존의 야구 게임과 계산기에서는 클로저 콜백을 통해 많은 뷰 계층을 이동하지 않았다. 이번 바텀뷰를 만들면서는 뷰 컨트롤러에서 바텀뷰로, 바텀뷰에서 테이블뷰로, 테이블 뷰에서 셀에 있는 스택뷰의 버튼으로 내려갔다. 그 구조를 맞춰가는 과정에서 파리미터를 활용해 원하는 액션으로 분기하거나 버튼을 구분하는 법을 알게 되었다.
또 테이블 뷰의 셀이 가진 버튼을 어느 위치에서 상위로 연결시키는지도 알게 되었다.
이번 깃 전략은 각자의 레포지토리로 포크해간 뒤 커밋과 푸시를 하고 원본 레포지토리의 본인의 브랜치로 풀리퀘스트를 한 번 넣었다.
이때 서로의 코드를 리뷰한 뒤 다시 원본 레포지토리의 dev 브랜치로 풀리퀘스를 하고 마지막으로 main에 머지를 했다.
매번 내 레포지토리를 원본 레포지토리와 동기화 하는 작업이 추가되긴 했으나 많은 풀 리퀘스트는 그만큼 더 안정적이고 코드에 대한 리뷰를 받을 수 있는 기회를 늘려주는 만큼 좋은 방법이라 생각되었다.
대신 트레이드오프로 약간의 다른 부분도 모두 컨플릭트로 처리되어 하나의 파일을 수정하게 된다면 반드시 컨플릭트 해결 과정이 필요했다는 점이 아쉬웠다.
또 포크의 문제인지는 모르지만 많은 부분이 한 번에 변경되었을 경우 반드시 깃데스크탑이나 웹 기반이든 프로그램이든 커맨드라인 툴을 열어서 컨플릭트를 해결해야 하는 경우도 있었는데 팀원 모두 처음 겪는 일이라 당황했었다.
만들어나가는 과정에서 여러 예외처리나 추가적인 기능 요구사항을 해결하는 과정이 꽤 재미있었다.
다음에는 레이블을 하나 쓰더라도 그 안에 들어갈 문자열의 길이를 신경 쓰게 될 것이고, 버튼 하나의 UI도 사용자의 경험이 어떻게 될지를 고려해볼 수 있는 시야를 갖게 해준 의미있는 프로젝트였다.
버튼 하나의 동작엔 하나의 ui업데이트가 거의 필수적이라는 점도 잊지 않을 것이다.
앞서 작성한 클로저 콜백과 깃 포크 외에도 많은 부분을 처음 접하고 새롭게 배웠지만 다 정리를 하지 못하는 것이 아쉽다.
역시 클로저 콜백과 테이블 뷰에 대해서만이라도 다시 공부하며 따로 정리해서 올려야곘다.
정말 가능하다면 꼭 리팩터링을 진행해보고 싶은데 바로 다음주부터 더 심화 기술이 필요한 프로젝트를 시작하게 되어 시간이 생길지 모르겠다.
이번엔 한 번 배우고 사용해봤던 클로저 콜백을 좀 더 확장해서 써보았으니 다음부터는 다른 방법인 델리게이트 패턴과 노티피케이션 센터를 활용하여 비동기 작업을 해봐야겠다.
이번에 비록 mvc 패턴을 잘 적용하진 못했지만 다른 팀원들의 과제 발표를 보면서 지난 계산기 앱 구조와 이번에 원했던 이상적인 구조 등을 비교하니 어느정도 감이 생길 거 같았다.
이 외에도 많이 사용되는 MVVM 패턴에 대해서 공부하고
레이어드, 클린, 헥사고날 아키텍처에 대해서도 공부해야겠다.
구조를 정하고 어디에 어떤 코드를 넣을지 고민하는 과정이 머리 아프지만 그래도 재미있어서 적성에 맞는 듯하다.
겨디정