모듈화에 대한 고민, 최적의 구조를 찾아야한다!!

현재 나는 정신 건강 챗봇 서비스를 개발하고 있는데 얼굴 인식, 음성, 텍스트를 분석해 현재 감정상태를 판단하고 이 감정에 맞는 답변을 낼 수 있는 프로젝트를 진행 중이다. LLM 모델은 AI 연구소 측에서 담당하여 협업하며 진행 하는 중..

 

현재까지 프로젝트를 진행하면서 Feature 단위로 모듈화를 나눠 UserSession, Chatbot, FaceCatch, VoiceRecord 등 각 기능별로 모듈화를 해 내부 네트워크 통신이나 데이터 저장하는 로직을 해당하는 기능에 모두 통합해 구성하였다.

 

이렇게 구성했을때 기능에 따라 모든 기능이 분리되어 관리된다는 장점이 있었지만, 영상 채팅 기능을 추가하여 기능을 디벨롭하면서 명확한 한계점을 맞이할 수 있었다.. API 통신을 하는 네트워크 로직, 데이터를 저장하는 Data 로직 등 추상화 및 확장성을 갖춘 형태로 별도 Core 형태의 모듈이 없다보니 동일한 로직을 그대로 사용해 구현해야한다는 한계가 명확하게 나오게 되었던 것이다..

 

이렇게 실제로 마주하기 전까지는 나름 잘 개발이 되어간다고 생각했지만, 점차 한계점을 느끼면서 내가 필요로 하는 구조를 고민할 수 있는 계기가 되기도 했다.

 

처음부터 설계를 잘 하고 들어갔다면 더 좋았겠지만 지금이라도 몸소 이 구조의 한계를 느끼고 변경점에 대해서 고민한다는 것 자체도 나에게 좋은 경험이 되었다.

 

결국 다시 본론으로 돌아와서 기존에 구현 했던 모듈화 된 구조의 한계는 다음과 같다.

  • 각 기능 모듈에서 유사한 네트워크, 데이터 저장 로직이 중복되어 작성되었다는 점
  • 이 기능이 확장 될 수록 공통 코드가 없어 재사용이 어렵고 유지보수가 더욱 어려워 진다는 점
  • 예를 들어 Chatbot 모듈에서만 사용할 수 있는 API 로직을 FaceCatch에서도 사용해야하는데 그러지 못단다는 것
  • Domain도 각 기능별로 별도 가지게 되어있어 분리되지 않아 데이터 모델 간 공유와 확장이 어려워 의존성을 갖게 된다는 점

이러한 문제점을 가지고 있는 현재 구조에서 그럼 어떻게 변경해 나가야 할까를 생각했을 때 가장 순수한 부분 부터 유지보수 및 확장성을 갖출 수 있는 형태로 모듈화를 하는게 맞다고 판단했다.

 

먼저 공통으로 사용할 수 있는 Domain, Core Layer를 도입하여 다른 Feature들 내 동일한 로직을 사용할 수 있는 재사용성에 신경쓰려고 했다.

 

Domain에는 모든 모듈에서 사용하는 Entity를 정의하고 Core에는 별도로 Network와 Storage 모듈을 만들어 Network 로직에는 API를 연결하는 DTO, Alamofire, EndPoint 등 네트워크 연결 클라이언트를 구성하였다.

 

Storage에서는 SwiftData, Firebase 연동 로직을 추상화하여 텍스트 기반 챗봇과 영상 기반 챗봇이 각각 해당 로직을 활용해 데이터를 저장하고 캐싱하는 방식까지 구현하도록 별도로 구분하였다.

 

그 외 나머지 기능 모듈은 Feature Layer 내 각 기능별 모듈화를 통해 도메인 및 네트워크, 데이터 저장에 대한 필요 의존성만 가지도록 분리했다.

 

정리하자면

 

Domain Layer

공통으로 사용하는 ChatRoom, ChatRoom, Message, ChatCategory, UserSession, MessageSource 등 Entity 모아 관리

모든 Feature에서 해당하는 모델을 공유해 사용할 수 있도록 구성

 

Core Layer

기존 Alamofire를 활용한 API 호출 로직 전반적으로 Network 모듈에 분리

추상화를 통해 해당 로직이 필요한 곳에 중복 코드 없이 가져가 사용할 수 있도록 구현

Chatbot, FaceChat 등 각각 필요한 곳에 import 해 사용

 

기존 Feature

Core
├── Domain
├── TRNetwork
├── Storage (예정)

Feature
├── Chatbot → Domain + TRNetwork
├── FaceCatch → Domain + TRNetwork
├── VoiceRecord → Domain

별도 공유 모듈을 적용하여 각 Feature별 기능을 나눠 재구성

 

이렇게 방향성을 가져가려고 하는데 조금 더 디벨롭 되기전에 한번 더 구조관련해서 생각해보려고 한다. 여기서 느낀점이라고 한다면 모듈화를 학습할때 필요에 따라 각 모듈을 나눈다는 것은 어느정도 이해가 됐지만 공통 모듈 및 각 기능별, layer 별 관리한다는게 크게 와닿지 않았다..

 

근데 프로젝트를 진행하게 되면서 어떤 점을 고려해야하고 추후 설계까지 생각해 프로젝트를 구성 해야 하는지 어떤 점을 생각해서 구조를 개선해야할지 이런 내용에 대한 접근법에 대해서 슬슬 감이 잡히는 것 같다.

 

일단 오늘은 이정도로 작업했고 다음주에 또 추가된 내용이 있을때 남겨놔야지.. 할게 산더미다..