달력

5

« 2025/5 »

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

'iOS Architecture'에 해당되는 글 2

  1. 2025.04.30 Architecture Pattern Framework의 문제점과 고민해볼 것들
  2. 2019.09.08 VIP를 읽어보고 고민한 것들

1. Intro

: iOS App을 개발하면서 Ribs나 TCA같은 Architecture Pattern을 사용하지 않았습니다. 해당 Architecture에서 동의하지 못하는 부분도 있었지만, Architecture를 사용하기 위해 별도의 의존성을 추가해야 하는 것이 위험해 보였기 때문입니다. 

 

 작년 하반기에, Robert C. Martin이 Framework에 대해 이야기하는 영상을 보았습니다. Uncle Bob은 해당 영상에서 Framework를 사용했을 때 겪을 수 있는 문제들에 대해 이야기를 하였는데요, 영상을 보면서 제가 Ribs나 TCA Module에 대해 갖고 있던 생각이 정리가 되어서 글로 작성해보았습니다.

 

2. Framework의 문제점과 고민해볼 것들

: Framework가 무엇인지부터 정의해보죠. Ribs, TCA 처럼 개발자가 Application을 효율적으로 개발할 수 있도록 이런저런 것들을 제공하는 것을 Framework라고 부를 수 있습니다. Framework마다 정해진 규칙, 흐름대로 개발자가 Code를 작성하게끔 유도하므로(이런걸 Invasive Framework라고도 합니다)... Project에 있는 Code들의 일관성을 높일 수 있고, 동료들이 Code를 파악하기 쉬워지니 협업에도 도움이 됩니다.

 

Invasive Framework

: Application을 개발할 때, Framework에서 제공하는 API나 Type을 이용하여 개발하게끔 하는 Framework.

 

 Framework를 이용하여 Application을 개발할 때, 생산성이 높아지고 편리해졌다고 느낄 수 있습니다. 하지만 시간이 갈수록 Application은 Framework에 깊게 결합되고 혹시라도 Framework에서 문제가 생긴다면 대응이 어려워지게 됩니다. TCA를 예로들면, 현재도(2025-04-30 기준) Xcode에서 Indexing이 느려져서 개발에 불편함을 주고있고, Swift Version Up 대응이 늦어지기도 했었습니다(link). 그리고 어떤 Spec을 구현해낼 때... Framework가 구현에 필요한 API를 제공하지 않거나, 예상하지 않았던 Flow로 Code를 작성해야 한다면 Framework가 오히려 방해가 될 수도 있습니다.

 

 Framework를 사용하는게 무조건 나쁘다고 단정지을 순 없지만, Framework를 Project에 사용하기 전에 몇 가지는 고민해보는게 좋을 것 같습니다.

 

1. Framework를 사용하여 무엇을 얻고싶나요?

2. 사용하고자 하는 Framework가 그것들을 제공해주나요?

3. 그 Framework를 사용한다면 어떤 위험들을 감수해야 하나요?

 

 Framework 대신에 단어만 바꾸면 일반적으로 많이 생각해보는 것들이죠? 만일 저라면... Redux와 유사하게 State를 관리하는 Code를 많이 작성하게 될 것 같고, Project 내 Code의 일관성을 높이고 싶으며, 사용하고자 하는 Framework에 존재하는 문제가 나에게 큰 영향이 없는 상황이라면 TCA를 사용할 것입니다.

 

 Uncle Bob이 Framework에 대해 이야기하는 영상에서 이런 말을 했습니다. 좋은 Architect는 Production Code가 Framework에 과하게 의존하지 않게하여, Framework를 Safe & Unintrusive하게 유지할 수 있게한다구요. 그리고 Framework를 사용하려면, Framework를 만든 사람들이 사용자를 위해 Commit하지 않으니(꼭 그렇지는 않습니다만) 직접 Commit해야 한다는 것을 알고 있어야 한다고도 말했구요.

 

 Framework에 너무 많은 것을 의존하지 않고, 충분히 고민 후 사용합시다. Framework는 도구니까요.

 

99. Reference

1) The problem with frameworks - Uncle Bob, youtube (link)

2) Invasive and Non-Invasive Frameworks in Java (link)

:
Posted by syjdev

Intro

 최근에, 동료와 함께 Demo App을 개편하는 일을 하게 되었다. Demo App의 주 목적은, 우리가 개발 및 배포하는 SDK에 대한 가이드와 간단한 동작을 보여주는 것이다. 그 외에 다른 복잡한 비즈니스적 요구사항이 없었고 시간상 여유가 있어서, 새로운 Architecture로 개발하기로 했다. 

 

 선택한 Architecture는 VIP인데, VIP를 설명하는 글에 따르면 Uncle Bob의 Clean Architecture를 참고해서 iOS 개발에 적합한 Component들로 구성한 Architecture라고 한다. 나는 VIP Architecture에 맞게 개발하기 위해 관련 글들(친절하게도, Sample Project도 공개되어 있다)을 읽었고, 생각한 것들을 여기에 정리해보고자 한다.

 

 

Vip의 Components 훑어보기

Clean Swift (VIP) Flow Diagram - 출처 https://hackernoon.com/introducing-clean-swift-architecture-vip-770a639ad7bf

 위의 Flow Diagram은, VIP를 구성하는 Component들을 보여주고, 어떻게 상호작용하는지를 보여준다. 역할이 애매하여 ViewController에 많은 코드를 넣는 실수를 줄이고자 Interactor와 Presenter를 두었고, Interactor에서도 Data를 가져오는 역할을 Worker가 담당하도록 하였다.

 

 Interactor는 View단의 요청을 받아서 자신의 역할을 수행하고, Presenter는 View단을 위한 Presentation Logic 처리를 담당한다. Router는 ViewController간 Transition 처리를 담당한다. Worker는 여러가지 Business Logic에 따라 다양한 처리를 하게 된다.

 

 

 

고민되는 것들

 

1) Router는 ViewController와 의존관계를 맺어야 하는가?

 Transition을 하기위해, 다음 화면을 노출하기 위한 정보가 필요할 수 있다. 예를들어, 쇼핑몰의 상품 목록에서 상품 상세화면으로 넘어가는 시나리오가 있다면 상세하게 보여줄 상품에 대한 ID가 필요할 것이다. Router의 역할중에 Transition시 Data를 전달하는 것도 있는데, Sample Project에서는 이를 위해 Router가 DataStore(Protocol)라는 것을 갖고 Interactor가 이 Protocol을 구현한다. 여기서 어색하다는 느낌이 들었는데, VIP Flow상 Router와 소통하는 Component는 ViewController 뿐이다. Sample Project는 VIP Flow와 맞지 않다.

 

 코드를 수정하여 ViewController에서 Transition에 필요한 정보가 있는 Model을 Router로 넘겨주게끔 수정하면 어떨까? VIP에서 ViewController에 Model을 넘겨주는 Component는 없다. 그리고 View가 Model을 직접 보는 것은, 일반적으로 좋지 않다.

 

 그렇다면 Presenter에서 'Transition에 필요한 추상화된 정보'를 ViewController로 넘겨주고, ViewController는 그 정보를 Router로 넘겨주면 어떨까. 그리고 ViewController는 'Transition에 필요한 추상화된 정보'를 그대로 Router로 넘기는 것이다. 그럴꺼면 애초에 Router가 ViewController가 아니라 Presenter와 상호작용 하는게 어떨까?

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
protocol Presenter {
    func presentSampleDetail(data: Data?)
}
 
protocol Router {
    func transition(from viewController: UIViewController, data: Data?)
}
 
protocol SampleRepresentable { }
 
class SamplePresenter: Presenter {
    var router: Router?
    var sampleRepresenter: SampleRepresentable?
    
    // data는 Interactor가 넘겨줄 것이다.
    func presentSampleDetail(data: Data?) {
        guard let viewController = sampleRepresenter as? UIViewController else { return }
        router?.transition(from: viewController, data: data)
    }
}
cs

 

 Router를 Presenter와 상호작용을 하도록, 위와같이 예제를 작성해보았다. 위의 간단한 예제를 작성하기 전에 Router와 상호작용 해야하는 Component가 Presenter 여야 할지, Interactor 여야 할지 고민이 되었다.

 

 Interactor는 이름이 온갖 역할을 다 해도 될것 같은 느낌을 준다(당연히 그러면 안된다). VIP Flow상 ViewController가 Interactor 무언가 요청하면, Interactor가 동작하고 필요에 따라 Presenter를 통해 ViewController가 갱신된다. 이때, Interactor는 presenter에 '무언가를 나타내줘'라고 요청하는 게 자연스럽다. 어떻게 보여줄지는 Interactor의 관심사가 아니다. 따라서 Presenter가 UILabel에 노출시킬 수 있는 단순한 문자열을 ViewController에 넘겨줄지, 다른 ViewController로 Transition하여 보여줄지 Interactor는 관심을 가져선 안된다고 판단했다.

 

 

2) Worker는 이해가 잘 안된다

: Worker같은 이름은 조심해서 쓸 필요가 있다고 생각한다. 'Manager라는 이름을 쓰지말자, 자제하자'와 비슷한 이유에서다. 아 그리고, hackernoon에 게시된 VIP 소개글을 읽을 때는 주의해서 읽는게 좋을 것 같다. Worker의 역할을, 마치 'Network나 내부 저장소에서 Data를 가져오는 Component'라고 오해하게끔 글을 적어놓았기 때문이다. 이건 조금만 생각해봐도 말이 안되는데, 성능상의 이유로 Network를 통해 가져온 Data를 내부 저장소에 Caching 해두는 시나리오를 생각해보자. 이때 Interactor가 Data를 요청한다면, Cached Data인지 확인해서 적절한 Worker에 요청해야 하는가? 당연히 그렇지 않을 것이다. Interactor는 Data가 필요할 뿐이지, 그게 Cached Data인지 Network로 요청해야 하는지에 대해서는 관심사가 아니기 때문이다(clean-swift에서 소개하는 VIP에서는 이렇게 적혀있지 않다).

 처음에는 Business Logic을 처리하는 Component를 Worker라고 굳이 명시해야 했는지 의문이 들었지만, VIP가 Clean Architecture를 참고하여 만든 Architecture라는 것을 떠올렸다. 아마도 VIP를 창조해낸 사람은, Interactor가 Model에 직접 의존하는 것을 가능한 막고 싶었던 것이겠지.

 

 

 

마무리하며

 VIP를 설명하는 글을 읽고, VIP는 현실의 일부 복잡한 문제들에 적용하기 어렵다는 생각이 들었다. 그냥 어떤 문제에서 잘 쓰일 수 있는 Solution인 것이다. 고민한 내용을 동료에게 공유하여, 현재 작업중인 Demo App 개편을 어떻게 할지 이야기를 나눠보아야 겠다. 아직 경력와 역량이 부족한 내가, 잘못 생각한 걸지도 모르기 때문이다.

 

 

 

Reference

- https://clean-swift.com/clean-swift-ios-architecture/

https://hackernoon.com/introducing-clean-swift-architecture-vip-770a639ad7bf

https://github.com/Clean-Swift/CleanStore

:
Posted by syjdev