C4 접근법
| 용어 | 영문 | 정의 |
|---|---|---|
| C4 접근법 | C4 Model | 소프트웨어 아키텍처를 시스템 컨텍스트 → 컨테이너 → 컴포넌트 → 코드의 4단계 추상화 수준으로 나눠, 바깥에서 안쪽으로 확대하며 표현하는 다이어그램 작성 방식. Simon Brown이 제안했다. |
| 시스템 컨텍스트 다이어그램 | System Context Diagram | C4 1단계. 대상 시스템을 하나의 상자로 두고, 이를 사용하는 사람과 연동하는 외부 시스템과의 관계를 표현한다. |
| 컨테이너 다이어그램 | Container Diagram | C4 2단계. 시스템을 이루는 실행·배포 단위(웹 애플리케이션, API 서버, 데이터베이스 등)와 그 사이의 통신을 표현한다. Docker 컨테이너와는 다른 개념이다. |
| 컴포넌트 다이어그램 | Component Diagram | C4 3단계. 하나의 컨테이너 내부를 책임별 구성 요소로 나누고 그 사이의 의존을 표현한다. |
| 코드 다이어그램 | Code Diagram | C4 4단계. 하나의 컴포넌트를 클래스 다이어그램 등 코드 수준으로 표현한다. 필요할 때만 작성한다. |
다이어그램 샘플
Section titled “다이어그램 샘플”온라인 쇼핑몰의 주문 기능을 예로, 같은 시스템을 1~4단계로 확대해 그린다. 다이어그램은 Mermaid 문법으로 작성한다.
1단계: 시스템 컨텍스트 다이어그램
Section titled “1단계: 시스템 컨텍스트 다이어그램”C4Context title 시스템 컨텍스트 - 온라인 쇼핑몰 Person(customer, "고객", "상품을 주문하는 사용자") System(shop, "온라인 쇼핑몰", "상품 조회와 주문을 제공한다") System_Ext(pg, "결제 대행사", "카드 결제를 처리한다") System_Ext(delivery, "택배사", "배송을 처리한다") Rel(customer, shop, "상품을 조회하고 주문한다") Rel(shop, pg, "결제를 요청한다", "HTTPS") Rel(shop, delivery, "배송을 요청한다", "HTTPS")
2단계: 컨테이너 다이어그램
Section titled “2단계: 컨테이너 다이어그램”C4Container
title 컨테이너 - 온라인 쇼핑몰
Person(customer, "고객")
System_Ext(pg, "결제 대행사")
System_Boundary(shop, "온라인 쇼핑몰") {
Container(web, "웹 애플리케이션", "React", "고객용 화면")
Container(api, "주문 API 서버", "Spring Boot", "주문 유스케이스를 처리한다")
ContainerDb(db, "주문 DB", "PostgreSQL", "주문 애그리거트를 저장한다")
}
Rel(customer, web, "사용한다", "HTTPS")
Rel(web, api, "호출한다", "JSON/HTTPS")
Rel(api, db, "읽고 쓴다", "JDBC")
Rel(api, pg, "결제를 요청한다", "HTTPS")
3단계: 컴포넌트 다이어그램
Section titled “3단계: 컴포넌트 다이어그램”주문 API 서버 내부를 계층별 구성 요소로 나눈다. 의존은 표현 → 애플리케이션 → 도메인 방향이고, 인프라스트럭처는 도메인이 정의한 리포지토리 인터페이스를 구현한다.
C4Component
title 컴포넌트 - 주문 API 서버
Container(web, "웹 애플리케이션", "React")
ContainerDb(db, "주문 DB", "PostgreSQL")
System_Ext(pg, "결제 대행사")
Container_Boundary(api, "주문 API 서버") {
Component(controller, "OrderController", "표현 계층", "주문 요청을 받는다")
Component(service, "PlaceOrderService", "애플리케이션 서비스", "주문 유스케이스를 조율한다")
Component(domain, "Order 애그리거트", "도메인 계층", "주문 불변식을 지킨다")
Component(repo, "JpaOrderRepository", "인프라스트럭처 계층", "OrderRepository를 구현한다")
Component(pgClient, "PaymentGatewayClient", "인프라스트럭처 계층", "결제 대행사 API를 호출한다")
}
Rel(web, controller, "호출한다", "JSON/HTTPS")
Rel(controller, service, "위임한다")
Rel(service, domain, "주문을 생성한다")
Rel(service, repo, "저장한다")
Rel(service, pgClient, "결제를 요청한다")
Rel(repo, db, "읽고 쓴다", "JDBC")
Rel(pgClient, pg, "호출한다", "HTTPS")
4단계: 코드 다이어그램
Section titled “4단계: 코드 다이어그램”Order 애그리거트를 클래스 다이어그램으로 표현한다. 다른 애그리거트(Customer)는 객체가 아니라 ID(CustomerId)로만 참조한다.
classDiagram
class Order {
<<Aggregate Root>>
-OrderId id
-CustomerId customerId
-List~OrderLine~ lines
-OrderStatus status
+place()
+cancel()
+totalAmount() Money
}
class OrderLine {
<<Entity>>
-ProductId productId
-int quantity
-Money price
}
class Money {
<<Value Object>>
-BigDecimal amount
-String currency
}
class OrderRepository {
<<interface>>
+findById(OrderId) Order
+save(Order)
}
Order "1" *-- "1..*" OrderLine
OrderLine --> Money
OrderRepository ..> Order