본문 바로가기

Programming/Architecture

02 Activity Diagram


Activity Diagram부터는 슬슬 프로그래밍적 접근이 나오게 되요. 물론, 유즈케이스(Usecase)다이어그램이 그렇지 않다는 것은 아니구요:D
Activity라는 거는 일이라고 보면 되요. 일 처리 하는 플로어 챠트~ 순서도죠. 제가 중학교때에도 얼핏 본거 같은 순서도는 아니네요 :)


예제는 바로 전 포스팅(01 Usecase Diagram)에서 만들었던 것을 가지고 진행 할거에요:)
(제가 두 번 작업 하는 일을 안하기 위해서…ㄱ-ㅋㅋㅋ)
  • 다이어그램(Diagram)의 종류 별 사용
    • 액티비티 다이어그램(Activity Diagram)

      사용되는 요소 보기
      StartUML을 기본값으로 시작 하게 되면, 다이어그램 별로 스테레오타입을 붙여서 분류 하더 라구요. 저는 단순히 (실제로 구현이 되는) 프로젝트 단위로 구별하려고 다이어그램은 한곳으로 몰아넣었어요 :D


      가장 처음은 다이어그램을 만드는 것 부터 시작이겠죠?
      나중에 더욱 자세히 설명 할 테지만, 우리가 그전에 유즈케이스를 만들 었잖아요? 그런 요소들이 가지고 있는 자체의 처리 과정에 대해서도 별도의 다이어그램들을 만들 수 있어요. 그럼 해당 다이어그램은 해당 유즈케이스에 포함 되는거죠 :)

      물론, 전에 만들었던게 유즈케이스이기 때문에 그거만 가지고 설명 했지만, 클래스나 다른 요소들에 대해서도 별도의 다이어그램을 만들 수 있답니다.

      일단은 EngineCore_TestUI 프로젝트가 가지고 있는 아주 큰 흐름도 부터 만드려고 해요.
      1. 모델 탐색기에서 액티비티 다이어그램 생성을 원하는 요소(모델, 서브시스템, 패키지 외 다른 객체 요소들)에서 마우스 우클릭 한다.
      2. Add Diagram에 마우스를 올려 놓는다.
      3. 액티비티 다이어그램(Activity Diagram)을 마우스 좌클릭한다.


      이름은 "전체적인 Activity Diagram" 이라고 해뒀어요 :)

      이 다이어그램은 흐름도에요. 그 말인즉, 처음과 끝을 알려 줘야 어떻게 흘러가는지를 알 수가 있다는 거죠. 일단, 시작과 끝을 넣어 볼까요?

      요소 선택과 생성은 이전 포스팅에서 열심히 했으니까 대부분생략 할게요 :) 결과만 보여주는 센스를 발휘 할 거에요 >_<ㅋ


      시작 요소는 InitialState(초기화 상태), 종료 요소는 FinalState(종료 상태) 에요.

      생성 한 후에는 이름을 바꿔 볼게요. 전체 프로그램의 흐름에 대한 거니까 시작점은 "프로그램 구동", 종료점은 "프로그램 종료"로 바꿔 볼게요.
      1. 생성되었던 시작점(InitalState)을 마우스 좌클릭 한다.
      2. 속성창(Properties)에서 이름(Name)부분을 마우스 좌클릭 한다.
      3. 이름을 변경 후 엔터를 입력 하거나 아무곳이나 클릭 한다.


      이렇게 요소의 이름을 바꿨어요:)


      EngineCore_TestUI는 프로그램이 구동되면, 다양한 초기 옵션을 불러온답니다. 물론 현재는 코딩으로 그러한 세팅이 되게끔 해 두었지만, 추후에 파일로 부터 불러올 것을 생각해서 불러온다는 개념으로 구현 해 두었어요.

      그럼 프로그램 구동 후 "EngineCore 옵션 로드" 후 "불러온 값에 의해서 설정" 하는 행동이 있겠죠? 일반적인 행동 상태이므로 이 부분은 ActionState를 사용하면 되요.

      저는 조금 디테일 하게 나누었지만, 옵션 불러오기 & 설정하기 를 하나의 ActionState로 두어도 괜찮을거 같아요 :) 취향존중!ㅋ


      프로그램 구동부터 여태까지만 흐름을 이어 보도록 해요. 아직 종료 된 것은 아니니까, 설정까지만 이어 갈게요.
      1. 상태 이전(Transition)을 마우스 좌클릭 한다.
      2. "프로그램 구동"으로 부터 "초기 옵션 불러오기"까지 마우스를 드래그 한다.


      짜잔~ 이제 슬슬 모양새가 잡혀 가네요 :D


      "초기 옵션 불러오기" 부터 "불러온 값 설정"까지는 직접 해보세요 :)

      이제 윈도우 프로그램 특성상 메인 루프가 돌아가게 되요. 메인 루프는 하나의 거대한 "일" 즉, Activity이니까 서브로 집어 넣을 게요.


      설정이 끝나면, 윈도우 메인 루프를 돌게 되있 으므로 설정->메인루프로 Transition을 시켜줘야 겠죠? 그리고 메인루프 자체가 종료되면, 프로그램 자체의 종료를 의미하므로 메인루프 -> 프로그램 종료로 Transition 시켜 주구요:)


      앞선 요소와 크기가 다르죠? 제가 직접 조절 할 수도 있지만, 여기서는 위에 AutoResize를 시켜 줬어요.

      AutoResize가 활성화 되면, 내부에 들어가 있는 내용에 따라서 요소의 크기가 자동으로 변한답니다.


      현재 있는 요소에 다이어그램이 링크 되는 방법을 모르기 때문에;; 일단은 그냥 만들어 거에요 :)
      "윈도우 메인루프" 라는 하위 엑티비티의 경우에는 내부적으로 다른 일들을 해야 해요. 여기서, 이전 유즈케이스에 입력 했던 내용들이 들어 갈거에요.

      1. 기존에 만들었던 ActivityDiagram의 상위 요소인 ActivityGraph1을 마우스 우클릭 한다.
      2. Add diagram에 마우스를 올려 놓는다.
      3. Activity Diagram을 마우스 좌클릭 한다.
      4. 생성된 Activity Diagram의 이름을 변경 한다.

      그럼 새로운 다이어 그램의 화면이 만들어 진 게 보이게 되요. 전 이름을 바꿨답니다:)


      그럼 윈도우 메인루프 내부에서 돌게 되는 순서도를 그려볼까요? 시작과 끝은 동일 해요. 하지만 이름은 달라야 하겠죠. 이전에 만들었던건 프로그램의 구동과 프로그램의 종료지만, 이건 단순히 윈도우 메인 루프 내에서만 처리되는 부분이니까요 :)


      윈도우 메인루프는 신호가 들어오던, 아니던 항상 이벤트에 대한 처리를 하게 되요. 보통 이 이벤트라는게, 해당 윈도우에 대한 임의의 신호(윈도우 창 상태가 바뀌었다든지, 키 입력, 마우스 입력, 등등등)에 대한 것들인데, 일단은 키 입력에 대한 부분만 구현 했어요.

      그럼 현재 일을 하는 아이, 즉 윈도우(현재 윈도우 메인루프 라는 하위 엑티비티 상태(SubactivityState)), 가 이벤트를 받는 거겠죠? 신호를 받을 때는 Signal Accept State 요소를 사용 해요. 이름은 "윈도우 이벤트 수신" 이라고 할게요.


      그리고 이 신호는 시작으로 부터 이어지는 거니까, Transition을 시켜 줄게요.


      이제 윈도우 이벤트가 어떤 것이냐에 따라서 처리를 달리 하게 되므로 분기(Decision)요소를 넣어야 할거에요. 분기문의 이름은 "이벤트 종류" 로~!


      그럼 크게 이벤트의 종류를 아래와 같이 적어 볼게요.
      1. 이벤트 미 발생
      2. 키보드 & 마우스 입력
      3. 윈도우 창 크기 변경
      4. 윈도우 종료

      아무런 이벤트가 발생하지 않은 것도 이벤트가 발생한 거라고 생각하면 되요(응?) 아무런 처리가 발생 하지 않은 거라도 현재 순서도는 종료되고 다시 또 시작되거든요. 루프라서… :)

      그래서 아무런 처리가 발생하지 않게 되면, 다시 윈도우 이벤트를 수신하러 되돌아 가면 되는 거에요. Transition을 이벤트 종류 분기에서 이벤트 수신 쪽으로 이어 주면 됩니다. 그렇게 되면 마치, 양방향이 된 거 처럼 보이게 될거에요.


      알아 보기도 힘들 뿐더러, "이벤트 미 발생" 이라는 문구도 적어야 하는데 어느쪽 화살표에 대한 문구인지 모호해 지잖아요? 같은 요소이면 가장 마지막에 만들어진 요소가 위쪽으로 올라가져 있게 되요.
      말인 즉슨, 해당 화살표를 클릭 했을 때, 마지막에 만들었던(분기점으로부터 수신으로 가는) 화살표가 선택 되요.


      이 상태에서 상단의 화살표 모양을 클릭 하면 메뉴가 나오는데, 여기서 위쪽의 Rectlinear를 클릭 하면 화살표 모양이 바뀌게 되요.


      그렇게 많이 달라지지 않았지만, 그래도 나눠진 것은 보일 거에요:)


      StarUML은 선분정리를 사용자가 신경을 많이 써야 되도록 만들어 져 있는 부분이 좀 맘에 안들기는 하지만, 그래도 무료 중에 제일 범용성이 있으니까….ㄱ- 군말 말고 써야죠…:)

      위 처럼 되어 있는 상태에서 분기점 요소를 선택해서 우측으로 이동해 볼까요?


      오오.. 화살표의 모양이 보이기 시작 했어요. 여기서 화살표를 선택하면 출발/도착/꺽인선에 사각형모양의 점이 찍힌걸 볼 수 있는데, 이 각 점을 드래그 해서 모양을 바꿔 볼 수 있어요. 이부분은 직접 실습!


      적당한 모양새를 갖추었으니까 화살표에 이름을 주어야 겠죠? 이름은 화살표를 더블클릭 하게 되면, 이름을 적을 수 있는 작은 창이 하나 뜨게 되는데, 거기서 입력을 하거나, 우측의 속성창(Properties)의 Name부분을 수정 하면 입력 된답니다.


      자아.. 이름도 나머지 부분도 입력 해 볼까요?


      2, 3은 특정한 Action이 되는 거니까 각각 ActionState로 만들면 될 거 같아요. 그리고 이벤트의 종류가 "윈도우 종료" 라면 바로 끝나는 쪽으로 가면 되겠죠?

      정리는 나중에 하고 일단 만들어서 이름을 입력 한 후에, 해볼 게요.


      으악.. 지저분 해라 ㅠㅠㅋ 요걸 아까 알려준 방법을 짬뽕하면..


      이해를 돕기 위해 최대한 깔끔하게 만들어 보았어요 :)
      장치 입력과 윈도우 창 크기 변경 이벤트가 일어나면 오픈지엘에게 해당 정보를 넘겨 줘야 합니다. 이 부분은 처리 되는 영역이 다르므로 Swimlane를 넣어 줄게요. 일 처리를 하는 영역을 구획화 해서 보기 좋게 하려는 목적이에요. 가로축과 세로축은 자신이 현재 만들고 있는 다이어그램의 모양새에 맞게 해주면 되구요 :)

      원하는 크기 만큼 드래그 해서 만들면 되요. 이름은 "윈도우"로 했어요.


      자료를 넘겨서 처리하는 부분은 오픈지엘에서 하게 되는 거니까, 오픈지엘 한테 자료를 넘겨 줘야 겠죠? :) 그 전에 영역을 분할 해야 되니까 옆쪽으로 오픈지엘 하나를 더 만들어 볼게요.


      윈도우 창 크기가 변경되면, 오픈지엘(구현된 내용은 Display 라는 클래스;;;)에게 변경된 창 크기를 알려 주어야 해요.
      이는 오브젝트 까지는 아니므로 "값"을 Transition만 시키는 Signal Accept State를 넣고,
      그렇게 받은 값은 오픈지엘한테는 특정한 행동(일)이니까, ActionState를 넣되 이름은 "Display 화면 크기 변경" 이라고 하면 될 거 같아요.
      오픈 지엘이 자신의 일을 마친 거니까, 이벤트 수신 상태로 다시 돌아가면 끝~


      (현재 구현 상태에서는 만들지 않았지만, 추후에 만들 내용으로 장치 입력에 대한 부분을 얘기하자면) 키보드와 마우스 입력은 키 매핑에 대한 클래스를 별도로 만들어서 넘길 거에요. 동시 입력 이라던지, FPS류 게임에서 달리면서 총을 쏜 다 던지 하는 방식을 사용 하려면 필요 할 거 같더라구요 :)
      클래스는 하나의 Object 즉, 객체를 의미 하는 것이고 그 Object가 전달이 되야 하는 것이 므로 Object Flow를 사용 하면 되요.


      StarUML의 ObjectFlow는 넘어가는 오브젝트 자체까지도 표시하도록 되어 있더 라구요. 구글링과 몇몇 서적을 찾아 봤을 때는 그냥 점선으로 "이 구간은 임의의 객체가 넘어갑니다" 라고 퉁 치기도 하던데요, 작성자와 그걸 보는 사람간의 약속으로 정하기도 하는 거 같아요:D


      이로써 윈도우 메인 루프는 완성 했어요. 어디까지나 대략적인 (날로 먹는걸 얘기하는건 아니에요 :D) 스케치를 하는 게 현재까지의 진행 이니까 간단하게 끝난 거에요 :)

      요소 중 SelfTransition을 설명해야 할거 같아요. 윈도우 메인루프 작성시 맨 위로 올라가 보면, 취향에 따라 이벤트가 없는 경우는 이벤트 수신이 될 때까지 대기하는 모습으로 표현 할 수도 있어요.(저는 분기에서 해뒀지만..ㅋ)

      이때는 SelfTransition으로 살짝 바꿔주변 된답니다. 물론, 제가 작성한 내용을 따라오신 분이라면 분기점에서 이벤트 미 발생의 경우를 지워야 겠죠? :)

      선분을 만드는 거라 드래그 하는 거라고 생각 할 수도 있는데, 자기 자신이 자기 자신으로 되돌아 오는 거니까, SelfTransition 선택 후 원하는 요소 클릭 하는 걸로 끝나요 :)
      1. SelfTransition을 마우스 좌 클릭 한다.
      2. 원하는 요소(여기서는 "윈도우 이벤트 수신")를 클릭 한다.


      그럼 자기 자신으로 들어가는 선분이 생기게 되요.


      선 정리는 스스로~ 이름도 넣어 주는 편이 가독성에 좋겠죠?


      Flow Final은 시스템이 정지 할 때를 의미 한다고 하는데, 여기서는 오류가 나더라도 시스템이 정지하는 경우가 없기 때문에 사용 되지는 않네요 :)

      Synchronization(동기화)는 포크(folk)나 조인(join)의 경우에 사용 하는데, 분기는 반드시 순서가 상관이 있을 때 사용 하는 거고, 별다르게 순서에 관계없이 한 꺼번에 일이 진행 되야 하거나 두 개이상의 일이 모두 완료 되었을 때에만 진행 되는 상황을 의미 해요.

      위의 두 개는 현재 까지의 예시 말고 별도의 예시를 들어 볼게요.

      그냥 대충 만들어 본거에요 ;_;

      많이들 사용하는 예시 중 비디오 대여 시스템~ 비디오를 대여할 때, 고르는 거랑 회원인지 아닌지 확인하는 거랑 따로 해도 상관 없잖아요~? (사실 뭐.. 구지 굉장히 절차지향적으로 치자면, 다 빌리기 전까진 확인을 하지 않는다로도 할 수 있지만)

      그래서 동시에 일이 진행 되는 거로 설정 했어요. 비디오를 고르는 거 자체 에서는 내가 보고 싶은 비디오가 없다면, 이미 "비디오를 대여한다" 라는 일을 진행 할 수 없으므로 시스템의 종료를 의미 하게 되죠.

      회원의 자격으로 결재를 진행 했고, 비디오를 고르는 일 자체가 둘 다 만족하게 되면, "비디오를 대여한다" 라는 일이 끝나게 되는 거죠.

휴우… 이렇게 또 하나의 다이어그램을 끝내는 군요~! 다음은 프로그램의 구현과 직결되는 다이어그램인 클래스 다이어그램을 해볼 게요 :)

'Programming > Architecture' 카테고리의 다른 글

04 Statechart Diagram  (2) 2012.07.10
03 Class Diagram 2  (6) 2012.05.30
03 Class Diagram 1  (0) 2012.05.26
01 UseCase Diagram  (3) 2012.04.29
StarUML 툴 구조  (0) 2012.04.27