프로젝트를 진행하면서 패키지 구조를 변경해야하는 상황이 생겼습니다. 현재 도메인형 패키지 구조를 계층형 패키지 구조로 변경할 계획입니다. 앞으로 진행될 상황과 패키지 구조를 변경하기로 결정한 이유에 대해 공유해보려고 합니다.
저희 프로젝트는 초기에 비즈니스 도메인 별로 패키지를 나누는 방식인 도메인형 패키지 구조를 채택하였습니다. 그동안 가장 익숙하게 사용해왔었던 방식이었고, 직관적이라고 생각했습니다. 하지만 프로젝트에 여러가지 기술이 적용되고 규모가 커지면서 몇가지 문제점이 보이기 시작했습니다.
member
⎿ controller
⎿ domain
⎿ service
⎿ mapper
⎿ dto
product
⎿ controller
⎿ domain
⎿ service
⎿ mapper
⎿ dto
cart
⎿ controller
⎿ domain
⎿ service
⎿ mapper
⎿ dto
exception
⎿ DataNotFoundException.java
⎿ DuplicateDataException.java
⎿ ForbiddenException.java
helper
⎿ AuthorizationHelper.java
레이어드 아키텍처의 주요 목표 중 하나는 각 계층 사이의 결합도를 낮추는 것입니다. 하지만 위 현재 패키지 구조에서는 모든 컴포넌트들이 하나의 루트 패키지 아래 모여있기 때문에 컴포넌트의 결합도가 높아집니다. 이는 코드가 변경되었을 때 영향을 미치는 범위가 넓어지게 될 수도 있다고 생각했습니다.
프로젝트 규모가 커지면서, 개발 초기단계에서 나타나지 않는 문제점이 발생할 수 있다고 생각했습니다. 즉 프로젝트가 복잡해질수록 계층별로 코드를 분리하여 관리하는 것이 유리합니다. 위 패키지 구조는 모든 컴포넌트가 하나의 패키지 아래 위치하기 때문에 코드의 구조화와 관리가 어려워 질 수도 있습니다.
개발자의 관점에 따라 클래스를 어떤 패키지에 둘지 애매한 경우가 존재했습니다. 예외처리를 위한 Exception
패키지와, 각 계층에서 공통적으로 사용되는 help
패키지를 어디에 두어야 할지에 대한 정확한 가이드라인을 정하기 어려웠습니다.
결과적으로 레이어드 아키텍처를 관점에서 각 패키지의 역할과 관심사를 나누었습니다.
개발자들의 관점마다 Layered Architecture의 명칭이 다르지만, 대부분 아래와 같은 논리로 설명할 수 있습니다.
어떤 패키지 구조가 더 좋은 구조인지에 대한 정답은 없다고 생각합니다.
하지만 저희 프로젝트에 레이어드 아키텍처 패턴을 적용한 이유는 다음과 같습니다.
멘토님께서 "현업에서 일반적으로 사용되는 패키지구조"를 설명해주신 내용입니다.
Layered Architecture의 기본 개념에 몇가지 내용을 변경하여 프로젝트에 적용했습니다.
Controller
가 위치하는 레이어입니다.레이어드 아키텍처에서 설명하는 내용은 아니지만 스프링기반 웹 애플리케이션에서 자주 사용되는 레이어입니다.
Application Layer는 주로 비즈니스 로직을 구현하고, 서비스 계층과 컨트롤러 간의 중간 역할을 수행합니다.
high cohesion loose coupling
갖도록 설계할 수 있습니다.Infrastruecture 레이어는 Data Access 기술, IoC 컨테이너 등의 기술적인 작업을 수행하는 계층입니다. 즉 상위 계층을 지원하는 역할을 하게 됩니다.
현재 구현을 시작하진 않았지만 앞으로 아래와 같은 기술이 추가될 것으로 예상됩니다.
Persistence Layer는 데이터베이스와 직접 통신하며 CRUD 작업을 수행합니다. 또한 데이터베이스와의 연결, 트랜잭션 관리, 쿼리 실행, 데이터 매핑 등과 같은 데이터베이스와 관련된 저수준의 작업을 처리합니다.
common
⎿ helper
⎿ AuthorizationHelper.java
⎿ exception
⎿ DataNotFoundException.java
⎿ DuplicateDataException.java
⎿ ForbiddenException.java
configuration
⎿ DataBaseConfiguration.java
controller
⎿ cart
⎿ dto
⎿ CartController.java
⎿ product
⎿ dto
⎿ ProductController.java
다음 내용은 패키지 구조 변경 이후 작성한 내용입니다!
패키지 구조를 변경를 변경하면서 기존의 "도메인형 패키지 구조"와 "계층형 패키지 구조"의 트래이드 오프 관계를 고민해볼 수 있었습니다. 또한 레이어드 아키텍처를 저희 프로젝트 요구사항에 맞춰 적용해보는 과정을 통해 프로젝트에 전체적인 일관성을 얻을 수 있었습니다.
동시에 어느정도 복잡성을 느끼기도 했습니다. 레이어로 분리된 클래스 이외의 다른 관심사가 발생한다면 패키지를 분리하기 어려울 수 있을것 것 같습니다. 또한 비즈니스 논리가 복잡한 경우 문제 해결을 위해 발생하는 비용이 높을것 입니다.
패키지 구조를 변경하는 과정을 통해, 모든 문제를 해결할 수 있는 아키텍처 패턴을 존재하지 않는다는 것을 체감할 수 있었습니다. 또한 앞으로 발생하는 모든 상황에 맞춰 트래이드 오프관계를 고려한 최선의 선택을 해아할 필요성을 느꼈습니다.
감사합니다 😄