iOS 애플리케이션을 위한 상향식 개발 Part 1 - 모듈화

Steve Kim
8 min readMar 26, 2022

--

https://en.wikipedia.org/wiki/Top-down_and_bottom-up_design#/media/File:Lego_Chicago_City_View_2001.jpg

시작하며

필자는 Flash 애플리케이션 개발에서부터 iOS 애플리케이션에 이르기까지 GUI 애플리케이션을 개발하는데에 있어 꾸준히 활용하고 있는 방식이 있다. (오히려 이전보다 더욱 발전시켜 사용하고 있다.)

그것은 바로 상향식 개발 방식이다. 아주 오래된 개발 방식이지만 세월이 지나고 시대가 바뀌어도 이 개발 방식은 여전히 유효하다. 특히 GUI 애플리케이션 개발은 20년 전이나 지금이나 크게 바뀌지 않았다.

상향식 개발

레고 블럭으로 작품을 만드는 것을 상상해 보라.

작품 전체를 만들기 위해선 사람과 나무 등의 구성요소들을 먼저 디자인하고 만들어야 한다. 그 후 블럭들을 꼽을 수 있는 넓직하고 비어있는 플랫폼에 요소들을 배치하여 작품을 완성한다.

사람을 만들기 위해 사람을 구성하는 요소들을 (예를 들어 머리, 팔, 다리, 몸통 그외 특징을 나타낼수 있는 꾸밈요소) 완성한 후 이들을 조합해 하나의 사람 모형을 완성한다.

사람의 구성요소 중 팔을 만들기 위해 팔을 구성하는 손, 팔목, 아래팔, 위 팔, 어깨 등의 구성요소를 먼저 만들어 조립해 하나의 팔 모형을 완성한다.

상향식 개발 방식이란 위에서 예시를 든 레고 작품을 만드는 방법과 크게 다르지 않다. 애플리케이션 전체를 완성하기 위해 애플리케이션이란 완성품을 기준으로 접근하는 것이 아니라 이를 구성하는 구성요소의 가장 작은 단위에서부터 점진적으로 완성해 가는 방식이다.

물론, 전체 애플리케이션 아키텍처에 대해 신경쓰지 않고 설계하라는 것은 아니다. 다만 완성품에 대한 설계는 느슨하고 가볍게 접근하며 구현의 흐름을 구성요소에 초점을 맞춰 완성해 가자는 이야기이다.

상향식 개발에 대해 좀 더 알고 싶다면

이 아티클은 상향식 개발 방식이 무엇인지에 대해 설명하는 글은 아니다.

상향식 개발 방식을 iOS 애플리케이션 개발에 어떻게 활용하는지에 대해 설명하고자 한다. 또한 이해를 쉽도록 하기 위해 요즘 떠오르는 SwiftUI 대신 기존 레거시 UIKit 기준으로 작성하였다.

모듈화

상향식 개발 방식에서 가장 중요한 것은 구성요소들에 대한 모듈화이다.

가장 하위 구성요소에서부터 모듈화가 잘 되어 있어야 레고 블럭처럼 필요에 따라 결합 사용이 가능하다.

필자가 여태까지 참여한 레거시 프로젝트들은 애플리케이션을 작성하기 위해 기본적으로 필요한 네트워크, 인증, 이미지 로딩 및 렌더링 모듈 등을 제외한 나머지 부분에 대해선 대부분 모듈화가 되어 있지 않았다.

모듈화 되어 있다고 한 것들도 오픈소스 라이브러리나 회사의 공통 모듈을 사용하는 수준의 모듈화이지 팀의 모듈은 아니었다.

때문에 프로젝트에선 늘 자주 사용하는 코드의 중복과 보일러플레이트 코드들이 난무했고, 뒤늦게 참여한 팀원의 입장에선 특정 기능을 구현하기 위해 어떤 방법을 사용할 지에 대한 고민이 필요했다.

예를 들어 한 프로젝트에 간단한 팝업 레이어를 띄우기 위한 구현이 여럿 존재한다던지, 얼럿을 띄우기 위해 샘플 코드처럼 모든 것을 구현해야 한다던지…

모듈화의 장점은

첫째, 언제끝날 지 측정하기 어려운 프로젝트의 진행도를 보다 투명하게 확인할 수 있도록 해준다.

둘째, 문제를 작은 단위로 쪼개어 정복할 수 있기 때문에 복잡성을 낮출 수 있다.

셋째, 유닛테스트와 사용 예시가 잘 갖추어 있다면 코드 신뢰도를 높일 수 있는데, 이것은 애플리케이션의 전체에 적용하는 것보다 작은 단위에서 적용하는 것이 유리하다.

모듈화! 어디서부터 어떻게 할 것 인가

나는 특정 기능을 구현하기 위해서가 아니라도 기본적인 SDK 사용에 대해서도 팀에서 공통으로 사용할 모듈이 준비되어 있어야 한다고 생각한다.

작성한 모듈은 꾸준히 업데이트 되고 발전되어야 하며 팀의 공동 자산이 되어야 한다.

이렇게 작성된 팀의 공동 자산 모듈이 견고하고 신뢰성이 높아진다면 현재 진행하고 있는 프로젝트가 드랍 되거나 변경 되더라도 팀의 생산성이 크게 위협받거나 두려워할 일이 사라진다.

언제든 새로운 프로젝트를 시작할 준비가 되어 있는 것이다.

UIKit 모듈화

애플리케이션 구현 시 중복과 보일러플레이트 코드가 많은 UIKit을 간단하고 중복 구현없이 사용하게 하기위한 모듈이 필요하다.

나는 어떤 팀에 조인하더라도 가장 먼저 하는 것이 UIKit 모듈을 작성하는 것이다. 대부분 이전에 사용하던 것을 재활용하고 prefix만 바꾸는 수준으로 시작해 팀에 맞도록 계속 발전시킨다.

prefix는 보통 현재 내가 속해 있는 조직의 이름을 따르도록 한다.
e.g) orgname-uikit-ios

작성 시 유의사항

  1. 커스텀 UI 컴포넌트들은 되도록 일반화해야 하고 확장 가능한 형태로 제공되어야 한다. (SRP, OCP 준수)
  2. 기본 추상 클래스는 중복과 보일러플레이트 코드를 피하기 위한 수준의 추상화만 제공해야 한다.
  3. 되도록 Apple SDK의 기본 기능을 사용해 구현해야 한다.
    RxSwift 등의 서드파티 모듈 의존성이 포함되지 않도록 한다.

아래 예제를 한 번 살펴보자.
2번에 따라 생성자 선언에 관련된 중복과 보일러플레이트 코드를 줄이고자 추상 클래스를 작성했다.

BaseView.swift

UIKit 모듈 구성

Extension

  • Foundation
    Apple Foundation 모듈에 부합하는 확장 프로퍼티, 함수, Subscription 모음
  • UIKit
    Apple UIKit 모듈에 부합하는 확장 프로퍼티, 함수, Subscription 모음
  • SE Support
    iPhone SE 시리즈와 같이 다양한 스크린 크기를 지원하기 위한 유틸 모음
  • Type Casting
    타입 캐스팅을 간편하게 하기 위해 준비된 오퍼레이터 모음

Math

수학 관련 확장 함수 모음
e.g) BinaryFloatingPoint+Trigonometric.swift

Component

  • Base
    UIView, UITableViewCell, UICollectionViewCell 등을 최소한으로 확장한 추상 클래스 모음
  • Cell
    일반화한 Custom Cell 모음
  • Control
    일반화한 Custom Control 모음
  • View
    일반화한 Custom View 모음
    e.g) ToastView, SnackBarView, StatusWindowToastView

Controller

Custom Controller 모음
e.g) ActionSheetController, PopUpController

Presenter

UI 컴포넌트를 화면에 띄우고 제거하거나 스타일을 커스터마이징 하기 위한 대리자 모음
e.g) Toast, SnackBar, StatusWindowToast

Utils

공통 유틸 모음

그 외 Filter, Graphics, Geometric 등 공통 함수들도 모듈에 포함된다.

애니메이션 모듈화

애니메이션은 GUI 애플리케이션 개발에 필수적인 구현 중 하나이다. 이 구현 또한 많은 중복과 보일러플레이트 코드를 만들어낼 우려가 있다. 또한 애니메이션 기능을 사용하기 위한 다양한 API가 존재하므로 개발자에 따라 각기 다른 구현이 될 가능성이 농후하다.

무작정 구현할 것이 아니라 잘 갖추어져 있는 오픈소스 라이브러리를 사용하는 것도 좋은 방법이다. 우리 팀은 적합한 오픈스소 라이브러리를 찾지 못해 layer-animation-kit-ios 모듈을 작성해 사용 중이다.

아키텍처 모듈화

Apple SDK는 유명 아키텍처에 대한 템플릿을 제공하지 않는다.

팀 내에서 사용할 아키텍처 템플릿을 일반화하고 모듈화 해두면 누구나 동일한 형태로 쉽게 구현할 수 있다. 추가로 Xcode File Template을 활용해 템플릿화 해놓는다면 훨씬 더 도움이 될 것이다.

그 외 모듈화

ZeplinDSL

최근 대부분의 프로젝트에서 디자인과의 협업을 위해 Zeplin을 사용할 것이다.
(Figma로 바뀌고 있는 추세이지만)

Zeplin 디자인 가이드를 보면 실제 개발을 위한 API와 괴리감이 있는 속성들이 꽤나 많이 존재한다. 개발자는 Zeplin 디자인 가이드를 보며 실제 코드에 반영하는데에 어려움을 호소한다.

Zeplin과 API와의 다른 속성들을 매핑해 주는 기능을 DSL 형태로 제공하는 모듈이다.

Zeplin
ZeplinDSL Sample

마치며

상향식 개발 방식의 가장 기본이 되는 모듈화에 대해 iOS 애플리케이션을 모듈화하는 아주 계략적인 예시를 들어 설명했다. 모듈화를 적용하는데에 완벽히 정석적인 방법은 없다. 간단한 구현이라도 패턴을 잘 분석하여 모듈화 할 수 있도록 항상 고민하는 자세를 가져야 한다. 처음엔 어려울지라도 충분히 연습하고 적용한다면 길이 보일 것이다.

--

--