PromleeBlog
sitemap
aboutMe

posting thumbnail
UML 시퀀스 다이어그램 객체 상호작용 흐름 한눈에 보기
UML Sequence Diagrams Object Interactions

📅

🚀

들어가기 전에 🔗

지난 시간에는 UML 클래스 다이어그램을 통해 소프트웨어의 정적인
구조
, 즉 뼈대를 살펴보았습니다.
하지만 실제 소프트웨어는 가만히 있는 그림이 아니라, 살아 움직이며 여러 기능을 수행합니다.
오늘은 이처럼 시스템이 특정 작업을 할 때, 그 내부의 객체들이 마치 연극배우처럼 시간의 흐름에 따라 서로
대화(메시지)
를 주고받으며 협력하는 모습을 생생하게 그려내는
UML 시퀀스 다이어그램
에 대해 알아보겠습니다.

🚀

시퀀스 다이어그램이란 무엇일까요? 🔗

시퀀스 다이어그램(Sequence Diagram)은 UML(Unified Modeling Language)의 여러 다이어그램 중 하나로, 시스템이나 특정 기능이 실행될 때 관련된 객체들 사이의
상호작용
시간 순서에 따라
자세히 보여주는 동적 모델링 도구입니다.
이름에서 알 수 있듯이, '순서(Sequence)'가 핵심입니다. 어떤 객체가 다른 객체에게 요청을 보내고, 그 요청을 받은 객체가 응답하거나 또 다른 객체에게 일을 시키는 일련의 과정을 시간 축을 따라 위에서 아래로 표현합니다.
Sequence diagram
Sequence diagram
클래스 다이어그램이 시스템의 '등장인물 소개'라면, 시퀀스 다이어그램은 그 등장인물들이 특정 '장면(시나리오)'에서 어떤 '대사(메시지)'를 주고받으며 '연기(동작)'하는지를 보여주는 '대본'과 같습니다.
특히 다음과 같은 경우에 매우 유용하게 활용됩니다.

🚀

시퀀스 다이어그램의 핵심 구성 요소 🔗

시퀀스 다이어그램은 몇 가지 직관적인 기호와 표기법을 사용하여 객체들의 상호작용을 생생하게 그려냅니다.

액터 와 객체/라이프라인 (Actor Object/Lifeline) 🔗

액터와 객체, 라이프라인
액터와 객체, 라이프라인

메시지 (Message) 🔗

메시지는 한 객체가 다른 객체에게 특정 작업을 요청하거나 정보를 전달하는 행위를 나타냅니다.
두 객체의 라이프라인 사이를 가로지르는 화살표로 표현되며, 화살표의 모양과 선 종류에 따라 다양한 의미를 전달합니다.
➡️

동기 메시지 (Synchronous Message) 🔗

➡️

비동기 메시지 (Asynchronous Message) 🔗

➡️

응답 메시지 (Reply Message / Return Message) 🔗

➡️

자체 메시지 (Self-Message) 🔗

➡️

생성 메시지 (Create Message) 🔗

➡️

소멸 메시지 (Destroy Message) 🔗

메시지
메시지

활성화 (Activation / Execution Occurrence) 🔗

활성화는 객체가 메시지를 받아 특정 작업을 수행하고 있는 기간, 즉 객체가
활발하게 실행 중
인 상태를 나타냅니다.
라이프라인 위에 얇고 긴 직사각형 모양으로 표시되며, 이 직사각형(활성화 박스)의 세로 길이는 작업 수행 시간을 의미합니다.
동기 메시지를 수신하면 해당 객체의 라이프라인에 새로운 활성화 박스가 시작되고, 이 활성화가 종료되어야(즉, 작업이 완료되어야) 송신 객체에게 제어권이 돌아갑니다.
활성화
활성화

제어 프레임 (Control Frame / Combined Fragment) 🔗

복잡한 시나리오에서는 단순한 메시지 교환 외에도 조건에 따른 분기(if-else), 반복(loop), 예외 처리, 병렬 처리 등 다양한 제어 흐름이 필요합니다.
시퀀스 다이어그램에서는 이러한 복잡한 로직 흐름을
제어 프레임
이라는 사각형 영역을 사용하여 명시적으로 표현할 수 있습니다.
프레임의 왼쪽 상단에는 연산자(Operator)가 표시되어 프레임의 종류를 나타냅니다.
➡️

alt (Alternatives, 대안) 🔗

여러 조건 중 하나에 해당하는 상호작용 블록이 실행됩니다. (프로그래밍의 if-else if-else 구문과 유사)
프레임 내부는 각 조건(가드 컨디션, [조건문])을 명시한 점선으로 구분된 영역(피연산자, Operand)들로 나뉩니다.
예시: 로그인 시도 시, [인증 성공]인 경우와 [인증 실패]인 경우의 서로 다른 처리 흐름.
alt 프레임
alt 프레임
➡️

opt (Optional, 선택) 🔗

특정 조건이 참(true)일 경우에만 해당하는 상호작용 블록이 실행됩니다. (프로그래밍의 if 구문과 유사)
예시: [쿠폰 사용 가능] 조건이 만족될 때만 할인 적용 로직 실행.
opt 프레임
opt 프레임
➡️

loop (Loop, 반복) 🔗

특정 조건이 만족되는 동안(또는 정해진 횟수만큼) 내부의 상호작용 블록이 반복 실행됩니다.
반복 조건(예: [아이템 수만큼], [while x < 10])을 명시할 수 있습니다.
예시: 장바구니에 담긴 모든 [상품 재고 확인]을 반복하는 과정.
loop 프레임
loop 프레임
➡️

par (Parallel, 병렬) 🔗

프레임 내부의 여러 상호작용 블록들이 동시에 병렬적으로 실행될 수 있음을 나타냅니다.
각 병렬 실행 블록은 점선으로 구분됩니다.
예시: 여러 외부 서비스에 동시에 데이터를 요청하고 각각의 응답을 기다리는 상황.
par 프레임
par 프레임
➡️

ref (Reference, 참조) 🔗

현재 다이어그램의 일부를 다른 독립적인 시퀀스 다이어그램으로 분리하여 참조할 때 사용합니다. 복잡한 다이어그램을 모듈화하여 가독성을 높일 수 있습니다.
프레임 안에는 참조하는 다른 시퀀스 다이어그램의 이름을 명시합니다. (예: ref [인증 처리])
➡️

break (Break, 중단) 🔗

loopalt 등의 프레임에서 특정 조건이 만족되면 현재 프레임의 실행을 중단하고 빠져나감을 나타냅니다. 일반적인 프로그래밍의 break 문과 유사합니다.
예시: 반복 처리 중 [오류 발생 시] break.
break 프레임
break 프레임

🚀

유스케이스 기반 시퀀스 다이어그램 작성 예제 🔗

이론만으로는 감이 잘 안 올 수 있으니, 간단한 "온라인 도서 주문 시스템에서 사용자가 도서를 검색하고 장바구니에 추가하는" 유스케이스를 가지고 시퀀스 다이어그램을 그려보겠습니다.

유스케이스 시나리오 (기본 흐름) 🔗

  1. 사용자가 검색창에 도서명을 입력하고 '검색' 버튼을 클릭한다.
  2. 검색 UI는 검색 요청을 검색 컨트롤러에게 전달한다.
  3. 검색 컨트롤러는 도서 서비스에게 도서 검색을 요청한다.
  4. 도서 서비스는 도서 저장소(데이터베이스 등)에서 해당 도서명으로 도서를 검색한다.
  5. 도서 저장소는 검색된 도서 목록을 도서 서비스에게 반환한다.
  6. 도서 서비스는 검색 결과를 검색 컨트롤러에게 반환한다.
  7. 검색 컨트롤러는 검색 결과를 검색 UI에 전달하여 화면에 표시하도록 한다.
  8. 사용자가 검색된 도서 목록에서 특정 도서의 '장바구니 담기' 버튼을 클릭한다.
  9. 검색 UI는 장바구니 컨트롤러에게 해당 도서의 장바구니 추가를 요청한다.
  10. 장바구니 컨트롤러는 장바구니 서비스에게 도서 추가를 요청한다.
  11. 장바구니 서비스는 현재 사용자의 장바구니에 해당 도서를 추가하고, 성공 여부를 반환한다.
  12. (추가 성공 시) 장바구니 컨트롤러는 검색 UI에 장바구니 추가 성공 메시지를 전달한다.
  13. 검색 UI는 사용자에게 "장바구니에 추가되었습니다" 알림을 표시한다.
이제 이 시나리오를 시퀀스 다이어그램의 주요 상호작용 흐름으로 나타내 보겠습니다. (실제 다이어그램은 그림으로 표현되어야 훨씬 명확합니다.)

참여 객체 🔗

시퀀스 다이어그램 주요 흐름 (의사 코드 스타일 메시지) 🔗

사용자:Actor --1. searchButtonClicked(도서명)--> 검색UI:SearchUI
  검색UI:SearchUI --2. requestSearch(도서명)--> 검색컨트롤러:SearchController
    검색컨트롤러:SearchController --3. findBooks(도서명)--> 도서서비스:BookService
      도서서비스:BookService --4. queryBooksByName(도서명)--> 도서저장소:BookRepository
      도서저장소:BookRepository --5. bookList --> 도서서비스:BookService (응답)
    도서서비스:BookService --6. searchResult(bookList) --> 검색컨트롤러:SearchController (응답)
  검색컨트롤러:SearchController --7. displayResults(searchResult)--> 검색UI:SearchUI
 
사용자:Actor --8. addToCartButtonClicked(선택된도서ID)--> 검색UI:SearchUI
  검색UI:SearchUI --9. requestAddToCart(선택된도서ID)--> 장바구니컨트롤러:CartController
    장바구니컨트롤러:CartController --10. addItemToCart(사용자ID, 선택된도서ID)--> 장바구니서비스:CartService
    장바구니서비스:CartService --11. isSuccess --> 장바구니컨트롤러:CartController (응답: true/false)
 
    장바구니컨트롤러:CartController --[isSuccess == true] (opt 프레임 시작)-->
      장바구니컨트롤러:CartController --12. notifyCartUpdateSuccess()--> 검색UI:SearchUI
      검색UI:SearchUI --13. showNotification("장바구니 추가 성공")--> 사용자:Actor
    -- (opt 프레임 종료) -->
    
    장바구니컨트롤러:CartController --[isSuccess == false] (opt 프레임 시작)-->
      장바구니컨트롤러:CartController -- notifyCartUpdateFail()--> 검색UI:SearchUI
      검색UI:SearchUI -- showNotification("장바구니 추가 실패")--> 사용자:Actor
    -- (opt 프레임 종료) -->
도서 검색 및 장바구니 추가 시나리오
도서 검색 및 장바구니 추가 시나리오
이처럼 시퀀스 다이어그램을 사용하면 복잡해 보이는 상호작용도 시간의 흐름에 따라 단계별로 명확하게 이해하고 표현할 수 있습니다.

🚀

시퀀스 다이어그램 작성 시 고려사항 🔗

효과적인 시퀀스 다이어그램을 작성하기 위해 몇 가지 고려할 점이 있습니다.

🚀

결론 🔗

오늘은 UML 시퀀스 다이어그램을 통해 시스템 내 객체들이 시간의 흐름에 따라 마치 대화를 나누듯 메시지를 주고받으며 상호작용하는 동적인 모습을 그리는 방법을 알아보았습니다.
라이프라인, 다양한 종류의 메시지, 활성화, 그리고 복잡한 흐름을 제어하는 제어 프레임 등 핵심 구성 요소를 이해하고, 실제 유스케이스를 바탕으로 다이어그램 작성 예시도 살펴보았습니다.
다음 시간에는 이렇게 설계된 소프트웨어가 얼마나 튼튼하고 유연한지 평가하고 개선하는 데 도움이 되는 중요한 설계 원칙들인
좋은 설계를 위한 SOLID 원칙 배우기
에 대해 자세히 알아보도록 하겠습니다.

참고 🔗