지난 글에서는 use case description 으로부터 시스템을 설계하는 class diagram 을 만드는 과정을 정리하였다.
이때 중간에 오브젝트 간 상호작용을 표현하는 방법으로서 communication diagram 으로 상호작용을 표현했다.
이번 글에서는 sequence diagram 이라는 또 다른 오브젝트 간 상호작용 표현 방법을 정리해본다.
Sequence Diagram
시퀀스 다이어그램은 오브젝트간 상호작용을 시간순으로 나타낸 다이어그램이다.
그리고 이 상호작용의 디테일 정도는 계층을 나눠서 표현한다.
한번에 모든 상호작용의 전체 디테일을 다 표현하면 너무 복잡하기 때문에, 필요한 만큼만 디테일하게 그릴 수 있다.
시퀀스 다이어그램은 클래스 다이어그램을 그리기 전 커뮤니케이션 다이어그램 대신에 그릴 수 있는 다이어그램으로 하나의 유즈 케이스에 대해서 그리는 것이 일반적이다.
시퀀스 다이어그램의 예시는 위와 같다.
먼저 세로축은 시간선을 나타낸다. 위에서 아래로 갈 수록 시간의 흐름이 진행되는 것을 보여준다.
가로 축에는 상호작용하는 외부 시스템 또는 오브젝트들이 나열된다.
두 오브젝트 사이의 메세지 전달은 커뮤니케이션 다이어그램과 동일하게 화살표로 표시한다.
만약 반복문, 조건문과 같은 로직을 표현하려는 경우, combined fragment 로 감싸고, 왼쪽 위 프레임 레이블에 연산자를 기술한다.
연산자 종류로는 alt, loop, ref 등이 있다. 프레임 상단에는 [ ] 안에 조건을 기술할 수 있다. (위 그림에선 생략함)
각각의 오브젝트에는 세로 점선으로 lifeline 을 나타낸다.
이 선은 이 객체가 메모리에 살아있는 시간을 나타낸다.
세로 점선 위에 네모 선은 activation 또는 execution 이라고 부르며, 그 오브젝트의 특정 메서드가 실행되는 시간을 나타낸다.
생성자의 경우, 실선이 아닌 점선 화살표로 표현한다.
또한 지난 글에서 언급했듯, 하나의 유즈 케이스에 대한 다이어그램을 그릴 때 적어도 1개의 컨트롤 클래스와 1개의 바운더리 클래스가 필요하다.
이처럼 시퀀스 다이어그램과 커뮤니케이션 다이어그램 모두 오브젝트간 상호작용을 표현하는 다이어그램이다.
커뮤니케이션 다이어그램이 각 오브젝트간 상호작용 관계를 좀 더 집중해서 그린다면
시퀀스 다이어그램은 상호작용을 시간 순으로 나타내는데 더 집중해서 그린다.
그래서 시퀀스 다이어그램은 오브젝트의 수가 많아지면 다이어그램이 옆으로 길어지기 때문에 오브젝트 사이의 상호작용을 한눈에 보기 힘들다는 단점이 있다.
반면 커뮤니케이션 다이어그램은 메서드 호출의 순서를 번호로만 표시하므로, 호출 흐름을 따라가는 것이 시퀀스 다이어그램보다 불편하다는 단점이 있다.
따라서 두 다이어그램 중 상황에 따라 더 적절한 다이어그램을 선택해서 그리는 것이 좋다.
오브젝트가 메모리에서 사라지는 경우, 위 그림과 같이 X 로 표시하여 오브젝트의 lifeline이 종료됨을 표시해준다.
필요한 경우에는 메서드가 값을 반환한다는 것을 이렇게 return 으로 표현할 수 있다.
이런 reply message 는 점선으로 표시한다.
로직을 처리하는 과정에서 자기 자신의 메서드를 호출하는 경우가 있을 수 있다.
이런 메세지를 가리켜 reflexive message 라고 부르며, 자기 자신으로 돌아오는 화살표로 표현한다.
Handling Complexity
시퀀스 다이어그램을 그릴 때 정말 시스템의 모든 로직을 다 그리게 되면 다이어그램이 너무 복잡해질 것이다.
그래서 다이어그램을 그릴 때 어느 정도 복잡도를 조정해서 그릴 필요가 있다.
복잡도를 조정하는 좋은 방법은 로직의 일부분을 추상화하는 것이다.
다이어그램이 복잡해지는 방향은 크게 가로와 세로로 나눌 수 있다.
오브젝트가 너무 많아서 복잡하거나, 상호작용의 단계가 너무 많아서 복잡한 것이다.
먼저 상호작용의 단계가 너무 많아서 복잡한,
세로로 길어지는 다이어그램은 interfaction fragment 로 단순화할 수 있다.
interfaction fragment 는 위 그림처럼 로직의 특정 영역을 프래그먼트로 감싸고 왼쪽 위에 interaction operator 를 기술한 형태로 작성한다.
대표적인 interaction operator 에는 반복문을 나타내는 loop, 조건문을 나타내는 alt, 특정 조건일 때만 실행하는 opt 가 대표적이다.
또한 ref interaction operator 를 사용하면, 로직 전체를 추상화하여 표기할 수 있다.
이 그림을 보면 showMessage 영역에 해당하는 로직은 ref 로 표기하여 로직을 추상화하여 그렸다.
showMessage 의 실제 로직은 별도의 시퀀스 다이어그램으로 그린다.
ref 는 일종의 함수와 같은 존재로, 다른 시퀀스 다이어그램에서도 재사용할 수 있다.
또한 ref 로 추상화한 시퀀스 다이어그램 안에서 재사용 가능한 메서드 호출을 정의하여 시퀀스 외부에서 해당 메서드를 호출하도록 할 수도 있다.
이렇게 다이어그램을 그리면 이 다이어그램을 ref 한 모든 액터, 오브젝트에서 getAllMenuName 이라는 메서드를 호출할 수 있다.
이번에는 가로로 길어지는 시퀀스 다이어그램을 추상화해보자.
가로로 길어지는 시퀀스 다이어그램은 오브젝트가 너무 많아서 발생한 경우이다.
이때는 오브젝트들을 하나의 그룹으로 묶어서 하나의 그룹 오브젝트로 표현할 수 있다.
이 그림을 보면 MenuOptions 라는 다이어그램을 참조하여 만든 MenuOptions 라는 사용자 정의 타입을 보여준다.
이 사용자 정의 타입에는 getAllOptionNames 라는 메서드가 있고
이 메서드를 호출하여 기능을 수행함으로써 원본 시퀀스 다이어그램에서 Menu, Option 이라는 오브젝트를 표현할 필요가 없어졌다.
(지금 그림에서는 Menu 가 이미 존재하기는 하지만, 이런 식으로 여러개의 오브젝트를 하나의 오브젝트의 동작으로 추상화할 수 있다는 느낌만 이해)
지금까지 시퀀스 다이어그램의 내용을 모두 정리하였다.
마지막으로 시퀀스 다이어그램과 커뮤니케이션 다이어그램을 비교해보자.
커뮤니케이션 다이어그램은 시퀀스 다이어그램과 동일한 정보를 나타내므로, 서로 대신하여 쓰일 수 있다.
커뮤니케이션 다이어그램은 각 오브젝트 간 관계를 나타내는 link 만을 나타내며, 별도의 '시간' 개념은 없다.
(대신 상호작용의 순서는 번호로 나타내며, 재귀 호출은 1.1 과 같이 . 으로 구분한 번호로 표현한다.)
또한 이렇게 그림을 다 그렸다면, 이 그림이 올바른지 model consistency 를 확인해야 한다.
지금까지 커뮤니케이션 다이어그램, 또는 시퀀스 다이어그램을 그렸다면, 이로부터 클래스 다이어그램이 나올 것이다.
이때 커뮤니케이션 다이어그램에서는 getName 함수가 menu 오브젝트에 있었는데, 클래스 다이어그램의 Menu 클래스에 getName 메서드가 정의되어있지 않다면 consistency 가 일치하지 않으니 수정해야 한다.
또 메서드 이름이 같더라도, 메서드의 시그니처(매개변수 개수, 이름, 타입 등)가 다르면 역시 consistency 가 일치하지 않으니 수정해야 한다.
다음으로 메세지를 보내는 오브젝트에서 메세지를 받는 오브젝트에 대한 레퍼런스를 갖고 있는지도 체크해야 한다.
Menu 클래스에 getName 메서드는 올바르게 정의했는데, 이를 호출하는 Restaurant 클래스에서 Menu 오브젝트에 대한 레퍼런스를 갖고 있지 않다면 역시 말이 안될 것이다.
그래서 멤버 변수로 받거나, 메서드 파라미터를 통해 전달받아 레퍼런스를 꼭 보유하도록 만들어야 한다.
(레퍼런스를 어디로 전달받을지 pathway 도 신중하게 고민해야 한다.)
'CS > 소프트웨어공학' 카테고리의 다른 글
[소프트웨어공학] 15. Detailed Design (2) | 2025.06.05 |
---|---|
[소프트웨어공학] 13. Requirement Analysis (4) | 2025.06.03 |
[소프트웨어공학] 12. Configuration and Version Management (0) | 2025.04.21 |
[소프트웨어공학] 11. Use Case Diagram (1) | 2025.04.21 |
[소프트웨어공학] 10. Requirement Capture (0) | 2025.04.20 |