반응형
Notice
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 |
Tags
- 인공지능
- 버전관리
- 데이터과학
- 소프트웨어
- 데이터베이스
- 빅데이터
- 컴퓨터공학
- 머신러닝
- I'm Sorry
- 네트워크
- 디자인패턴
- 컴퓨터과학
- 알고리즘
- 데이터분석
- 프로그래밍
- 딥러닝
- 사이버보안
- 자료구조
- 네트워크보안
- 파이썬
- 보안
- 소프트웨어공학
- 웹개발
- Yes
- 자바스크립트
- 클라우드컴퓨팅
- 데이터구조
- 컴퓨터비전
- 프로그래밍언어
- springboot
Archives
- Today
- Total
스택큐힙리스트
Composite 패턴으로 백엔드 트리 구조 깔끔하게 다루기 본문
반응형
“댓글 트리·카테고리·조직도… 백엔드에서 계층형 데이터를 손대다 보면 재귀-SQL과 if-else 지옥에 빠지기 쉽죠.”
Composite 패턴은 이런 ‘전체-부분(Part-Whole)’ 관계를 객체 수준에서 먼저 해결해, 서비스·리포지토리·쿼리 코드의 복잡도를 크게 낮춰 줍니다.
1️⃣ Composite 패턴, 한 줄 정의
“단일 객체(Leaf)와 복합 객체(Composite)를 동일한 인터페이스로 다루게 해 트리 구조를 재귀적으로 표현한다.”
백엔드에서는 폴더-파일, 메뉴-하위메뉴, 권한-하위권한처럼 ‘자기 자신을 다시 포함’하는 도메인에 특히 유용합니다.
2️⃣ 왜 백엔드에서 중요한가?
- ORM 엔티티 계층화 – 댓글, 카테고리 같은 무한 깊이 구조를 객체-그래프로 깔끔히 매핑
- 도메인 서비스 단순화 – getTotalSize()처럼 Leaf/Composite 구분 없는 재귀 메서드로 로직 축소
- 리팩터링-친화적 – 새 Leaf 타입(예: VideoFile) 추가 시 트리 구조 전체 수정 없이 인터페이스만 구현
이 덕분에 하위 모듈 교체나 마이크로서비스 분리 시 영향 범위를 최소화할 수 있습니다.
3️⃣ Spring Boot + JPA 구현 예시
// ① 공통 타입 – Component
public interface Node {
String getName();
long getSize(); // Leaf·Composite 모두 지원
}
// ② Leaf – 실제 파일
@Entity
public class FileNode implements Node {
@Id @GeneratedValue private Long id;
private String name;
private long size;
// getters…
}
// ③ Composite – 디렉터리
@Entity
public class DirectoryNode implements Node {
@Id @GeneratedValue private Long id;
private String name;
@OneToMany(cascade = CascadeType.ALL)
@JoinColumn(name = "parent_id")
private List<Node> children = new ArrayList<>();
@Override
public long getSize() { // 재귀 호출!
return children.stream()
.mapToLong(Node::getSize)
.sum();
}
}
Node 인터페이스만 바라보면 Leaf(파일)와 Composite(폴더)를 구분할 필요가 없습니다. 서비스·컨트롤러는 DirectoryNode.getSize()를 호출하기만 하면 전체 용량을 얻습니다.
4️⃣ 계층 데이터베이스 모델링 팁
JPA로 단순 @ManyToOne 관계(Adjacency List)를 쓰면 깊은 트리 탐색 시 N+1 문제가 생깁니다.
대안으로 Closure Table을 도입하면 전 경로를 별도 테이블에 저장해, “특정 노드의 모든 후손” 쿼리를 한 번에 해결할 수 있습니다.
5️⃣ 실전 적용 체크리스트
- 상속 대신 인터페이스 – JPA 상속 전략보다 컴포지트 계층을 @OneToMany로 표현하면 유연성이 높습니다.
- 재귀 로직은 서비스 안으로 – Repository는 쿼리만, 합산·삭제 같은 재귀는 도메인 서비스에서 캡슐화합니다.
- 트랜잭션 주의 – 깊은 트리 일괄 삭제 시 @Transactional과 배치 삭제 쿼리를 조합해 락을 최소화하세요.
- 캐시 전략 – 전체 트리 빈도 높은 읽기는 Redis Hash + 비동기 TTL 업데이트로 오버헤드를 줄입니다.
한 줄 요약
Composite 패턴은 “도메인 객체 트리를 코드 레벨에서 먼저 해결해, 복잡한 계층형 데이터를 한 방에 길들인다.”
반응형
'개발' 카테고리의 다른 글
Facade 패턴: 복잡한 서비스, 한 줄 인터페이스로 끝! (0) | 2025.07.18 |
---|---|
데코레이터 패턴: 핵심 기능에 ‘슈퍼파워’를 덧입히는 법 (0) | 2025.07.18 |
Bridge 패턴: 기능·구현을 갈라놓는 비밀 통로 (0) | 2025.07.17 |
Adapter 패턴으로 레거시 API 호환하기 (1) | 2025.07.17 |
레거시 API도 걱정 끝! 리액트·스프링에서 Adapter·Facade 패턴으로 우아하게 래핑하기 (0) | 2025.07.17 |
Comments