Unified Modeling Language · OMG 표준 · 1997~현재

UML 읽는 법 소프트웨어 구조를 그림으로

UML은 소프트웨어 구조와 동작을 시각화하는 표준 표기법이다. 기호가 많아 복잡해 보이지만 실전에서 자주 쓰는 건 클래스 다이어그램시퀀스 다이어그램 두 가지다. 이 문서의 빠른 참조 표는 북마크해두고 필요할 때 꺼내보면 된다.

구조 다이어그램 (정적 — "어떻게 생겼나")

  • 클래스 다이어그램 ← 가장 중요
  • 패키지 다이어그램
  • 컴포넌트 다이어그램

행위 다이어그램 (동적 — "어떻게 동작하나")

  • 시퀀스 다이어그램 ← 두 번째로 중요
  • 상태 다이어그램 (State Machine)
  • 활동 다이어그램

1. 클래스 박스 구조

클래스 하나는 3구역으로 나뉜 직사각형으로 표현된다. 위에서부터 이름 → 필드 → 메서드 순서다.

Animal - name: String - age: u32 + is_hungry: bool + eat() → void - breathe() → bool 이름 구역 클래스(struct) 이름 필드 구역 접근자 이름: 타입 - private + public # protected 메서드 구역 접근자 이름(인자) → 반환타입

접근자 기호 → Rust 대응

기호의미Rust
+public (어디서든 접근)pub fn foo()
-private (클래스 내부만)fn foo() (기본값)
#protected (자식 클래스까지)Rust에 직접 대응 없음 (pub(crate) 근사)
~package (같은 패키지)pub(crate)

2. 관계 기호 읽기

화살표 종류가 다르면 관계가 다르다. 각 기호를 하나씩 살펴보자.

Dog Animal

① 상속 (Inheritance)

실선 + 속이 빈 삼각형 화살표. 화살표가 부모를 향한다.
Dog is-a Animal. Dog는 Animal의 모든 특성을 물려받는다.

Rust에서: Rust에는 struct 상속이 없다. 트레이트 상속(trait Dog: Animal)이 이에 가장 가깝다.

Cat «interface» Flyable

② 구현 (Implementation / Realization)

점선 + 속이 빈 삼각형 화살표. 상속과 생김새가 비슷하지만 선이 점선이다.
인터페이스(trait)를 구현함을 나타낸다.

Rust에서: impl Flyable for Cat

Owner Pet 1 0..* pets (참조 관계)

③ 연관 (Association)

실선 + 열린 화살표 (V자). "알고 있다" 관계. 한쪽이 다른 쪽을 참조한다.
숫자(다중성)가 붙으면 몇 개를 가리키는지를 나타낸다.

Rust에서: struct Owner { pets: Vec<Arc<Pet>> }

④ 집합(Aggregation) vs ⑤ 합성(Composition) — 가장 헷갈리는 두 가지

Team Player

빈 마름모 ◇ = 집합(Aggregation)

Team이 없어도 Player는 다른 Team에 소속될 수 있다. 서로 독립적으로 존재 가능.

struct Team { players: Vec<&Player> }
빌림(borrow) — Player의 수명이 Team과 무관

House Room

채워진 마름모 ◆ = 합성(Composition)

House가 파괴되면 Room도 함께 사라진다. 생사를 같이한다.

struct House { rooms: Vec<Room> }
소유(own) — Room의 수명이 House에 종속

다중성(Multiplicity) 표기 → Rust 타입

UML 표기의미Rust 타입예시
1정확히 1개T사람 → 뇌 1개
0..1없거나 1개Option<T>사람 → 배우자 (없거나 1명)
* 또는 0..*0개 이상Vec<T>쇼핑카트 → 아이템들
1..*1개 이상(T, Vec<T>)팀 → 최소 1명의 멤버
3정확히 3개[T; 3]RGB → 채널 3개

2. 시퀀스 다이어그램 읽기

시간 흐름에 따른 객체 간 메시지 교환을 표현한다. 위에서 아래로 읽는다. "누가 누구에게 무엇을 요청하고 어떤 응답을 받는가"를 단번에 파악할 수 있다.

Client HttpServer Database GET /users/42 SELECT * FROM users WHERE id=42 Ok(User { id: 42, name: "jin" }) serde_json::to_string(user) 200 OK {"id":42,"name":"jin"} 범례 실선 + 채워진 화살표 = 동기 호출 (기다림) 점선 + 열린 화살표 = 반환 (return) 수직 박스 = 활성화 구간 (실행 중) ↩ 루프 화살표 = 자기 자신 호출 (self call)
읽는 순서: 위 → 아래 (시간 순). 실선 = 내가 상대를 호출. 점선 = 상대가 나에게 값을 돌려줌. 수직 박스가 있는 구간이 해당 객체가 실행 중인 시간이다.

3. 상태 다이어그램 읽기

객체가 가질 수 있는 상태와, 어떤 이벤트가 발생했을 때 어느 상태로 전이하는지를 나타낸다. Rust의 enum과 직결된다.

시작 Pending confirm() Confirmed ship() Shipped deliver() Delivered 종료 cancel() [Shipped 이전만 가능] Cancelled
시작점 (채워진 원)
종료점 (이중 원)
상태
전이 (이벤트)

위 다이어그램을 Rust enum으로 표현하면:

enum OrderStatus {
    Pending,
    Confirmed,
    Shipped,
    Delivered,
    Cancelled,
}

impl Order {
    fn confirm(&mut self) -> Result<(), &str> {
        match self.status {
            OrderStatus::Pending => { self.status = OrderStatus::Confirmed; Ok(()) }
            _ => Err("cannot confirm"),
        }
    }
    fn cancel(&mut self) -> Result<(), &str> {
        match self.status {
            OrderStatus::Shipped | OrderStatus::Delivered => Err("too late to cancel"),
            _ => { self.status = OrderStatus::Cancelled; Ok(()) }
        }
    }
}

4. 실전 예제 — 쇼핑몰

User가 Order를 여럿 낼 수 있고, Order는 여러 OrderItem을 합성(Composition)으로 포함한다. OrderItem은 Product를 참조한다.

User - id: u64 - email: String + login() + place_order() Order - id: u64 - status: OrderStatus - total: f64 + confirm() + cancel() OrderItem - quantity: u32 - price: f64 + subtotal() → f64 Product - name: String - price: f64 - stock: u32 1 0..* places 1..* items ◆ 1 product ◆ 합성: Order가 사라지면 OrderItem도 사라진다 (Vec<OrderItem> 소유) → 연관: OrderItem이 Product를 참조하지만 Product는 독립적으로 존재

주문 생성 흐름 — Browser → OrderController → PaymentService 순서로 호출된다.

Browser OrderCtrl PayService ① POST /order {items} ② charge(amount) ③ Ok(receipt) ④ save_order() ⑤ 201 Created {orderId}

주문 상태 머신. Pending → Confirmed → Shipped → Delivered 가 정상 경로. Cancelled는 Shipped 이전에만 가능.

Pending confirm() Confirmed ship() Shipped deliver() Delivered cancel() [Shipped 이전만] Cancelled

빠른 참조 — 화살표 한눈에

외울 필요 없다 — 이 표를 북마크해두고 다이어그램 볼 때마다 참고하면 된다.

화살표 모양이름Rust 대응
실선 ─── △ (빈 삼각형)상속is-a 관계, 부모 쪽을 향함trait Child: Parent
점선 ···· △ (빈 삼각형)구현인터페이스(trait) 구현impl Trait for Type
실선 ─── → (열린 화살표)연관참조를 가짐, "알고 있다"Arc<T> 또는 &T 필드
실선 ◇── → (빈 마름모)집합포함하지만 독립적 생존Vec<&T> (빌림)
실선 ◆── → (채워진 마름모)합성생사를 같이함, 부모가 소유Vec<T> (소유)
점선 ···· → (열린 화살표)의존사용하지만 필드 아님함수 파라미터, 로컬 변수