강의

멘토링

커뮤니티

Inflearn Community Q&A

keunbyul274183's profile image
keunbyul274183

asked

Gemini's Development Practice - Commerce Backend Basics

개념 간 격벽 분리와 목록 조회 시 발생하는 참조 구조

Written on

·

43

1

제미니님 안녕하세요. 강의를 통해 각 개념 간의 응집성을 높이고, 불필요한 의존성을 줄여 격벽을 세우는 설계를 깊이 있게 연습하고 있습니다.

강의에서 배운 원칙을 적용하여 '리뷰'나 '찜' 같은 개념들이 '상품' 개념을 단방향으로 참조하도록 구조를 잡고 있습니다. 하지만 실제 상품 목록 조회 기능을 구현하다 보니, 설계의 일관성을 유지하기 어려운 상황을 마주하게 되어 조언을 구하고자 합니다.

  1. 개념 간 의존성의 역전: 목록 화면에서 '리뷰 수'나 '찜 수'를 함께 보여주거나, 이를 기준으로 상품을 정렬해야 하는 요구사항이 생겼습니다. 이 경우 상품 개념이 본래 몰라야 할 하위 개념(리뷰, 찜 등)의 상태를 알아야만 하는 상황이 발생합니다.

  2. API 구성의 어려움: 상세 페이지는 API를 잘게 나누어 클라이언트에서 합성함으로써 개념 간의 독립성을 지킬 수 있지만, 목록의 경우 수십 개의 상품에 대해 매번 각각의 리뷰 수 API를 호출하여 클라이언트가 매핑하는 방식은 어딘가 어색하고 성능과 구현 효율 면에서 의문이 듭니다.

결국 조회를 위해 상품이 다시 리뷰나 찜을 알게 되면, 처음 설계한 개념 간의 단방향 참조 구조가 깨지거나 서로를 참조하는 순환 참조가 발생할 것 같아 우려됩니다.

이처럼 개념 간의 격벽을 유지하려는 설계 원칙과, 여러 개념의 데이터가 한꺼번에 필요한 조회 요구사항이 충돌할 때 어떤 식으로 접근하는 것이 현명할까요? 원칙을 고수하며 우회할 방법이 있을지, 혹은 이런 조회 상황에서는 설계적 타협이 필요한 것인지 견해를 듣고 싶습니다.

kotlinspring-boot도메인dbms/rdbmsbackend

Answer 2

0

geminikims님의 프로필 이미지
geminikims
Instructor

안녕하세요 질문 감사드립니다!

[질문1]

이 부분에서는 전략적으로 방향을 정해 선택을 해야하긴합니다
저는 이 케이스라면은 로직을 조합하는 방식으로 해결할 수 있을 것 같습니다

각 개념의 로직을 가능한 단순화 시키고 지키겠다는 방향으로 결정한다면
조회 시에는 상품 목록 먼저 조회 후 리뷰 수, 찜 수를 불러와서 병합 할 것 같구요
(그에 대하여 조합하는 레이어 또는 영역에 대한 고민은 필요할 것 같습니다)

또 정렬을 진행한다면 복합 정렬이 아니라 단순 정렬이라면 리뷰 개념에서 먼저 상품 정렬에 대한 데이터를 가져온 후 상품을 가져오는 것도 방법일 것 같습니다

 

다만 이는 전체 코드 뉘앙스와 그만큼의 트레이드 오프가 가치가 있는가? 를 검토해보셨으면 좋겠습니다
쿼리와 조인으로 풀면 심플한데 그렇게까지 유지해야하는 이점이 명확해야 할 것 같습니다

제가 제안하는 격벽과 개념은 유연한 편입니다, 설계 개념/문서 같은 개념이 아니라 지금 나의 소프트웨어의 상태를 관망하고 고민하고 그대로 표현하는 형태이기 때문에 충분히 열고 닫힐 수 있습니다.

그래서 충분히 근거가 타당하다면 일관성 유지는 어느 정도 타협 할 수 있다고 생각합니다
특히 비즈니스의 흐름과 임팩트가 상품 목록에 담겨있다면 사실상 상품목록 조회는 애초에 모~든 개념을 다 알아야할 수도 있습니다

말 장난이기도하지만, 그렇다면 "상품 목록" 자체가 전역에 있는 개념과 같이 봐야할 수도 있는 것 같습니다
물론 저라면 그럼에도 적절히 합성 하는 방식을 선택할 것 같긴한데 어려운 상황도 분명히 있을 것입니다


[질문2]

음.. 우선 상품 목록의 찜 수, 리뷰 수 조회 시 별도 API를 호출하는 것은 타당하지 않은 구조라 생각하고 좋지 못한 구조라고 생각합니다

그런 의미에서 저는 Presentation Layer(Controller 클래스들)개념 영역 바깥이라고 생각합니다
(강의에서도 언급 했던 것 같은데 벌써 가물가물하네요;;)

그래서 상품 목록 API는 1개로 유지하고, 그 안에서 로직적으로 ProductService, FavoriteService, ReviewService 를 조합하는 형태로 진행하시는게 좋을 것 같다고 생각합니다

 

만~약 API를 정말 나눈다하더라도 상품별로 각각 호출하는 것이 아닌 "상품 목록 조회 API -> 리뷰수 조회 API (ProductIds 를 받아서 벌크처리)" 이렇게 되어야 할 것 같은데, 상당히 비효율적인 방식이라고 보여집니다

+ 홍보아닌 홍보지만 후속 강의인 "커머스 레거시 x AI편"에서 마침 "상품 목록 조회 시 찜 수, 주문 수"를 조회하는 요구사항이 있습니다 😃 (찜/주문 수 정렬 요구사항은 없긴합니다, 다만 위에 언급한 합성/조합에 대한 관점을 설명하오니 궁금하시다면 참고하셔도 좋을 것 같습니다!)


모쪼록 답이 되었길 바랍니다! 감사합니다!

0

안녕하세요, 인프런 AI 인턴입니다. keunbyul27님.

백엔드 개발에서 개념 간의 격벽을 유지하는 것은 설계의 응집성과 안정성을 높이는 데 매우 중요하지만, 조회 시 발생하는 데이터를 종합적으로 제공해야 하는 상황에서는 이 원칙을 지키기 어려운 경우가 자주 발생합니다.

관련 질문 URL과 원칙:

이와 관련된 무척 유사한 논의가 개념 간 격벽을 침범하는 경우에서 이루어졌습니다. 이 게시물을 통해 다른 개발자들이 직면한 유사한 상황과 그 해결 방법을 참조하실 수 있습니다.

문제 해결을 위한 접근 제안:

  1. 조회용 DTO 사용: 조회 화면에서 다수의 데이터를 한 번에 가져와야 할 경우, 조회 전용 DTO(Data Transfer Object)를 사용하는 방법이 있습니다. 이를 통해 개념 자체는 원칙을 지키면서도 클라이언트에 필요한 데이터를 제공합니다.

  2. 캐싱을 통한 성능 개선: 만약 매번 ‘리뷰 수’나 ‘찜 수’를 가져오는 것이 비효율적이라면, 캐시를 활용해 이러한 값들을 쉽게 접근할 수 있도록 개선할 수 있습니다. 캐싱은 데이터베이스와의 직접적인 상호작용을 줄여 성능을 향상시킵니다.

  3. 조회 레이어: 개념 간 격벽을 명확히 하기 위해 조회 레이어를 별도로 구성하여, 조회 로직을 이곳에서 처리하고 서비스 로직에서는 개념 간 의존성을 최소화할 수 있도록 합니다.

  4. 어그리게이터 패턴 활용: 필요한 데이터가 여러 개념에 걸쳐 있는 경우, 어그리게이터 패턴을 통해 여러 개념의 데이터를 한 번에 조회할 수 있는 객체를 구성할 수 있습니다. 이를 통해 설계의 복잡도를 낮추며 부가적인 데이터가 필요한 상황을 타겟팅할 수 있습니다.

설계적 타협:

때때로 비즈니스 요구사항이 설계 원칙보다 우선되어야 하며, 이러한 경우 조회 기능에 한해서는 설계 원칙을 완화하는 것도 고려할 수 있습니다. 이는 프로젝트의 복잡도와 성숙도에 따라 신중히 결정되어야 합니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 고민을 해결한 사례를 제시하고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서도 답변해 주실 것입니다.

keunbyul274183's profile image
keunbyul274183

asked

Ask a question