들어가며
프로젝트를 개발하면서 계층형 아키텍처를 최대한 잘 구성하기 위해 노력했습니다. 개발을 꾸준히 하면서, 계층형 아키텍처에도 문제가 있을 수 있다고 생각했습니다. 어떤 점에서 문제를 겪었는지, 그 문제를 어떻게 해결할 수 있는지에 대해 이 글을 통해 작성해보고자 합니다. 이 글은 [Clean Architecture] 계층형 아키텍처의 문제점 글과 [Clean Architecture] 계층형 아키텍처의 문제점을 해결하는 육각형 아키텍처(헥사고날 아키텍처) 글을 참고해서 작성했습니다.
데이터베이스 주도 설계
NestJS로 서비스를 개발하면서 기존 코드를 계층별로 구분하여 작성하려고 노력했습니다. 처음 코드를 작성할 때는 큰 문제를 겪지 않았지만 비즈니스의 복잡도가 커지면서 조금씩 문제를 겪기 시작했습니다.
하나의 계층이 다음 계층의 여러 클래스를 연결하고 있고 연결된 클래스는 또 다음 계층의 여러 클래스를 연결하는 구조가 만들어졌습니다. 코드를 작성할수록 난잡한 연결이 계속해서 이뤄지는 문제가 발생했습니다.
계층형 아키텍처를 구성하기 위한 노력을 하면서 코드를 살펴보니 데이터베이스를 중심으로 코드 구성이 이뤄지고 있었습니다. 서비스 계층에서 레포지토리를 직접 의존하고 있었고, 그러다 보니 레포지토리의 코드가 바뀌면 서비스 계층의 코드에도 영향이 가는 서비스와 레퍼지토리 간의 강한 결합이 발생하는 문제가 발생했습니다. 만약 관계형 데이터베이스에서 NoSQL로 변경하고자 한다면 서비스 계층에도 변경의 영향을 줄 수 있는 구조였습니다. 즉 최종적인 의존의 방향성이 데이터베이스로 향하면서 코드의 변경을 자유롭게 하지 못하는 문제를 느낄 수 있었습니다.
의존 역전 원칙
그렇다면 계층 간의 거대한 강 결합의 문제를 해결하고, 서비스에서 레포지토리 간 의존의 방향성을 반대로 바꿀 수만 있다면 어느 정도 계층형 아키텍처의 문제를 해결할 수 있지 않을까 생각했습니다. 거대한 강 결합의 문제는 DDD의 개념을 활용해서 해결하고자 했고, 의존의 방향성에 대해서는 DIP를 생각할 수 있었습니다. DDD에 대해서는 다음 글에서 설명하고, 이번 글은 DIP를 어떻게 적용했는지에 대해 살펴보고자 합니다.
DIP란 의존 역전 원칙으로 고수준 모듈은 저수준 모듈의 구현에 의존해서는 안 되며 저수준 모듈이 고수준 모듈에서 정의한 추상 타입에 의존해야 한다는 것을 의미합니다. DIP를 적용해서 서비스와 레포지토리 간의 의존성의 방향성을 역전한다면 서비스와 레포지토리 간의 강한 결합으로부터 나오는 문제를 해결할 수 있겠다고 생각했습니다.
만약 도메인 계층에 속하는 Entity에 영속성 계층의 Repository가 의존한다면 두 계층 사이에는 순환 의존성이 생깁니다. 이 문제를 해결하기 위해 도메인 계층에 Repository에 대한 인터페이스를 만들고, 실제 Repository의 구현체를 영속성 계층에 구현하게 만들면 도메인이 영속성에 의존하던 구조를 영속성이 도메인에 의존하도록 설계할 수 있습니다. 이렇게 된다면 도메인 계층에서는 순수한 비즈니스 로직에만 신경 쓸 수 있게 됩니다.
클린 아키텍처
계층형 아키텍처에서 의존의 방향성에 대해 고민하다 보니 클린 아키텍처에 대해 알 수 있었습니다. 위 그림에서 보이는 것처럼 모든 의존성은 Entities로 향합니다. 그리고 DB의 경우 원 가장 밖에 존재하는 것을 볼 수 있습니다. 가장 안 쪽에 있는 도메인 코드에서는 어떤 DB를 사용하는지, 어떤 UI 프레임워크가 사용되는지 몰라도 되기에 비즈니스 규칙에 집중할 수 있습니다.
물론 클린 아키텍처가 무조건적인 정답은 아닐 수 있습니다. 계층별로 더욱 체계적으로 분리해야 하기에 비용이 더 발생할 수 있습니다. 그럼에도 코드를 역할과 책임에 맞게 보다 잘 분리할 수 있기에 좋은 아키텍처라고 생각합니다. 클린 아키텍처를 적용할 수 있다면 최종적으로 DB에 의존하는 것이 아니라 도메인 계층에 의존하기 때문에 코드의 변경에도 보다 자유로울 수 있고 강 결합 문제도 어느 정도 해결할 수 있습니다.
마치며
앞으로도 팀의 발전을 돕는 개발자가 되기 위해 노력하려 합니다. 팀에 필요한 부분이 무엇일지 고민하면서, 팀에 도움이 된다면, 열심히 공부해서 실무에 적용할 수 있는 개발자가 되기 위해 노력하고 싶습니다. 팀의 성장에 기여할 수 있는 개발자가 되겠습니다.
참고 및 출처
'Project > 서버 개발' 카테고리의 다른 글
[Project] 프로젝트 삽질기43 (feat EC2 크레딧) (1) | 2023.01.14 |
---|---|
[Project] 프로젝트 삽질기42 (feat 테스트 중 node.js 메모리 부족) (0) | 2022.12.20 |
[Project] 프로젝트 삽질기40 (feat 해시) (0) | 2022.07.16 |
[Project] 프로젝트 삽질기39 (feat UML) (0) | 2022.07.15 |
[Project] 프로젝트 삽질기38 (feat AWS SQS 적용) (2) | 2022.07.15 |