Skip to content

Commit fa29e0c

Browse files
committed
Add detailed documentation on DDD and coding concepts
Introduced comprehensive markdown files covering key topics like Domain-Driven Design (DDD), coding best practices, and technical explanations (e.g., dependency management, JPA, Docker). These documents aim to assist developers in understanding and applying core concepts effectively.
1 parent 783a7ab commit fa29e0c

File tree

2 files changed

+275
-0
lines changed

2 files changed

+275
-0
lines changed
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
## 1. 도메인(Domain)
2+
**도메인(Domain)** 은 소프트웨어가 해결하고자 하는 **문제 영역**을 의미합니다. 예컨대 쇼핑몰, 은행 시스템, 병원 예약 시스템 등 구체적인 업무나 사업 영역이 도메인이 됩니다. DDD에서는 이 도메인을 깊이 이해하고, 소프트웨어에 적합한 형태로 모델링하여 **비즈니스 로직**을 올바르게 구현하는 것을 최우선으로 삼습니다.
3+
4+
---
5+
6+
## 2. Ubiquitous Language(보편 언어)
7+
**Ubiquitous Language(보편 언어)****도메인 전문가(현업 담당자)****개발자** 사이의 소통에 사용되는 **공통 언어**를 말합니다.
8+
- 예를 들어, “장바구니에 상품을 담는다”라는 도메인 용어를 코드 클래스나 메서드 이름에도 그대로 반영하여, 팀 전체가 **같은 개념과 용어로 의사소통**할 수 있도록 돕습니다.
9+
- 이를 통해 서로 다른 직군 사이에서 용어 정의가 불분명해져 생길 수 있는 **지식 누락**이나 **오해**를 줄일 수 있습니다.
10+
11+
---
12+
13+
## 3. Bounded Context(경계 컨텍스트)
14+
도메인이 커지면, 한꺼번에 모든 것을 처리하기 어렵습니다. 그래서 **의미가 구분되는 맥락**별로 나누어 관리하는데, 이를 **Bounded Context(경계 컨텍스트)** 라고 부릅니다.
15+
- 예를 들어, 대형 쇼핑몰 시스템이라면 “상품 관리”, “주문”, “결제” 등으로 나눌 수 있습니다.
16+
- 각 컨텍스트가 **독립적으로** 자체 모델을 유지하되, 필요한 경우에만 다른 컨텍스트와 **명확한 연동 규칙**을 정의합니다.
17+
- 이를 통해 **불필요한 결합**을 피하고, 각 컨텍스트가 독립적으로 발전∙배포될 수 있도록 유연성을 확보합니다.
18+
19+
---
20+
21+
## 4. Entity, Value Object, Aggregate 등 핵심 개념
22+
23+
### 4.1. Entity(엔티티)
24+
- **고유 식별자(ID)** 를 가지며, 해당 식별자를 통해 엔티티의 **생애 주기 전체를 추적**합니다.
25+
- 예: “주문(Order)” 엔티티는 주문 ID로 식별되며, 주문 상태가 바뀌어도 ID가 유지됩니다.
26+
27+
### 4.2. Value Object(값 객체)
28+
- 별도의 식별자가 없고, **값 자체**가 중요한 객체입니다.
29+
- **불변성**을 강조하며, 값이 변경되면 새로운 Value Object로 대체하는 방식을 권장합니다.
30+
- 예: “주소(Address)” 객체는 식별자보다 그 안의 지역, 도로명, 우편번호 등 **** 자체가 중요합니다.
31+
32+
### 4.3. Aggregate(애그리거트)
33+
- 서로 밀접하게 연관된 **엔티티와 값 객체의 집합**입니다.
34+
- 해당 애그리거트의 **루트 엔티티(Aggregate Root)** 를 통해서만 외부에서 접근∙조작할 수 있도록 하여 일관성을 보장합니다.
35+
- 예: “주문(Order)”과 “주문 항목(OrderLine)”들이 하나의 애그리거트를 이룹니다.
36+
37+
### 4.4. Domain Service(도메인 서비스)
38+
- 특정 엔티티에 속하기 애매하지만, 여전히 **도메인 규칙** 에 해당하는 로직을 모아 둡니다.
39+
- 예: 둘 이상의 애그리거트를 동시에 처리해야 할 경우, 별도의 Domain Service로 추상화하여 책임을 분리할 수 있습니다.
40+
41+
### 4.5. Repository(리포지토리)
42+
- 엔티티나 애그리거트의 **저장∙조회∙삭제**를 책임지는 컴포넌트입니다.
43+
- DDD에서는 Repository를 통해 도메인 객체를 조작하고, 내부적으로는 JPA나 MyBatis 등 구체적인 DB 기술을 사용합니다.
44+
45+
---
46+
47+
## 5. Context Mapping(맥락 맵핑)
48+
**Bounded Context**가 여러 개 존재할 때, 각 컨텍스트 간 **협력 관계****통신 방식**을 정의하는 것을 **Context Mapping**이라고 합니다.
49+
- 예: “주문 컨텍스트”와 “결제 컨텍스트”가 서로 상호작용할 때, 데이터를 어떻게 넘겨주고 어떤 이벤트를 발생시킬지 정의합니다.
50+
- 필요에 따라 **Anti-Corruption Layer**를 두어 외부 시스템∙컨텍스트와의 데이터 변환∙보호를 수행하거나, **Shared Kernel**로 공통 모델을 공유하는 식으로 모델 통합 방식을 결정합니다.
51+
52+
---
53+
54+
## 6. 도메인 이벤트(Domain Event), Event Storming 등
55+
### 6.1. 도메인 이벤트(Domain Event)
56+
- “주문이 생성되었다(OrderCreated)”, “결제가 완료되었다(PaymentCompleted)”처럼, **도메인 로직상 중요한 사건**을 이벤트 객체로 표현합니다.
57+
- 이를 발행∙구독(pub/sub) 구조로 설계하면, 컨텍스트 간 **결합도를 낮추고**, **확장성**을 높일 수 있습니다.
58+
59+
### 6.2. Event Storming
60+
- 도메인 전문가와 개발자가 함께 **시간 축(Time Line)** 순으로 도메인 이벤트를 시각화하여 분석∙설계하는 방법론입니다.
61+
- 포스트잇 등을 활용한 시각화를 통해 **업무 흐름**, **핵심 시나리오**, **잠재적 문제** 등을 빠르게 파악할 수 있습니다.
62+
63+
---
64+
65+
## 7. Subdomain(하위 도메인)
66+
- **Core Subdomain(핵심 하위 도메인)**: 프로젝트에서 가장 중요하고 경쟁력을 만드는 부분입니다. 에너지를 집중 투자해야 합니다.
67+
- **Supporting Subdomain(지원 하위 도메인)**: 핵심을 보조하는 로직이나 기능입니다.
68+
- **Generic Subdomain(범용 하위 도메인)**: 보편적인 기능 예: 결제 모듈, 이메일 전송 등. 필요하다면 제3자 솔루션을 활용하기도 합니다.
69+
70+
DDD는 **핵심 도메인**에 더 많은 시간을 투자해 비즈니스 가치를 최대화하고, 나머지 부분은 효율적으로 구성해 전체 생산성을 높이는 전략을 지향합니다.
71+
72+
---
73+
74+
## 8. DDD가 추구하는 목표 및 장점
75+
76+
1. **복잡한 비즈니스 요구사항에 대한 체계적 접근**
77+
- 핵심적인 문제를 해결하기 위해 도메인을 구조적으로 이해하고, 변화 요구에 대응하기 쉽도록 만듭니다.
78+
79+
2. **팀 간 원활한 소통**
80+
- Ubiquitous Language를 통해 도메인 전문가와 개발자 간 **용어와 개념**이 일치하도록 돕습니다.
81+
82+
3. **올바른 추상화와 캡슐화**
83+
- Aggregate 등을 사용하여 핵심 로직을 감싸고, 불필요한 외부 접근을 제한함으로써 **유지보수**가 쉬워집니다.
84+
85+
4. **확장성과 유연성**
86+
- Bounded Context를 적절히 분리하고, Context Mapping을 통해 **컨텍스트 간 결합도**를 줄여 나갑니다.
87+
88+
---
89+
90+
### 결론
91+
도메인 주도 설계(DDD)는, **도메인 모델**이 개발 과정 전체에서 최우선이 되도록 하여 복잡한 비즈니스 로직을 **정확**하고 **유지보수 가능**하게 만드는 방법론입니다.
92+
도메인 전문가와 개발자가 **공통 언어**로 끊임없이 소통하면서, **도메인 핵심 가치를 소프트웨어에 반영**하려는 노력이 DDD의 근본이라 할 수 있습니다.

question/1~3-week-test.md

Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
**1. 의존성 관리가 필요한 이유**
2+
3+
- 라이브러리나 프레임워크가 업데이트되거나 변경될 때, 서로 호환이 보장되도록 버전을 맞추고 충돌을 방지하기 위함
4+
- 코드가 점점 복잡해짐에 따라, 프로젝트의 안정성과 유지보수를 쉽게 하기 위해 필요
5+
- e.g. 도메인 모듈(계층)을 나누면, 한 곳의 수정이 다른 곳에 미치는 영향이 최소화된다.
6+
예를 들어, 도메인 로직을 변경해도 애플리케이션·인프라 레이어는 건드릴 필요가 적다.
7+
각 레이어의 책임이 분명해 유지보수 범위와 충돌이 줄어든다.
8+
9+
---
10+
11+
**2. 계층(레이어)을 구분해서 설계하는 이유**
12+
13+
- 책임 분리를 통해 각 레이어가 맡는 역할을 명확히 하고, 코드 가독성과 유지보수를 향상
14+
- 각 레이어가 독립적으로 변경될 수 있어, 시스템 확장성과 유연성을 높임
15+
16+
---
17+
18+
**3. Controller, Service, Repository 각 레이어는 어떤 책임을 가지며 어떻게 협력하나요?**
19+
20+
- **Controller**: 클라이언트 요청을 받고, 적절한 Service를 호출하여 결과를 반환
21+
- **Service**: 비즈니스 로직을 처리하며, 필요한 경우 Repository를 통해 데이터 접근 수행
22+
- **Repository**: 데이터베이스와 직접 소통하여 데이터를 조회·저장·수정·삭제
23+
24+
---
25+
26+
**4. DDD(Domain-Driven Design)의 목표**
27+
28+
- 소프트웨어의 핵심 복잡도(도메인 로직)를 명확하게 표현하고 해결하기 위함
29+
- 도메인 모델을 중심으로 팀 간의 공통 언어(Ubiquitous Language)를 형성하여 요구사항과 구현이 일치하게 개발
30+
31+
---
32+
33+
**5. OOP(Object-Oriented Programming)가 필요한 이유**
34+
35+
- 객체를 중심으로 책임과 역할을 나누어 설계하면, 코드 재사용성과 유지보수가 좋아짐
36+
- 캡슐화, 상속, 다형성 등을 통해 복잡도를 낮추고 유연성을 높임
37+
- e.g. 회원 정보를 다루는 “User” 객체가 “Name”과 “Address” 같은 값 객체를 각각 캡슐화하여 사용한다고 해보겠습니다.
38+
“Name” 객체가 “firstName”, “lastName”을 유효성 검증(빈 문자열 여부, 특수문자 포함 등)하고, “Address” 객체가 “City”, “Street”, “PostalCode”를 검증하도록 분리하면, 이름 형식 변경이나 주소 포맷 변경 등 세부 규칙이 생겨도 관련 객체만 수정하면 됩니다.
39+
이런 식으로 객체마다 자체적인 검증과 책임을 분명히 두면, 실무에서 규칙이 자주 추가·수정되는 상황에서도 코드를 대폭 갈아엎지 않고도 유연하게 대응할 수 있게 됩니다.
40+
41+
---
42+
43+
**6. .gitignore를 사용하는 목적**
44+
45+
- 버전 관리가 불필요하거나 보안상 노출되면 안 되는 파일(빌드 결과물, 환경 설정 파일 등)을 Git에서 제외하여 관리
46+
- 저장소 용량 낭비와 불필요한 충돌을 방지
47+
48+
---
49+
50+
**7. Docker가 로컬 개발 환경에서 주로 어떻게 쓰이나요?**
51+
52+
- 특정 버전의 DB나 외부 서비스 환경을 빠르게 구성하여, 개발자가 동일한 환경에서 작업할 수 있도록 지원
53+
- 여러 프로젝트에서 환경 충돌 없이 독립적인 컨테이너를 구동할 수 있음
54+
55+
---
56+
57+
**8. Docker의 Image와 Container의 개념과 차이에 대해 설명해주세요.**
58+
59+
- **Image**: 실행 가능한 환경(파일시스템, 런타임, 설정 등)을 캡슐화한 템플릿
60+
- **Container**: Image를 실제로 실행한 상태로, 독립된 프로세스로 동작
61+
62+
---
63+
64+
**9. docker-compose.yml 파일을 작성할 때 유의해야 할 점은 무엇인가요?**
65+
66+
- 서로 연결될 서비스(컨테이너)의 포트, 볼륨, 네트워크 설정을 명확히 정의
67+
- 환경 변수나 데이터 볼륨, 버전 정보를 정확히 기재하여 재현 가능하도록 함
68+
- 여러 컨테이너 간 의존성을 고려하여 실행 순서를 지정하거나, 재시작 정책을 설정
69+
70+
---
71+
72+
**10. JPA가 하는 역할은 무엇인가요?**
73+
74+
- 자바 객체와 데이터베이스 테이블 간의 매핑을 자동으로 처리하여, SQL을 직접 다루지 않고도 데이터를 조작할 수 있게 함
75+
- 데이터 액세스 계층을 단순화하고, 생산성과 유지보수를 높임
76+
77+
---
78+
79+
**11. JPA에서 Entity 클래스에 주로 사용되는 어노테이션과 그 역할을 설명해주세요.**
80+
81+
- `@Entity`: 해당 클래스를 JPA가 관리하는 엔티티로 지정
82+
- `@Table`: 엔티티와 매핑될 테이블 이름 설정
83+
- `@Id`: 엔티티의 PK(기본 키) 필드 지정
84+
- `@GeneratedValue`: PK의 자동 생성 전략 지정
85+
- `@Column`: 테이블의 컬럼 속성(name, nullable, length 등) 지정
86+
- `@OneToMany`, `@ManyToOne`, `@OneToOne`, `@ManyToMany`: 엔티티 간의 연관관계를 설정
87+
88+
---
89+
90+
**12. JPA에서 Converter, Embeddable, Auditing 등을 사용하는 이점은 무엇인가요?**
91+
92+
- **Converter**: 특정 타입을 변환(예: enum ↔ String)하여 DB와 애플리케이션 간에 일관성을 유지
93+
- **Embeddable**: 재사용 가능한 값 객체를 쉽게 활용해 도메인 모델을 풍부하게 표현
94+
- **Auditing**: 생성·수정 시점이나 작성자 등을 자동으로 관리해, 공통 요구사항을 중복 없이 처리
95+
96+
---
97+
98+
**13. 양방향 매핑(ManyToOne, OneToMany) 시 주의해야 할 점은 무엇인가요?**
99+
100+
- 무한 루프(순환 참조) 방지: 예를 들어, 양쪽에서 같은 엔티티를 직렬화할 때
101+
- 연관관계 주인 설정: 어느 쪽이 외래 키를 관리하는 주인인지 명확히 해줘야 함
102+
- 필요 없는 양방향보다는 단방향을 우선 고려하여 복잡도를 낮춤
103+
104+
---
105+
106+
**14. JPA에서 N+1 문제가 무엇인지 예를 간략하게 적고 해결방법을 설명하세요.**
107+
108+
- **N+1 문제**: 연관 관계가 있는 엔티티를 조회할 때, 추가로 N번의 쿼리가 발생하여 성능 저하를 일으키는 문제
109+
- **예시**: Member와 Team 엔티티가 다대일(ManyToOne) 관계일 때, 모든 Member를 조회하고 각 Member의 Team을 LAZY 로딩할 때 발생
110+
```java
111+
public void demonstrateNPlusOneProblem() {
112+
// 첫 번째 쿼리: 모든 Member를 조회
113+
// 예) SELECT m FROM Member m
114+
List<Member> members = memberRepository.findAll(); // 1개의 쿼리
115+
116+
for (Member m : members) {
117+
// 각 Member마다 Team 정보를 LAZY 로딩하면서 실행되는 쿼리
118+
// 예) SELECT t FROM Team t WHERE t.id = ?
119+
System.out.println(m.getTeam().getName()); // N개의 쿼리
120+
}
121+
}
122+
```
123+
124+
- **해결 방법**
125+
- 페치 조인(Fetch Join)을 사용하여 한 번의 쿼리로 모든 연관 엔티티를 함께 조회
126+
- JPA의 `EntityGraph`를 사용하여 페치 조인을 명시적으로 설정
127+
- @BatchSize를 사용하여 일괄 처리로 성능을 향상
128+
129+
**15. 단위 테스트(Unit Test)는 무엇이며, 왜 필요한가요?**
130+
131+
- **정의**: 시스템의 가장 작은 단위(주로 메서드나 클래스)의 동작을 검증하는 테스트
132+
- **필요성**: 빠른 피드백으로 에러를 조기에 발견하고, 리팩토링이나 기능 추가 시 안정성을 제공
133+
134+
---
135+
136+
**16. 통합 테스트(Integration Test)는 무엇이며, 왜 필요한가요?**
137+
138+
- **정의**: 여러 컴포넌트나 모듈이 실제로 연결된 상태에서 전체 흐름이 정상 동작하는지 검증하는 테스트
139+
- **필요성**: 모듈 간 연동 문제, 의존성 문제 등을 조기에 발견해 실제 배포 후 장애를 줄임
140+
141+
---
142+
143+
**17. Mock은 무엇이며, 어떤 상황에서 왜 사용하는가요?**
144+
145+
- **정의**: 실제 객체 대신에 비슷한 동작만 흉내내는 ‘가짜 객체’
146+
- **사용 상황**: 외부 의존성이 있는 코드를 테스트할 때, 네트워크나 DB 같은 복잡한 환경을 대체하여 테스트를 빠르고 독립적으로 진행하기 위해 사용
147+
148+
---
149+
150+
**18. RESTful한 API를 설계할 때 핵심적으로 고려해야 할 점들은 무엇인가요?**
151+
152+
- 리소스(명사형) 중심의 URL과 HTTP 메서드(POST, GET, PUT, DELETE)로 명확한 액션 표현
153+
- 적절한 상태 코드(2xx, 4xx, 5xx)와 에러 메시지 설계
154+
- 요청과 응답에 일관성 있고 명확한 JSON(or XML) 구조 사용
155+
- 보안, 버전 관리, 문서화 등도 함께 고려
156+
- 리소스 간의 관계를 표현하고, 가능하다면 HATEOAS(Hypermedia as the Engine of Application State)를 활용해 API의 자기 기술적인 특성을 활용
157+
158+
---
159+
160+
**19. DTO를 사용하는 이유는 무엇인가요?**
161+
162+
- 도메인(Entity) 객체와 API 요청·응답 모델을 분리해, 불필요하거나 민감한 정보 노출을 막을 수 있음
163+
- 계층 간 데이터 이동 시 변환 로직을 추가하거나, 표시 형식을 자유롭게 조절 가능
164+
165+
---
166+
167+
**20. Spring Boot에서 전역 예외 처리를 위해 사용할 수 있는 방법은 무엇인가요?**
168+
169+
- `@ControllerAdvice``@ExceptionHandler`를 사용해 전역적으로 예외를 핸들링
170+
- `ResponseEntityExceptionHandler`를 상속받아 공통 에러 처리를 구성
171+
- 필터나 인터셉터 등을 활용해 더 넓은 범위에서 에러 처리를 할 수도 있음
172+
173+
---
174+
175+
**21. API 서버로 들어오는 다양한 데이터의 포맷(타입)을 핸들링하기 위해 어떤 방법들을 사용할 수 있나요?**
176+
177+
- RequestParam 혹은 PathVariable의 경우
178+
- **Spring**에서 `HttpMessageConverter`를 설정하거나 커스텀 Converter를 구현
179+
- RequestBody의 경우
180+
- **Jackson**이나 **Gson** 같은 라이브러리를 활용해 JSON/XML 등 다양한 포맷을 직렬화/역직렬화
181+
- 커스텀 Serializer/Deserializer를 작성해 특정 데이터 타입에 대해 맞춤형 처리를 적용
182+
183+
---

0 commit comments

Comments
 (0)