UML 다이어그램, 설계의 언어를 배우다

📌 들어가며
안녕하세요! 멀티캠퍼스 유레카 3기 백엔드 과정을 수강 중인 개발자 지망생입니다.
오늘은 소프트웨어 공학의 핵심인 UML 다이어그램을 배웠어요! 그동안 "설계? 그냥 바로 코딩하면 되는 거 아니야?"라고 생각했는데, 오늘 수업을 듣고 나니 왜 대규모 프로젝트에서 설계가 필수인지 완벽하게 이해하게 됐습니다.
선생님이 수업 시작할 때 이렇게 말씀하셨어요.
"설계 없이 코딩하는 건 설계도 없이 건물 짓는 것과 같다. 소규모 프로젝트는 그냥 짓는 게 빠를 수 있지만, 100층 빌딩을 설계도 없이 지을 수는 없다!"
특히 유스케이스 다이어그램으로 시스템 요구사항을 정리하고, 클래스 다이어그램으로 객체 간 관계를 설계하고, 시퀀스 다이어그램으로 객체 간 상호작용을 표현하는 과정이 정말 인상 깊었어요!
🎯 Today I Learned
✅ UML이란 무엇인가?
✅ 유스케이스 다이어그램 (Use Case Diagram)
✅ 클래스 다이어그램 (Class Diagram)
✅ 시퀀스 다이어그램 (Sequence Diagram)
✅ 다이어그램 간의 관계
✅ 실무에서의 활용 방법
🤔 UML, 왜 필요할까?
설계 없이 개발하면?
시나리오: 쇼핑몰 프로젝트 (5명 팀)
[설계 없이 개발]
김철수: "난 회원가입 먼저 만들게!"
이영희: "난 상품 목록 만들게!"
박민수: "난 결제 시스템 만들게!"
2주 후...
- 회원가입에서 저장한 데이터를 상품에서 못 읽음 ❌
- 결제 시스템이 회원 정보 구조를 몰라서 연동 실패 ❌
- 3명이 같은 기능을 중복 개발 ❌
- 코드 합치는 데만 1주일 소요 ❌
결과: 프로젝트 실패 😱
UML 다이어그램으로 설계하면:
[1주차: 설계]
- 유스케이스로 기능 정리
- 클래스 다이어그램으로 구조 설계
- 시퀀스 다이어그램으로 동작 흐름 정의
[2-3주차: 개발]
- 모두가 같은 설계도를 보고 개발
- 데이터 구조 통일
- 역할 분담 명확
결과: 프로젝트 성공! ✅

UML이란?

UML = Unified Modeling Language (통합 모델링 언어)
목적:
- 시스템을 시각화
- 설계를 문서화
- 팀원 간 의사소통
종류:
- 구조 다이어그램: 클래스, 객체, 컴포넌트...
- 행위 다이어그램: 유스케이스, 시퀀스, 활동...
👥 1단계: 유스케이스 다이어그램 - 사용자 관점의 설계
유스케이스 다이어그램이란?
유스케이스 다이어그램 = 사용자와 시스템의 상호작용을 표현
핵심 질문:
- 누가(Actor) 시스템을 사용하나?
- 시스템이 무엇(Use Case)을 제공하나?
구성 요소
1. 시스템 (System)
┌─────────────────┐
│ 쇼핑몰 시스템 │
│ │
└─────────────────┘
큰 사각형으로 표현
2. 액터 (Actor)
👤
고객
👤
관리자
시스템 외부의 사용자
사람 모양으로 표현
3. 유스케이스 (Use Case)
( 로그인 )
( 상품 검색 )
( 주문하기 )
타원으로 표현
사용자가 인식하는 기능
4. 관계 (Relationship)
연관 관계 (Association)
👤 ───── ( 로그인 )
실선: 액터가 유스케이스 사용
포함 관계 (Include)
( 주문하기 ) ─────«include»────→ ( 결제하기 )
점선 + «include»: 필수로 포함
확장 관계 (Extend)
( 결제하기 ) ←────«extend»───── ( 쿠폰 사용 )
점선 + «extend»: 선택적 확장
일반화 관계 (Generalization)
👤 일반 회원
△
│
👤 VIP 회원
삼각형 화살표: 상속 관계

실전 예제: 온라인 쇼핑몰
┌──────────────────────────────────────┐
│ 온라인 쇼핑몰 시스템 │
│ │
│ ( 회원가입 ) │
│ ( 로그인 ) ←───── 👤 고객 │
│ ( 상품 검색 ) │
│ ( 장바구니 담기 ) │
│ ( 주문하기 ) ────«include»───→ ( 재고 확인 )
│ │ │
│ └────«include»───→ ( 결제하기 )
│ ↑ │
│ «extend»─┘ │
│ ( 쿠폰 사용 ) │
│ │
│ ( 주문 관리 ) ←───── 👤 관리자 │
│ ( 재고 관리 ) │
└──────────────────────────────────────┘
유스케이스 작성법
❌ 잘못된 예:
( 버튼 클릭 ) ← 기능이 아니라 동작
( 데이터베이스 저장 ) ← 시스템 내부 동작
( SQL 실행 ) ← 구현 세부사항
✅ 올바른 예:
( 상품 주문 ) ← 사용자 목표
( 회원 정보 수정 ) ← 사용자 관점
( 배송지 변경 ) ← 명확한 기능
핵심 원칙:
1. 사용자 관점에서 작성
2. 동사 + 명사 형태
3. 시스템이 제공하는 가치
4. 하나의 완결된 작업
관계 이해하기

Include (포함):
상황: 주문할 때 결제는 필수!
( 주문하기 ) ────«include»───→ ( 결제하기 )
의미: 주문하려면 반드시 결제해야 함
Extend (확장):
상황: 결제할 때 쿠폰 사용은 선택!
( 결제하기 ) ←────«extend»───── ( 쿠폰 사용 )
의미: 결제할 때 원하면 쿠폰을 사용할 수 있음
차이점:
구분 Include Extend
| 의미 | 필수 포함 | 선택적 확장 |
| 방향 | A → B (A가 B 포함) | A ← B (B가 A 확장) |
| 예시 | 로그인 → 인증 | 결제 ← 쿠폰사용 |
📦 2단계: 클래스 다이어그램 - 구조의 설계
클래스 다이어그램이란?
클래스 다이어그램 = 시스템의 구조를 클래스로 표현
목적:
- 클래스 간 관계 파악
- 코드 구조 설계
- 데이터베이스 설계 기초
클래스 표기법
┌─────────────────┐
│ Student │ ← 클래스명
├─────────────────┤
│ - name: String │ ← 속성 (필드)
│ - age: int │
│ - grade: String │
├─────────────────┤
│ + study(): void │ ← 메서드 (연산)
│ + attend(): void│
└─────────────────┘
가시성:
+ : public
- : private
# : protected
~ : default (package)
클래스 간 관계

1. 일반화 (Generalization) - 상속
┌─────────┐
│ Animal │
└─────────┘
△
│ (빈 삼각형 + 실선)
┌─────┴─────┐
│ │
┌─────────┐ ┌─────────┐
│ Cat │ │ Dog │
└─────────┘ └─────────┘
관계: Cat "is a" Animal
코드: class Cat extends Animal
Java 코드:
public class Animal {
protected String name;
public void eat() {
System.out.println("먹는다");
}
}
public class Cat extends Animal {
public void meow() {
System.out.println("야옹");
}
}
public class Dog extends Animal {
public void bark() {
System.out.println("멍멍");
}
}
2. 실체화 (Realization) - 인터페이스 구현
┌───────────────┐
│ «interface» │
│ Flyable │
└───────────────┘
△
│ (빈 삼각형 + 점선)
┌────┴────┐
│ │
┌──────┐ ┌──────┐
│ Bird │ │Plane │
└──────┘ └──────┘
관계: Bird "can do" Fly
코드: class Bird implements Flyable
Java 코드:
public interface Flyable {
void fly();
}
public class Bird implements Flyable {
@Override
public void fly() {
System.out.println("새가 난다");
}
}
public class Plane implements Flyable {
@Override
public void fly() {
System.out.println("비행기가 난다");
}
}
3. 연관 (Association) - 참조 관계
┌──────────┐ ┌──────────┐
│ Student │────────── │ Course │
└──────────┘ 1..* └──────────┘
관계: Student "has a" Course
다중성: 학생 1명이 여러 수업 수강
Java 코드:
public class Student {
private String name;
private List<Course> courses; // 참조
public void registerCourse(Course course) {
courses.add(course);
}
}
public class Course {
private String courseName;
private int credit;
}
다중성 (Multiplicity):
1 : 정확히 1개
0..1 : 0개 또는 1개
* : 0개 이상
1..* : 1개 이상
2..5 : 2개부터 5개까지
4. 집합 (Aggregation) - 약한 소유
┌──────────┐ ┌──────────┐
│ Car │◇────── │ Wheel │
└──────────┘ └──────────┘
4
관계: Car "has a" Wheel (빈 다이아몬드)
의미: 바퀴는 자동차 없이도 존재 가능
Java 코드:
public class Wheel {
private String brand;
private int size;
}
public class Car {
private List<Wheel> wheels; // 약한 소유
public Car(List<Wheel> wheels) {
this.wheels = wheels; // 외부에서 생성된 바퀴
}
// Car가 사라져도 Wheel은 남아있음
}
5. 합성 (Composition) - 강한 소유
┌──────────┐ ┌──────────┐
│ House │◆────── │ Room │
└──────────┘ └──────────┘
관계: House "owns a" Room (채워진 다이아몬드)
의미: 집이 없으면 방도 없음
Java 코드:
public class Room {
private String name;
private int size;
}
public class House {
private List<Room> rooms; // 강한 소유
public House() {
rooms = new ArrayList<>();
rooms.add(new Room()); // House가 Room 생성
}
// House가 사라지면 Room도 사라짐
}
Aggregation vs Composition:

구분 Aggregation (집합) Composition (합성)
| 소유 | 약한 소유 | 강한 소유 |
| 생명주기 | 독립적 | 종속적 |
| 표기 | 빈 다이아몬드 ◇ | 채운 다이아몬드 ◆ |
| 예시 | Car - Wheel | House - Room |
6. 의존 (Dependency) - 일시적 사용
┌──────────┐ ┌──────────┐
│ Car │- - - -→│ GasPump │
└──────────┘ └──────────┘
관계: Car "uses a" GasPump (점선 화살표)
의미: 잠깐 사용하고 끝
Java 코드:
public class GasPump {
public void fillGas(int amount) {
System.out.println(amount + "L 주유");
}
}
public class Car {
// GasPump를 멤버 변수로 갖지 않음!
public void fillGas(GasPump pump) { // 매개변수로만 사용
pump.fillGas(50);
}
}
클래스 다이어그램 실전 예제
쇼핑몰 시스템:
┌───────────────┐
│ User │
│───────────────│
│- userId │
│- password │
│───────────────│
│+ login() │
│+ logout() │
└───────────────┘
△
│
┌────┴────┐
│ │
┌──────┐ ┌──────┐
│Admin │ │Customer│
└──────┘ └──────┘
│
│1
│
│*
┌──────┐
│Order │ ◆────┐
└──────┘ │
│*
┌─────────┐
│OrderItem│
└─────────┘
│
│*
│
┌─────────┐
│ Product │
└─────────┘
📊 3단계: 시퀀스 다이어그램 - 동작의 설계
시퀀스 다이어그램이란?
시퀀스 다이어그램 = 객체 간 메시지 교환을 시간 순서로 표현
언제 사용?
- 로그인 과정
- 주문 흐름
- API 호출 순서
구성 요소
Actor Object1 Object2
│ │ │
│─────────→ │ 1. 메시지
│ │─────────→ 2. 메시지
│ ←─────────│ 3. 응답
←─────────│ │ 4. 응답
│ │ │
요소:
- Actor: 사용자
- Object: 객체 (점선이 생명선)
- 화살표: 메시지 (→)
- 점선 화살표: 응답 (←·)

실전 예제: 로그인 과정
User LoginPage Server Database
│ │ │ │
│ 1.입력 │ │ │
│──────────→│ │ │
│ │2.로그인 요청 │
│ │────────→│ │
│ │ │3.쿼리 │
│ │ │─────────→│
│ │ │4.결과 │
│ │ ←─────────│
│ │5.JWT 생성│ │
│ │ │ │
│ │6.토큰 반환│ │
│ ←────────│ │
│7.메인페이지│ │ │
←──────────│ │ │
│ │ │ │
설명:
1. 사용자가 ID/PW 입력
2. LoginPage가 Server에 로그인 요청
3. Server가 Database에 쿼리
4. Database가 사용자 정보 반환
5. Server가 JWT 토큰 생성
6. Server가 LoginPage에 토큰 반환
7. LoginPage가 메인 페이지로 이동
활성화 박스 (Activation Box)
Object
│
│─────→ ← 메시지
┃
┃ ← 활성화 박스 (객체가 작동 중)
┃
←───── ← 응답
│
조건문과 반복문
조건문 (alt):
[재고 > 0]
주문 처리
[재고 = 0]
품절 알림
반복문 (loop):
loop [장바구니 상품마다]
가격 합산
end
시퀀스 다이어그램 예제: 주문 과정
Customer Cart OrderService PaymentService Database
│ │ │ │ │
│ 1.담기│ │ │ │
│──────→│ │ │ │
│ │ │ │ │
│ 2.주문│ │ │ │
│──────→│ │ │ │
│ │3.주문생성│ │ │
│ │─────────→│ │ │
│ │ │4.재고확인 │ │
│ │ │──────────────────────────→│
│ │ │5.OK │ │
│ │ ←──────────────────────────│
│ │ │6.결제 요청 │ │
│ │ │─────────────→│ │
│ │ │7.결제 완료 │ │
│ │ ←─────────────│ │
│ │ │8.주문 저장 │ │
│ │ │──────────────────────────→│
│ │9.완료 │ │ │
←──────────────────│ │ │
│ │ │ │ │
💡 오늘 나는 무엇을 잘했는가 (성취)
프로젝트 설계도를 그렸어요!
1. 유스케이스 다이어그램:
┌──────────────────────────────┐
│ 게시판 시스템 │
│ │
│ ( 회원가입 ) │
│ ( 로그인 ) ←──── 👤 회원 │
│ ( 게시글 작성 ) │
│ ( 댓글 달기 ) ─include→ ( 로그인 확인 )
│ ( 좋아요 ) │
│ ( 북마크 ) │
└──────────────────────────────┘
2. 클래스 다이어그램:
┌───────┐ 1..* ┌─────────┐
│ User │◆───────────│ Post │
└───────┘ └─────────┘
│1
│
│*
┌─────────┐
│ Comment │
└─────────┘
이렇게 정리하니까 테이블 설계가 훨씬 명확해졌어요!
팀원들과 의사소통이 빨라졌어요!
"댓글에 대댓글 기능을 넣을까요?"라는 질문에 말로 설명하는 대신 클래스 다이어그램을 그려서 보여줬더니, 3분 만에 이해하고 의견 통일!
Before (30분 회의):
"댓글이 있고요, 그 댓글에 또 댓글을..."
"어? 그럼 데이터는 어떻게 저장?"
"음... 테이블을 두 개?"
After (3분):
┌─────────┐
│Comment │
│- id │
│- parent │ ← 이거면 끝!
└─────────┘
🔧 어떤 문제를 겪었고, 어떻게 개선할까 (개선점)
문제 1: 다이어그램이 너무 복잡해짐
처음엔 모든 기능을 하나의 유스케이스 다이어그램에 넣으려다가... 너무 복잡해서 포기했어요 😅
해결 방법:
개선 전:
[메인 시스템]에 모든 기능 30개 포함 ❌
개선 후:
- [회원 관리] 유스케이스
- [게시판] 유스케이스
- [관리자] 유스케이스
기능별로 분리! ✅
문제 2: 클래스 관계 헷갈림
Aggregation과 Composition의 차이가 계속 헷갈렸어요!
해결 방법:
외우기 쉬운 예시 만들기:
Aggregation (집합) = 회사 - 직원
- 회사 없어져도 직원은 다른 회사 갈 수 있음
- ◇ (빈 다이아몬드)
Composition (합성) = 사람 - 심장
- 사람 없으면 심장도 의미 없음
- ◆ (채운 다이아몬드)
문제 3: 시퀀스 다이어그램의 순서
JWT 인증 과정을 시퀀스로 그리다가... 순서가 꼬여서 3번 다시 그렸어요!
개선 계획:
순서:
1. 먼저 순서를 텍스트로 정리
2. 그 다음 다이어그램으로 변환
예:
1. 사용자 로그인 요청
2. 서버가 DB 조회
3. JWT 생성
4. 토큰 반환
📚 오늘 배운 것 (학습)
1. 다이어그램마다 목적이 다르다
유스케이스: "뭘 만들까?" (요구사항)
클래스: "어떻게 구조?" (설계)
시퀀스: "어떻게 동작?" (흐름)
3개 모두 필요!
2. 설계의 중요성
설계 없이: 코딩 2시간 → 리팩토링 10시간
설계 후: 설계 1시간 → 코딩 3시간
총 시간: 12시간 vs 4시간
설계가 3배 빠름!
3. 의사소통 도구로서의 다이어그램
말로 설명: "게시글이 있고, 댓글이 있고..."
다이어그램: [그림 1장]
1장의 그림 > 1000마디 말
4. 실무에서의 활용
기획자: 유스케이스 다이어그램으로 요구사항 전달
개발자: 클래스 다이어그램으로 구조 설계
팀원: 시퀀스 다이어그램으로 흐름 공유
모두가 같은 그림을 보고 작업!
😊 좋았던 점 & 😅 아쉬웠던 점
좋았던 점
👍 실습 위주로 진행
이론 설명 30분, 실습 90분! 직접 그리면서 배우니까 훨씬 이해가 빨랐어요.
👍 실제 프로젝트 적용
배운 내용을 바로 miniproject2에 적용해봤더니, 테이블 설계가 훨씬 명확해졌어요!
👍 팀 프로젝트에 바로 써먹음
오후에 팀 회의할 때 클래스 다이어그램 보여줬더니, 모두가 "오! 이해됐어요!"라고!
아쉬웠던 점
😢 도구 사용법 배우는 시간 부족
PlantUML, draw.io 같은 도구를 간단히만 소개하고 넘어가서 아쉬웠어요. 실습 시간에 손으로 그리느라 시간이 오래 걸렸습니다.
😢 활동 다이어그램은 못 다룸
시간 관계상 활동 다이어그램(Activity Diagram)은 못 배웠어요. 프로세스 흐름 표현할 때 유용할 것 같은데...
😢 실무 예시가 더 있었으면
"대기업에서는 어떻게 다이어그램을 활용하는가?"에 대한 예시가 더 있으면 좋았을 것 같아요!
🎓 나만의 학습 팁
1. 단계별로 그리기
Step 1: 텍스트로 정리
"사용자가 로그인하면..."
Step 2: 간단한 스케치
종이에 대충 그려보기
Step 3: 도구로 정리
draw.io로 깔끔하게
2. 실제 서비스 분석하기
쿠팡 앱을 켜서:
1. 어떤 기능이 있나? → 유스케이스
2. 어떤 데이터가 필요한가? → 클래스
3. 주문 과정은? → 시퀀스
역분석하면서 연습!
3. 관계 외우는 법
일반화 (상속): Cat is a Animal
실선 + 빈 삼각형 △
실체화 (구현): Bird can Fly
점선 + 빈 삼각형 △
연관 (참조): Student has Course
실선 ─
집합 (약한 소유): Car has Wheel
빈 다이아몬드 ◇
합성 (강한 소유): House owns Room
채운 다이아몬드 ◆
의존 (사용): Car uses GasPump
점선 화살표 ─ ─ →
4. 추천 도구
무료 도구:
1. draw.io (https://app.diagrams.net/)
- 가장 쉬움
- 브라우저에서 바로 사용
- 추천! ⭐⭐⭐⭐⭐
2. PlantUML
- 코드로 다이어그램 생성
- 버전 관리 가능
- 약간 어려움
3. StarUML
- 전문 도구
- 기능 많음
- 무료 버전 제한적
5. 체크리스트
유스케이스 다이어그램:
☑ 액터는 시스템 외부인가?
☑ 유스케이스는 사용자 관점인가?
☑ Include/Extend 방향이 맞나?
☑ 너무 세부적이지 않나?
클래스 다이어그램:
☑ 클래스 이름은 명사인가?
☑ 메서드 이름은 동사인가?
☑ 관계 화살표 방향이 맞나?
☑ 순환 의존은 없나?
시퀀스 다이어그램:
☑ 시간 순서가 위→아래인가?
☑ 메시지 순서가 명확한가?
☑ 응답이 빠진 곳은 없나?
☑ 생명선이 올바른가?
🚀 다음 학습 목표
📌 단기 목표 (이번 주)
✓ miniproject2 전체 다이어그램 완성
✓ 팀원들과 다이어그램 리뷰
✓ draw.io 마스터하기
✓ 활동 다이어그램 독학
📌 중기 목표 (이번 달)
✓ 포트폴리오에 다이어그램 추가
✓ ERD (Entity Relationship Diagram) 학습
✓ 상태 다이어그램 학습
✓ 실무 프로젝트 사례 분석
📌 장기 목표 (부트캠프 기간)
✓ 모든 프로젝트에 설계 문서 작성
✓ GitHub에 다이어그램 포함
✓ 취업 포트폴리오 완성도 UP
🎬 마치며
오늘 수업을 듣기 전에는 "다이어그램? 그냥 그림 아니야?"라고 생각했어요.
하지만 직접 그려보고 나니 깨달았습니다.
다이어그램은 개발자의 언어입니다.
코드만 보면 전체 구조를 파악하기 어렵지만, 다이어그램 하나면 한눈에 시스템 전체가 보여요!
선생님이 마지막에 하신 말씀이 기억에 남아요.
"좋은 개발자는 코드를 잘 짜는 사람이 아니라, 좋은 설계를 한 후 코드를 짜는 사람이다. 다이어그램은 그 설계를 표현하는 도구다."
특히 유스케이스 다이어그램으로 "뭘 만들지" 정하고, 클래스 다이어그램으로 "어떻게 만들지" 설계하고, 시퀀스 다이어그램으로 "어떻게 동작할지" 표현하는 과정이 정말 체계적이었어요!
앞으로는 코딩하기 전에 5분만 투자해서 다이어그램을 그려보는 습관을 들이겠습니다! 💪
설계의 힘, 오늘 제대로 배웠습니다!
💬 여러분은 어떤 도구를 사용하시나요?
draw.io? PlantUML? StarUML? 추천하는 UML 도구가 있다면 댓글로 공유해주세요! 🙏