View

300x250

이번에 프로젝트의 전반적인 구조를 클린 아키텍처로 구현해보는 것을 하나의 과제로 삼고 진행해보려 노력했다. 아무래도 구조 자체가 추상화가 많이 되어있다보니, 구조의 의도를 이해하는데에 시간과 노력이 꽤나 들어갔던 것 같다.

아키텍처를 잘 써보고 싶어서 요런 고민도 했었고 Riverpod을 통해 클린 아키텍처를 적절히 구현하려고 요런 고민도 했었다.

그리고 실제로 계층 구조를 나누고 그 위에 코드로 기능들을 구현을 하면서 여러가지 장단점이 눈에 들어왔다. 물론 내가 처음에 구조를 잘못 나눠 불편한 점도 많이 있었지만, 어떻게 해야 좀 더 의도에 적합하게 코드를 작성할 수 있을 지도 눈에 들어오기 시작했다. 그 경험들을 잊기전에 짧게 기록으로 남겨두려 한다.

단점부터 시작하자

러닝코스트가 너무 높다!

러닝코스트는 생각보다 큰 단점이였다. 물론 그 계층들의 의미, 구조의 의의를 이해하고 나서는 어디에 어떤 코드를 넣으면 될 지가 눈에 보이기 시작했지만, 그 전에 한 1~2주 동안은 클린 아키텍처가 뭘 위한 구조인지도 파악하기가 좀 어려웠던 것 같다. 아키텍처를 적용한 팀프로젝트라면 팀원들 모두가 클린 아키텍처를 이해해야 진행할 수 있을텐데, 요 부분이 나 같이 학교 과제용 팀프로젝트나 토이프로젝트 규모의 학생 레벨 서비스 개발에서 클린 아키텍처를 적용하기 힘들게 만드는 부분이 아닐까 생각했다.

보일러 플레이트 코드가 너무 많다!

요것도 귀찮고 번거로웠다. 물론 이런 보일러코드들을 자동으로 작성해주는 툴이 있다고 하지만, 그런걸 사용해야 할 정도로 쓸데없이 반복해서 코드를 작성해야 하는 일이 많다는 의미로 받아들여졌다. 뷰모델에서부터 데이터소스까지 연결되어야하는 데이터 패스가 거쳐가야하는 계층이 많다보니 어쩔 수 없나 싶기도 하고, 그럼에도 각 계층에 반복적인 형식으로 작성되어야 하는 코드가 있는건 좀 귀찮게 느껴지긴 했다.

프로젝트 초반에 장점을 느끼기 힘들다

내가 생각하는 클린아키텍처의 장점은 확장성이였다. 주요한 비즈니스 로직은 그대로 두고 Presentation Layer를 웹이나 앱, PC용 프로그램으로도 만들면 어디로든 동일한 로직을 적용할 수 있게 되고, DB에서 데이터를 가져올 때 인터페이스만 따르면 로컬DB, 네트워크상의 여러 DB 서비스 등 어디에서나 동일한 형식으로 데이터를 받아와 사용할 수 있으니 이런 의존성의 분리를 통한 Presentation Layer, Data Layer 구현체의 변경가능성이 큰 장점이라고 생각되었다.

그러나, 실질적으로 여러 개의 프론트엔드, 여러 개의 백엔드를 가져야 할 만큼 프로젝트가 커지는게 어느 시점인가? 를 생각해보면, 요런 아키텍처를 적용해서 장점을 느끼는 시점이 프로젝트가 어느정도 운영이 된 이후라고 생각이 들었다. 요런 큰 규모로 다양한 책임을 분리하고 추상화하는 아키텍처는 리팩토링 시점에 적용하는게 빠른 초기 서비스 개발이나 장점을 느끼기에 더 적절하지 않을까? 라고 느꼈다.

그럼에도 내가 느낀 장점

확장성이 좋다

확장성은 인정. 클린 아키텍처를 적용해 코드를 작성하고 폴더링을 하면서, 프로젝트의 먼 이후 시점을 생각했을 때에는 너무나도 깔끔하게 코드가 운영될 수 있는 설계라고 생각되었다. 2개 이상의 DB를 사용한다면 어떻게 처리해야 할까? 혹시 웹도 지원하게 되면 어떻게 처리해야 할까? 를 생각해봤을 때, 요렇게 인터페이스로 나누고 각 DB의 데이터 모델을 엔티티로 변환해 사용하는 등의 프로세싱으로 이런 것들을 다 처리할 수 있을 것 같다고 느껴진다. 그런 이유에서 코드를 짜고 폴더에 넣으면서 요 귀여운 녀석들이 재활용될 미래를 상상하니 설렘이 느껴졌다 🥰🥰

구조만 한 번 이해하면 코드의 책임과 작성되어야 하는 폴더가 보인다

작성한 각 코드가 어디 위치에 저장되어야 할 지가 너무나도 명확하게 구분되어있었던 것 같다. Presentation Layer의 View, ViewModel과 DataModel을 나눠두고 Domain Layer의 Usecase, Repository, Entity와 Data Layer의 Repository, DataSource, Model을 구분해두니 “내가 생각할 때 요 코드는 이런 역할이야” 라고 생각하는 곳에 파일을 넣으면 되고, 그 곳에 가면 코드가 있었다. 요런 점은 아주 편했던 것 같다.

불편한 건 플러터였나 🤔

블로그 글을 작성하면서 다시 생각해봤을 때, 어쩌면 내가 느꼈던 클린 아키텍처를 구현할 때 불편했던 점들이 플러터의 불편했던 점들인 것 같기도 하다. Riverpod을 통해서 생성한 DataSource 오브젝트를 WidgetRef로 넘겨주는 부분이라거나 ViewModel(Provider)과 View의 연결이라거나. 오히려 플러터에 익숙치 않아서 플러터스럽게 코드를 짜지 못해 발생한 구현상의 문제인 것 같기도 하다. 흠… 요건 플러터에 대한 숙련도 이슈라 좀 더 연습이 필요할지도?

지금 프로젝트 구조를 갈아엎을 필요가 있음!

처음에는 아래 이미지처럼, 서비스 내 뷰를 기준으로 폴더를 나누고 그 안에 각각 Presentation, Domain, Data 폴더를 만들어 파일을 관리했다. 의도는 “각 뷰 별로 3개의 레이어에 파일을 분리해 관리하자” 였는데, 결론적으로는 실패했다.

Untitled.png

Untitled.png

실패의 원인은 이거다. 막상 기능개발을 해보니, 데이터 계층의 로직과 도메인 계층의 로직이 여러 뷰에서 재활용되어야 하는 일이 너무 많았다. 생각했던 만큼 ‘뷰 단위 구현의 분리’는 의미가 없었다. 이로 인해 발생한 문제는 아래와 같다.

  1. UseCase를 활용해 B 기능의 DataLayer 를 끌어다 사용한다고 하더라도, A 폴더의 Domain Layer에서 B 폴더의 Domain Layer에 접근해야 했다. 이렇게 되니 폴더 사이에 촘촘한 의존성이 생겨버리면서 폴더로 파일들을 구분시킨 의미가 없어져버렸다.
  2. 중복 코드를 작성하는 일이 꽤나 빈번하게 발생했다. 예를 들면 ‘post id에 대해 작성한 User가 누구인지 FB에 쿼리를 날려 사용자 정보 받아오기’ 같은 코드는 여러 뷰에서 사용될 수 있는 기능인데, 누가 미리 이걸 구현해뒀는지 알 수 없고, 어떤 화면에서 구현되어 있을지 일일이 확인해보기도 힘들다. 각 뷰에서 필요한 기능을 각자가 개발하다보니 여러 뷰에서 활용될 수 있는 코드가 중복 작성되어있기도 했고, 데이터 모델과 파이어베이스 쿼리 로직까지 여러 개가 작성되어 있기도 했다. 심지어는 두 로직의 구현이 다르고 데이터 모델 구조가 달라서 내부적으로 문제가 발생한 경우도 있었다.
  3. DB나 UseCase 코드가 여기저기 폴더에 여러 파일로 파편화되어있다보니, 정작 DB source를 다른 것으로 교체하고 싶다고 해서 원하는대로 교체할 수 없는 설계라는걸 느꼈다. 내가 원했던 건 파이어베이스로 연결된 DB를 테스트용 데이터가 있는 DB로 코드 한 줄 바꿔서 갈아끼우면 모든 기능은 동일하게 동작하지만 데이터를 테스트 DB에서 가져오는 거였는데, 지금은 전혀 그런 코드가 아니다. 이걸 코드 한 줄을 통해 어떤 DB에서 데이터를 가져올지 선택하도록 바꿔야하는건 20000% 동의한다.

Untitled.png

이런 이유에서 아예 이렇게 폴더 구조와 파일 구조를 개편하려고 생각하고 있다.

Untitled.png

  1. 뷰는 뷰끼리 폴더를 나눠두고 관리를 한다. 뷰모델은 상호간의 의존성이 강하게 발생하지 않으니깐.
  2. Domain Layer에서 각 기능의 큰 범주에 따라 폴더를 구분한다. 예를 들면 DB에서 데이터를 가져오는 UseCase 들을 묶고, 저장하는 UseCase 들을 묶고, User 정보돠 관련된 UseCase 들을 묶는 방식으로. → 요걸 통해서 최대한 비즈니스 로직들을 재사용할 수 있기를 기대한다.
  3. 엔티티(도메인 계층에서 사용하는 데이터 모델)을 따로 모아둬서 중복 작성되지 않도록 막고, 데이터 레이어에서 편하게 모델 구조를 참고할 수 있게 만든다.
  4. Data Layer에서는 하나의 DB와 관련된 코드를 하나로 묶어 관리한다. 이전 방식에서는 각 뷰에 관련된 데이터 관련 코드들이 묶여있다보니, 중복 작성되는 경우가 너무 많았었다. 좀 더 관리하기 편하도록 각 DB에 대해 별도로 코드를 뭉쳐둘 필요성을 느꼈다.

이런 방식으로 해야지 클린 아키텍처를 적용하려던 원래 의의를 통해 의존성 분리와 높은 모듈 교체력을 달성할 수 있다는 걸 프로젝트를 2달 정도 굴려보면서 알게되었다. 이제 대망의 코드 리팩토링의 시간이다. 이슈와 커밋을 잔뜩 남기겠지만, 이번 달 초에는 요걸 한 번 시도해봐야겠다. 프로젝트를 멀리까지 생각하면 지금 적용을 하는게 당연할 것 같다. 화이팅!!

320x100
Share Link
reply
반응형
«   2024/05   »
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