// education

기능 모델링

기능 관점에서 시스템을 본다는 것

6장에서 소프트웨어 시스템을 기능·동적·정보 세 관점으로 나눠 본다고 했다. 이번 장은 그 첫 번째, 기능 관점을 다룬다.

기능 관점은 시스템을 하나의 변환기로 본다. 무언가가 들어오면(입력) 시스템 내부에서 어떤 가공을 거쳐 다른 무언가가 나간다(출력). 책마루 온라인 주문 시스템으로 보면, "손님이 담은 장바구니"가 들어와서 "포장 지시서와 결제 영수증"이 나가는 하나의 큰 변환 과정이다. 기능 관점이 다루는 건 이 변환의 논리 그 자체다 — 어떤 계산과 어떤 제약조건을 거쳐 입력이 출력으로 바뀌는가. 반대로 이 변환이 정확히 언제 일어나는지, 어떤 순서로 실행되는지는 기능 관점의 관심사가 아니다. 그건 8장에서 다룰 동적 관점의 몫이다.

이 기능 관점을 그림으로 표현하는 대표적인 방법이 **구조적 분석기법(Structured Analysis)**이다. 요구사항 분석 도구 중 지금까지도 가장 널리 쓰이는 기법이며, 이 장 전체가 이 기법 하나를 다루는 데 할애된다.

구조적 분석기법 — 하향식으로 쪼개나간다

구조적 분석기법의 핵심 아이디어는 단순하다. 시스템 전체를 "정보를 받아 가공해 내보내는 하나의 큰 프로세스"로 놓고, 그 프로세스를 점점 더 작은 세부 프로세스로 쪼개나간다. 이 방식을 하향식(top-down) 분할이라 부른다.

하향식 분할과 계층화

책마루 온라인 주문 시스템을 통째로 "온라인 주문을 처리한다"는 프로세스 하나로 보면 너무 크다. 이걸 "주문을 접수한다", "재고를 확인한다", "결제를 처리한다", "배송을 처리한다"는 네 개의 하위 프로세스로 쪼갤 수 있다. "재고를 확인한다"는 또 "매장 재고를 조회한다", "품절 여부를 판정한다"로 더 쪼갤 수 있다. 이렇게 쪼개나가다 보면 더는 나눌 필요가 없을 만큼 단순한 프로세스에 도달하는데, 이를 **원시 프로세스(functional primitive)**라 부른다.

이렇게 상위 프로세스와 하위 프로세스 사이에 종속 관계를 두어 단계별로 배열하는 것을 **계층화(leveling)**라 한다. 계층화를 하는 이유는 단순하다 — 큰 시스템을 한 장의 그림에 다 담으면 아무도 읽을 수 없다. 회사 조직도가 "대표 → 본부 → 팀"으로 나뉘어야 이해하기 쉬운 것과 같은 이치다. 구조적 분석기법의 결과물은 이렇게 계층적으로 나뉜 도표들과, 더는 쪼개지지 않는 말단 프로세스들의 상세 설명, 그리고 그 사이를 오가는 데이터에 대한 정의로 구성된다.

자료흐름도(DFD)의 네 가지 기호

구조적 분석기법이 그림으로 정보의 흐름과 변환을 표현할 때 쓰는 도구가 **자료흐름도(Data Flow Diagram, DFD)**다. 자료흐름도는 딱 네 가지 기호만으로 이루어진다.

기호 이름 의미
사각형 외부 객체 시스템 밖에서 정보를 주고받는 대상. 책마루라면 손님, 매장 직원, 결제대행사, 택배사
프로세스 정보를 처리하고 변환하는 작업 단위. "재고를 확인한다"처럼 동사구로 이름 붙인다
화살표 자료 흐름 데이터가 흐르는 방향과 그 데이터의 이름
열린 사각형(두 줄) 자료 저장소 오래 보관되는 데이터. 책마루라면 상품 재고 DB, 주문 이력 DB

이 네 가지만으로 "정보가 어디서 시작해 어떻게 가공되고 어디로 가는지"를 도식화할 수 있다. 예를 들어 "손님(외부 객체)이 낸 주문 정보(자료 흐름)가 주문 접수 프로세스(프로세스)에 들어가고, 재고 DB(자료 저장소)의 재고 정보와 결합해 포장 지시서(자료 흐름)가 되어 매장 직원(외부 객체)에게 전달된다"는 식으로 하나의 흐름을 그릴 수 있다.

배경도 — 시스템을 블랙박스로 그리기

계층화된 자료흐름도의 맨 위, 즉 시스템 전체를 아직 쪼개지 않은 채 프로세스 하나로 그린 그림을 **배경도(Context Diagram)**라 부른다. 배경도는 시스템을 하나의 블랙박스로 취급하고, 그 블랙박스가 외부 세계와 어떤 정보를 주고받는지에만 집중한다.

책마루 온라인 주문 시스템의 배경도를 그려보면 이런 모습이 된다.

배경도가 하는 일은 두 가지다. 첫째, "우리가 만들어야 할 시스템의 경계가 정확히 어디까지인가"를 확정한다. 매장 POS 시스템 자체는 배경도 밖에 있는 별개의 대상이고, 우리는 그것과 정보를 주고받는 관계만 신경 쓰면 된다는 걸 이 그림 하나로 확인할 수 있다. 둘째, 시스템의 입출력 데이터 전체를 한눈에 보여준다. 배경도가 완성되어야 비로소 "이 블랙박스 안을 어떻게 채울 것인가"라는 다음 단계로 넘어갈 수 있다.

프로세스를 쪼개나가기 — 레벨화와 프로세스 번호

배경도의 프로세스 하나를 쪼개면 그다음 단계의 자료흐름도가 나온다. 이걸 레벨 1 자료흐름도라 부른다. 책마루 배경도의 "책마루 온라인 주문 처리"는 이렇게 쪼갤 수 있다.

  1. 주문 접수
  2. 재고 확인
  3. 결제 처리
  4. 배송 처리

이 네 프로세스는 각각 번호를 갖는데, 이 번호 부여 방식에는 규칙이 있다. 배경도의 최상위 프로세스는 번호 0을 갖는다. 그 프로세스를 쪼갠 자료흐름도(레벨 1)의 네 프로세스는 1, 2, 3, 4번을 갖는다. 만약 "2. 재고 확인"을 더 쪼개 "2.1 매장 재고 조회", "2.2 품절 여부 판정"으로 나눈다면, 이 하위 프로세스들이 그려진 자료흐름도는 "다이어그램 2"가 되고 프로세스 번호도 2.1, 2.2를 갖는다. 이렇게 번호 체계만 봐도 어떤 프로세스가 어떤 프로세스의 하위인지 바로 알 수 있다.

레벨 1 자료흐름도로 본 책마루

배경도 하나만 봐서는 시스템 내부가 어떻게 돌아가는지 알 수 없다. 레벨 1 자료흐름도에서 비로소 "책마루 온라인 주문 처리"라는 블랙박스 안이 열린다. 앞서 나눈 네 프로세스를 입출력과 함께 정리하면 이런 표가 된다.

번호 프로세스 주요 입력 주요 출력
1 주문 접수 주문정보(손님) 접수된_주문
2 재고 확인 접수된_주문, 재고_수량(자료 저장소) 재고_확인_결과
3 결제 처리 재고_확인_결과, 결제수단 결제_승인_결과
4 배송 처리 결제_승인_결과 포장_지시서(직원), 배송_요청(택배사)

이 표를 보면 "2. 재고 확인"이 "재고_수량"이라는 자료 저장소를 직접 들여다본다는 걸 알 수 있다. 매장 POS에서 판매가 일어날 때도 이 같은 저장소를 갱신해야 온라인 재고와 매장 재고가 어긋나지 않는다 — 이 저장소 하나를 두고 매장 판매와 온라인 주문이 동시에 접근하는 지점은 나중에 설계 단계에서 동시성 문제로 다시 등장할 소지가 크다. 지금 단계에서는 "이 자료 저장소가 두 경로에서 동시에 쓰인다"는 사실을 자료흐름도에 명시적으로 남겨두는 것만으로 충분하다. 문제를 어떻게 풀지는 아직 설계의 몫이다.

원시 프로세스와 미니 명세서

프로세스를 어디까지 쪼갤지는 분석가의 판단에 달려 있다. 일반적인 기준은 "하나의 프로세스가 하나의 명확한 기능만 수행할 정도로 충분히 작아졌는가"이다. 더는 쪼갤 필요가 없는 지점에 도달한 프로세스를 원시 프로세스라 부르고, 이 원시 프로세스의 상세한 동작을 텍스트로 기록한 문서를 **미니 명세서(프로세스 명세서)**라 한다.

예를 들어 "2.2 품절 여부 판정"이 원시 프로세스라면, 그 미니 명세서는 이런 식이다.

번호: 2.2
이름: 품절 여부 판정
입력: 매장_재고_수량
출력: 품절_여부

본문:
  IF 매장_재고_수량 <= 0 THEN
    품절_여부 = TRUE
    상품_상태를 "품절"로 갱신
  ELSE
    품절_여부 = FALSE
  END IF

미니 명세서의 번호는 그 프로세스의 번호와 항상 일치한다. 그래서 완성된 미니 명세서의 개수는 곧 원시 프로세스의 개수와 같아진다. 보통 미니 명세서 하나는 한 페이지를 넘지 않을 정도로 간결하게 쓰는 게 좋다 — 그래야 다음 단계인 설계·구현에서 실제로 참고할 만한 문서가 된다.

자료흐름도의 균형

계층화된 자료흐름도를 그릴 때 반드시 지켜야 할 제약이 하나 있다. 상위(부모) 자료흐름도의 입출력은 하위(자녀) 자료흐름도의 입출력과 정확히 일치해야 한다. 이를 **균형(balancing)**이라 부른다.

책마루 배경도에서 "책마루 온라인 주문 처리" 프로세스가 손님으로부터 "주문 정보"를 받는다면, 이 프로세스를 쪼갠 레벨 1 자료흐름도에서도 "주문 정보"라는 같은 이름의 데이터가 어딘가(이 경우 "1. 주문 접수" 프로세스)로 들어가야 한다. 상위 레벨에서 갑자기 없던 입력이 하위 레벨에 나타나거나, 반대로 상위 레벨의 입력이 하위 레벨 어디에도 안 보이면 균형이 깨진 것이고, 이는 정보 흐름이 끊겼다는 신호다.

균형을 지키면서도 상위 레벨에서는 여러 개의 세부 데이터를 하나로 묶어 표시하고, 하위 레벨로 내려가면서 쪼개 보여주는 방식은 자료흐름도를 읽기 쉽게 만드는 요령이다. 예를 들어 배경도에서는 "주문 정보" 하나로 뭉뚱그려 표시하고, 레벨 1에서는 "상품 목록", "배송지", "결제 수단"으로 쪼개 보여주는 식이다. 이렇게 묶고 쪼개는 방식에 대한 세부 정보는 다음에 설명할 자료사전에 정의해둔다.

자료사전 — 데이터에 대한 데이터

자료흐름도는 시각적인 그림이라 직관적이지만, "주문 정보"가 정확히 어떤 항목들로 구성되는지까지는 그림만으로 담을 수 없다. 이걸 체계적으로 기록해두는 문서가 **자료사전(Data Dictionary)**이다. 자료사전은 데이터에 대한 데이터, 즉 메타데이터를 모아놓은 저장소다.

자료사전은 몇 가지 간단한 연산자로 데이터 구성을 표현한다.

연산자 의미
= 주문정보 = 상품목록 + 배송지 + 결제수단 주문정보는 세 항목으로 구성된다
+ 상품목록 + 배송지 두 항목의 결합(AND)
[ | ] [ 카드결제 | 계좌이체 ] 둘 중 하나 선택(OR)
{ } 또는 반복 표시 1 { 상품항목 } 20 상품항목을 1~20번 반복
( ) ( 배송_메모 ) 있어도 되고 없어도 되는 선택적 항목

책마루의 "주문정보"를 자료사전에 정의하면 이런 식이 된다.

주문정보 = 손님_ID + 1{상품_항목}20 + 배송지 + 결제수단 + (배송_메모)
결제수단 = [ "카드" | "간편결제" | "계좌이체" ]

이렇게 정의해두면 개발자가 "주문정보에 배송 메모가 항상 있어야 하는가"를 자료흐름도 그림만 보고 추측할 필요 없이 자료사전에서 바로 확인할 수 있다.

분할의 기준: 결합도와 독립성

시스템을 어떻게 쪼갤 것인가에는 정답이 없다. 다만 좋은 분할이 지향하는 목표는 있다 — 각 프로세스가 독립적으로 이해되고 수정될 수 있도록, 프로세스 내부의 응집도는 높이고 프로세스 사이의 결합은 최소화하는 것이다. 책마루 예로 보면 "결제 처리"와 "배송 처리"를 하나의 프로세스로 뭉쳐놓으면, 배송 방식만 바꾸려 해도 결제 로직까지 함께 들여다봐야 하는 상황이 생긴다. 반대로 너무 잘게 쪼개면 프로세스 사이를 오가는 자료 흐름이 지나치게 많아져 오히려 전체 그림이 복잡해진다. 이 균형점을 찾는 감각은 업무 분야에 대한 이해가 있어야 잡히는데, 그래서 모델링은 시스템을 만들 분야의 전문 지식을 가진 사람이 주도하는 게 이상적이다.

핵심 정리

다음 장(8장 동적 모델링)에서는 이번 장에서 정지 화면처럼 다뤘던 책마루의 주문 처리 과정에 시간의 흐름을 더한다. 주문이 접수부터 배달 완료까지 어떤 상태를 거치고, 어떤 사건이 그 상태 변화를 일으키는지를 상태변화도로 그려본다.

← 이전요구사항 분석과 모델링 다음 →동적 모델링