
👋 들어가기 전
회사에서 굵직한 스프린트가 하나 마무리되어 오늘은 오랜만에
회고를 하는 시간을 가지려한다.
회고 내용은 바로 어제 iOS 개발 팀 앞에서 발표한 나의 리팩토링 경험이다.
리팩토링을 하며 배운점과 느낀점을 중심으로 돌아보려한다.
✊무엇을 리팩토링 했는가?
12월 10일에 일을 시작한 나의 첫 스프린트 임무는 MVP를 증명할 수 있는 앱을 2주만에
찍어내야했다. 하지만 크게 3가지 문제가 있었다.

1. 미리 짜여져있는 코드
미리 짜여있는 코드를 그대로 가져가야하는 지, 내가 다시 짜야하는 지 결정이 빠르게 되지 않았다.
게다가 짜여있는 코드 조차 iOS개발을 주로 하신분이 아니라 코드를 이해하는데도 생각보다 오래걸렸다.
2. 자신없는 UI Framework
UIKit을 자주 사용했던 나와 달리 미리 짜여져있는 코드들은 SwiftUI로 작성이 되어있었다.
스유를 아예 안해본 것은 아니지만 SwiftUI에 대한 자신감은 UIKit 만큼은 없었다.
3. 부족한 시간
정말 물리적인 시간자체가 부족했다.
기존 코드를 읽고 이해하는데도 시간이 부족하고, 아키텍쳐가 아예 없는 정말 날 것 그대로였기 때문에
비지니스 로직과 UI 로직이 분리가 되지 않아 있었다.
빨리 찍어야하는 것은 이해가 되지만, 정말 이대로 가는게 맞을까?? 라는 생각을 많이 했다.
☝️현실과의 타협
먼저 SwiftUI는 그대로 가져가되 비지니스 로직과 UI 작업은 분리해야 된다고 결정하여
View에 박혀있던 비지니스 로직을 ViewModel에 옮기며 동시에 코드도 정리를 해나아갔다.
그러나 문제가 하나 더 발생했다.
비지니스로직이 생각보다 많아져 뷰모델 자체가 굉장히 비대해졌고
일단 시간이 짧게나마 다음과 같은 형태로 일단 1차 리팩토링을 진행했다.

MVP 증명은 됐지만 이제부터 본격적인 서비스를 만들어야하는 스프린트에 돌입했다.
하지만 그 과정에서 지금 구조에서는 다음과 같은 문제가 생겼다.

위와 같은 문제들은 협업에 부정적인 영향을 주기 때문에 리팩토링은 필수적이였고
나는 이번 스프린트 때 리팩토리를 진행했다.
다음은 내가 리팩토링 내용을 함께일하는 개발자분들에게 발표하고
코드리뷰를 받은 과정을 공유하려한다.
✌️S.O.L.I.D 너 실제로 쓰이는 구나??
이번 리팩의 핵심은 객체의 책임을 최대한 잘게 부수는 과정이다.
이전 그림을 보면 Uploader라는 객체가 upload 과정 전에 굉장히 많은 전처리가 필요한데
그 과정을 Uploader에서하고 있고, ViewModel도 과도하게 많은 책임을 갖고 있다.
이번 리팩토링 과정에서 나는 SOLID 이론을 직접 적용해본 경험이 너무 좋았다.
신기했던건 당시에는 SOLID를 염두한 것은 아니지만 더 간결하게 만들려고 하다보니
결과적으로 SOLID의 내용이 무의식적으로 나왔다는 점이다.
SOLID에 대한 내용이 궁금하면 내가 정리한 글도 있고, 훨씬 잘 정리된 글도 많으니 찾아보길 바란다.
객체 지향 프로그래밍 (2) [ S.O.L.I.D ]
오늘은 객체 지향 프로그래밍 설계 원칙인 S.O.L.I.D 원칙에 대해 알아보자 SOLID란?SOLID 원칙들은 결국 클래스 내부 응집도는 높이고, 타 클래스들 간 결합도는 낮추는 High Cohesion(응집도) - Loose Cou
hamp.tistory.com
1. SRP
책임 분산을 곰곰히 생각해보니 배운 SOLID의 S가 생각이 났다.
단일 책임 원칙.. 역시 이론이란건 실제 쓰이는게 맞는 것 같다.
먼저 앞선 그림은 3개의 객체의 구조로 많은 책임을 지다보니 자연스럽게 특정 객체가
비대해지고 관리과 어려워졌다.
그래서 전체적인 프로세스를 나열하고 공통 객체로 묶을 수 있는 작업들을 정리하여
오른쪽과 같이 5개의 객체로 책임을 나눌 수 있었다.

2. OCP
두번 째는 개방 폐쇄 원칙이다.
이전 구조에서는 하나의 객체에 기능이 몰려있기 때문에 변화가 일어나면 다양한 곳도 영향을
받았었는데, 이번에는 프로토콜을 적극적으로 적용해서 다음과 같이 개선했다.
Uploader 객체에서는 여러개의 validator를 갖고 있는데 이 때 Uploader 입장에서는
validator의 validate 함수만 알고 있기 때문에 별도의 변화에 대해서는 전혀 영향이 없는
구조가 되었다.
protocol Validatable {
func validate() throws
}
class someValidator {
...
func validate() throws
}
3. DIP
마지막은 의존관계 역전 법칙이다.
기존에는 빠른 MVP 검증을 위해 직접적인 구현체를 의존했지만
현재는 모든 객체들이 protocol 타입으로 의존성을 주입받아, 독릭성을 유지하고,
객체간의 결합도를 최소화시켜 테스트 용이성과 코드 재새용성을 확대시켰다.

👍 리팩토링 결과
개선된 점은 굳이 쓰자면 다음과 같이 짤지만, 과정에서 배운 개인적인 성장은 정말 뜻 깊었던 같다.

😀 소감 및 마무리
현업 개발자분들께 오프라인으로 코드리뷰를 받은 경험은 정말 떨리고도 가슴뛰었다.
특히, 내가 한 부분을 발표자료로 준비하여 나의 과정을 숨김없이 전부 전달하고
거기에 따른 냉철하지만 속 깊은 피드백은 "아 이래서 코드리뷰를 꺼려하면서도 하는 이유가 있구나"
라는 생각을 들게 했다.
코드리뷰에서 받은 피드백이나 조언은 조금만 더 깊게 생각해내면 떠 올릴 수도 있던게
내용이 있었지만 그걸 하지 못했던 것에 대한 자괴감과 부끄럼움을 느꼈고
그 만큼 현업분들의 영양가 있는 생각을 듣게되어 리뷰의 필요성을 동시에 느꼈던 것 같다.
어제 발표 이후 팀원분들은 이런 코드 리뷰 자리를 많이 갔자는 얘기가 나왔고
부족한 내 발표를 "준비하느라 고생했다", "잘하셨다" 라고 따뜻한 말도 들어 나름 기분이 좋았다.
출처
'iOS' 카테고리의 다른 글
시뮬레이터 vs 에뮬레이터 (0) | 2025.01.26 |
---|---|
샌드박스와 파일시스템 (0) | 2025.01.26 |
패키지 만들기 (0) | 2025.01.07 |
Localization (1) | 2024.12.28 |
[ 부스트 캠프 ] 채팅 기능을 위한 웹소켓 만들기 (1) | 2024.11.30 |