지금까지 여러 사이드 프로젝트를 진행하면서, 나도 모르게 관습적으로 Controller, Service, Domain, Repository 구조를 따르는 코드 설계를 해왔다.
익숙하고 보편적인 구조였기 때문에 큰 고민 없이 적용했지만, 프로젝트가 커지고 시간이 지난 뒤 코드를 다시 살펴보면 문제의 원인을 정확히 파악하거나 수정해야 할 위치를 찾는 데 어려움을 겪는 경우가 많았다.
특히, 로직이 Service에 집중되면서 책임이 모호해지고, 어떤 코드가 외부 시스템에 영향을 주는지, 어떤 코드가 순수 도메인 로직인지를 구분하기가 점점 더 어려워졌다. 그럴때마다 디버깅과 유지보수에 많은 시간을 낭비하게 되었고, 구조적인 개선의 필요성을 절실히 느끼게 되었다....
그래서 나는 핀토스 프로젝트를 기반으로, 왜 기존 구조에 한계를 느꼈고, 어떤 고민을 통해 구조를 재정의하게 되었으며, 나만의 아키텍처에 대해서 정리해보려고한다.

위 사진은 나만의 레이어 구조를 그린 것이다.
위 레이어를 분류하기 전에 어떠한 기능을 처리할 때 어떤 단계들이 필요한지 고민해보았다.
그 결과 아래와 같은 단계들이 도출되었다.
그리고 각 단계들을 하나의 책임을 가지고 있다고 생각하여 레이어로 분류해보았다.
Presentation : API 요청 / 응답 처리UseCase : 흐름 제어 및 트랜잭션 처리Business : 비즈니스 로직 및 외부 시스템의 추상화Domain : 도메인 로직 처리Infra : 외부 시스템 (ex. DB, 서드파티API 등)나만의 아키텍처를 설계할 때 중요하게 생각한 요소는 애플리케이션 계층의 책임 분리이다.
그 이유는, 과거의 작성한 코드를 확인했을 때 어떤 비즈니스 흐름을 가지는 지 파악이 어려워 디버깅하는데 더 많은 시간을 투자했기 때문이다...
그리고 유지보수를 해야하거나 새로운 기능을 추가할 때 너무 괴롭다고 느꼈다..
(내가 작성한 코드인데도 볼 때 마다 디버깅을 하는 괴로움....)
그래서 본래의 애플리케이션 계층 책임에 대해 다시 생각해보기로 했다.
하지만 애플리케이션 계층의 코드를 봤을 때 비즈니스 로직(퍼시스턴스 로직, 예외처리, 도메인 로직 등)을 모두 구현하고 있어 흐름파악이 불가한 상태였다...
그래서 이러한 문제를 해결하고자 애플리케이션 계층의 책임을 제한하고 분리해야겠다고 생각했다...
그리고 비즈니스 로직 구현에 대한 책임은 Business Layer라는 계층을 별도로 만들어 책임을 부여해기로했다.
이렇게 함으로써 애플리케이션 계층은 비즈니스 로직에 대한 책임을 Business Layer에게 위임함으로써 흐름만을 조율할 수 있고, 해당 기능에 대해서 어떤 흐름을 가지는지 애플리케이션 계층의 코드만으로 쉽게 파악할 수 있게 되었다.
규모가 작거나 비즈니스 규칙이 간단한 프로젝트의 경우는 Business Layer가 필요 없을 수도 있다고 생각한다.
왜냐하면 동일한 도메인이더라도 비즈니스 흐름과 규칙은 모두 다를 수 있고, 불필요한 계층은 오히려 유지보수 측면에서 부정적이라고 생각하기 때문이다.
하지만, 애플리케이션 계층에서 비즈니스 로직이 포함되어야하는 경우에 Business Layer 계층 도입을 통해서 비즈니스 흐름을 조율하는 애플리케이션 계층이 여러 책임을 가지도록 하는 것을 방지할 수 있다고 생각한다.
아키텍처 설계 두번째 이유는 도메인 계층과 애플리케이션 계층의 명확한 격리이다.
도메인 계층과 애플리케이션 계층은 외부로부터 어떠한 의존을 갖지 않도록 해야한다.
그 이유는 외부의 변화가 우리 애플리케이션 내부에 영향을 끼쳐서는 안되기 때문이다.
도메인 계층의 경우는 비즈니스의 핵심 규칙을 담당하는 핵심 영역으로 외부의 변화로 도메인의 영향을 받으면은 안되기 때문이다.
애플리케이션 계층의 경우도 도메인 계층을 이용하여 비즈니스 흐름 조율을 담당하여 우리가 제공하는 서비스의 핵심 영역으로 생각했다.
이처럼 도메인 계층과 애플리케이션 계층은 우리 애플리케이션에서 핵심적인 영역으로 외부에 의존해서 외부로부터 영향을 받아서는 안된다고 생각했다.
그렇기 때문에 사진과 같이 Core 영역이 외부(표현, 인프라)영역에 의존하는게 아니라 외부 영역이 Core 영역을 의존하도록 의존성의 방향을 바꿨다.
아키텍처는 구체적인 구현 방법이 아니라 어떠한 방향성에 대해서 정의하는 것이기 때문에 소프트웨어를 어떤 방향으로 바라보는지를 정의하는 것이라고 생각한다.
내가 직접 느꼈던 불편했던 점에 대해 정리하고 개선해봄으로써 코드를 바라보는 시야를 넗힐 수 있는 시간이었다고 생각한다.
나만의 아키텍처를 정의하면서 느낀 점은 클린 아키텍처..?같다라는 생각을 했다.
하지만 클린 아키텍처이더라도 저만의 언어와 용어로 각 계층의 역할과 책임을 다시 정의해봄으로써 상황에 따라 유연하게 시스템 구성요소 간 의존성이 바뀐다는 것을 알 수 있는 시간이었다.
내가 생각한 아키텍처에 대한 의견과 다른 사람이 봤을 때 어떤 부분이 부족하고 어떤 부분이 좋은지 피드백이 궁금해졌다.. !!
기회가 되어 팀 프로젝트에 참여하게 된다면 직접 설계한 아키텍처를 팀원들에게 제안해보고, 반응이 긍정적이라면 함께 적용해보는 과정을 해보고 싶다는 생각을 했다..
언제든 질문사항이나 피드백 감사합니다 !!
댓글로라도 남겨주시면 너무 감사하겠습니다 :)