상태와 구조를 그리는 법: State·ER·Class 다이어그램
이 글은 "다이어그램으로 생각하기" 시리즈의 세 번째 글입니다. 2편에서 흐름을 그리는 Flowchart와 Sequence를 다뤘다면, 이번에는 흐름이 아니라 상태를 가진 대상과 데이터·코드의 구조를 그리는 세 종류를 정리하려 합니다.
흐름은 "무엇이 어떤 순서로 일어나는가"를 보여줍니다. 그런데 막상 그려보면, 어떤 대상은 순서보다 "지금 어떤 상태에 있는가"가 더 본질적이라는 생각이 들 때가 있습니다. 또 어떤 것은 시간의 흐름이 아니라 가만히 멈춰 있는 구조 자체를 봐야 이해가 됩니다. State·ER·Class는 그런 정적인 면을 그리는 도구입니다.
State 다이어그램 — 상태와 생명주기
State 다이어그램은 한 대상이 가질 수 있는 상태와 그 사이의 전이를 그립니다. 시작은 [*]로, 종료도 [*]로 표시합니다. 화살표는 "이 상태에서 저 상태로 넘어가는 사건"을 뜻합니다.
돌이켜 보면 이 다이어그램의 진가는 직접 그려보기 전엔 잘 와닿지 않았습니다. 블로그 글 한 편의 생명주기를 State로 그려본 적이 있는데, Flowchart로 그렸다면 "글을 쓰고 발행한다"는 절차로 보였을 일이, 상태 다이어그램에서는 상태 중심으로 보였습니다. slug는 발행한 뒤에는 바꾸지 않는다는 것, 편집은 게시된 글을 직접 건드리는 게 아니라 별도의 임시저장(편집중) 상태로 분기시킨다는 것, 삭제는 영구 삭제가 아니라 soft delete라는 것이 한 화면에 드러났습니다.
무엇보다 좋았던 건, "이 전이는 빠졌네"를 찾는 데 특히 유용했다는 점입니다. 가능한 상태를 다 늘어놓고 화살표를 잇다 보면, 연결되지 않은 상태나 빠진 전이가 자연스럽게 눈에 띕니다. 흐름도였다면 그냥 한 줄로 지나갔을 누락이, 상태의 지도 위에서는 빈 칸으로 남습니다.
stateDiagram-v2
[*] --> 임시저장
임시저장 --> 예약: 예약 발행
임시저장 --> 게시됨: 즉시 발행
예약 --> 게시됨: 예약 시각 도달
게시됨 --> 편집중: 편집 시작
편집중 --> 게시됨: 수정 반영
게시됨 --> 숨김: 숨기기
숨김 --> 게시됨: 공개
게시됨 --> 삭제됨: soft deleteER 다이어그램 — 데이터 모델
ER(Entity-Relationship) 다이어그램은 엔티티(테이블이나 컬렉션)와 그 사이의 관계, 그리고 각 엔티티의 속성을 그립니다. 관계의 카디널리티는 crow's-foot(까마귀발) 표기로 나타냅니다. 한쪽 끝의 모양이 1인지, 0 이상인지, 1 이상인지를 표현해서 1:N이나 N:M 같은 관계를 한눈에 읽게 해 줍니다.
주로 DB 스키마를 이해하거나 다른 사람과 공유할 때 그립니다. 글로 "USER는 여러 POST를 가지고, POST는 여러 REVISION을 가진다"고 적는 것보다, 선과 기호로 보는 편이 훨씬 빠르게 와닿습니다.
다만 솔직히 말하면 함정도 있었습니다. 자기참조(self-relation) 관계 — 예를 들어 POST가 다른 POST를 관련 글로 가리키는 경우 — 는 Mermaid에서 긴 곡선으로 그려져 공간을 제법 먹습니다. 한 엔티티에서 출발해 자기 자신으로 돌아오는 선이라, 다른 관계들 위로 크게 휘어 지나가며 도형을 어수선하게 만들곤 합니다. 작은 모델에서는 괜찮지만, 엔티티가 많아질수록 이 자기참조 선들이 가독성을 떨어뜨린다는 점은 알고 그리는 게 좋겠다는 생각이 들었습니다.
erDiagram
USER ||--o{ POST : "작성"
POST ||--o{ REVISION : "스냅샷"
POST ||--o{ POST : "관련글(자기참조)"
POST {
string slug
bool isPublished
}Class 다이어그램 — 코드 구조
Class 다이어그램은 UML의 일부로, 클래스나 인터페이스의 속성과 메서드, 그리고 그들 사이의 관계(상속·구현·연관)를 그립니다. <|-- 같은 화살표로 "Dog는 Animal을 상속한다" 같은 계층을 표현합니다. 객체지향 설계를 공유하거나 타입 계층을 정리할 때 쓰입니다.
다만 여기에는 분명한 트레이드오프가 있습니다. Class 다이어그램은 코드와 동기화가 되지 않으면 금세 낡아버립니다. 코드는 매일 바뀌는데 다이어그램은 한 번 그려두고 잊기 쉬워서, 어느 순간 실제 코드와 다른 그림을 보며 헷갈리게 됩니다. 그래서 저는 모든 클래스를 빠짐없이 그리기보다는, 큰 그림과 핵심 관계만 그리는 편이 낫다는 생각을 하게 되었습니다. 세세한 메서드 시그니처는 코드를 보면 되니까, 다이어그램은 "이것과 저것이 어떤 관계인가"라는 구조의 뼈대를 보여주는 데 집중하는 것입니다.
classDiagram
class Animal {
+name: string
+speak()
}
Animal <|-- Dog
Animal <|-- Cat세 다이어그램은 무엇이 다른가
같은 정적 구조를 그린다고 묶었지만, 세 다이어그램이 그리는 대상과 답하는 질문은 서로 다릅니다. 정리해 보면 이렇습니다.
다이어그램 | 그리는 대상 | 답하는 질문 | 언제 쓰나 |
|---|---|---|---|
State | 상태 | 이 대상은 어떤 상태에 있을 수 있고, 어떻게 옮겨가는가? | 생명주기·전이가 있는 대상을 다룰 때 |
ER | 데이터 | 어떤 데이터가 있고, 서로 어떻게 연결되는가? | DB 스키마를 이해·공유할 때 |
Class | 코드 | 어떤 타입·클래스가 있고, 어떤 관계를 맺는가? | 객체지향 설계·타입 계층을 공유할 때 |
결국 무엇을 그리느냐가 어떤 다이어그램을 고를지를 정한다는 생각이 듭니다. 상태를 가진 대상이면 State, 데이터의 연결이면 ER, 코드의 구조면 Class입니다. 흐름(2편)과 상태·구조(이번 글)까지 봤으니, 큰 갈래는 거의 다 다룬 셈입니다.
다음 4편(마지막)에서는 지금까지 다루지 않은 나머지 관점의 다이어그램들과, 결국 상황에 맞는 다이어그램을 고르는 법을 정리해 보려 합니다.
관련 글
다이어그램 종류는 왜 이렇게 많을까: 그림이 아니라 관점이라는 이야기
다이어그램 종류가 많은 이유는 각자 답하는 질문이 다르기 때문입니다. 같은 시스템을 Flowchart·Sequence·State로 그려 보며, 다이어그램은 그림이 아니라 관점이라는 생각에 이른 기록입니다.
흐름을 그리다: Flowchart와 Sequence 다이어그램의 차이
흐름을 그리는 두 종류의 다이어그램을 비교합니다. Flowchart는 절차와 분기를, Sequence는 시간순 상호작용과 동기·비동기 경계를 드러냅니다. 발행 파이프라인을 직접 그린 경험을 곁들였습니다.
Obsidian으로 프로젝트를 구조적으로 관리하기
ERD, 플로우차트, 명세, 백로그를 Obsidian에서 통합 관리하고, Claude Code와 연동하여 프로젝트를 구조적으로 분해하는 방법을 정리했습니다.