설계의 마지막 두 조각
12장에서 모듈 구조를 어떻게 나눌지, 13장에서 자료 흐름과 데이터를 어떻게 배치할지, 14장에서 반복되는 설계 문제를 어떻게 재사용 가능한 형태로 풀지를 다뤘다. 이 장은 Part 4 "소프트웨어 설계"의 마지막 장으로, 남은 두 조각을 다룬다. 하나는 사용자 인터페이스 설계 — 손님과 직원이 실제로 마주하는 화면을 어떻게 만들 것인가. 다른 하나는 상세설계 — 지금까지 "이 모듈이 무슨 일을 하는가"까지만 정했던 것을, 실제 코드로 옮기기 직전의 구체적인 절차로 문서화하는 작업이다.
사용자 인터페이스가 설계의 일부인 이유
인터페이스 설계를 "화면 디자인" 정도로 가볍게 여기기 쉽지만, 소프트웨어 공학에서는 인터페이스도 12장에서 다룬 네 가지 설계 활동 중 하나로 명시적으로 다룬다. 이유는 단순하다 — 아무리 내부 로직이 견고해도, 인터페이스가 사용자의 사고방식과 어긋나면 그 시스템은 현장에서 쓰이지 않기 때문이다(1장에서 언급한 "매장 직원의 요구를 놓치면 시스템은 완성돼도 안 쓰인다"는 상황이 바로 이것이다).
인터페이스 설계는 **인간-컴퓨터 상호작용(HCI, Human-Computer Interaction)**이라는 분야의 지식을 끌어온다. 핵심은 사람이 정보를 처리하는 방식 — 단기 기억의 한계, 반복 작업에서의 실수 확률, 낯선 화면 앞에서 느끼는 불안 — 을 고려해 화면을 설계해야 한다는 것이다. 책마루의 두 사용자 집단은 이 점에서 요구가 크게 다르다. 손님은 시스템을 어쩌다 한 번, 그것도 스마트폰 화면이라는 제한된 공간에서 쓰는 비전문가다. 반면 매장 직원은 같은 화면을 하루에도 수십 번 반복해서 쓰는 준전문가다. 좋은 인터페이스 설계는 이 두 집단에게 각각 다른 인터페이스 스타일을 선택하는 데서 시작한다.
인터페이스 스타일 네 가지
사용자와 시스템이 대화하는 방식은 몇 가지 정형화된 스타일로 분류된다.
- 명령어 언어(command language): 사용자가 정해진 문법의 명령을 직접 입력하는 방식. 숙련되면 가장 빠르지만 배우는 데 시간이 걸린다. 책마루라면 매장 직원이 재고 시스템에
재고조회 B001처럼 짧은 명령을 입력해 즉시 조회하는 관리자 콘솔이 여기 해당할 수 있다 — 매일 반복 사용하는 숙련자에게는 클릭 여러 번보다 빠르다. - 메뉴 방식(menu-driven): 선택지를 화면에 나열하고 그중 하나를 고르게 하는 방식. 배우기 쉽지만 선택지가 많아지면 화면을 이동하는 부담이 커진다. 전체 화면 메뉴, 드롭다운 메뉴, 팝업 메뉴, 버튼·라디오·체크박스 등 세부 형태가 다양하다. 책마루의 고객용 주문 화면 — 카테고리를 눌러 상품을 고르고, 배송 방법을 라디오 버튼으로 선택하는 — 이 전형적인 메뉴 방식이다.
- 양식 채움(form fill-in): 정해진 항목마다 값을 입력하게 하는 방식. 여러 항목을 한 번에 정확히 입력해야 하는 작업에 적합하다. 책마루의 관리자용 "신규 상품 등록" 화면(상품명, 가격, 초기 재고 수량, 카테고리를 각각 입력)이 여기 해당한다.
- 자연어(natural language): 사용자가 일상 언어로 요청하면 시스템이 해석해 처리하는 방식. 가장 자유롭지만 구현 난이도가 높고 오해석 위험이 있어, 책마루 규모의 시스템에서는 챗봇 상담처럼 제한된 영역에만 적용하는 것이 현실적이다.
같은 시스템 안에서도 사용자 집단에 따라 스타일을 다르게 조합할 수 있다. 손님용 주문 화면은 메뉴 방식과 양식 채움을 섞어 쓰고(상품은 메뉴로 고르고, 배송지는 양식으로 입력), 직원용 재고 관리 화면은 반복 작업의 효율을 위해 명령어 언어를 일부 도입하는 식이다.
인터페이스 설계의 원칙
인터페이스 스타일을 정했다면, 그 안에서 지켜야 할 설계 원칙들이 있다. 책마루 화면에 적용해 보면 이렇다.
| 원칙 | 의미 | 책마루 적용 예 |
|---|---|---|
| 일관성 | 같은 동작에는 같은 표현을 쓴다 | "장바구니에 담기"와 "재입고 알림 받기" 버튼의 색상·위치 규칙을 통일 |
| 피드백 | 사용자의 모든 조작에 시스템이 즉시 반응을 보여준다 | 재고가 0이 되면 화면에 즉시 "품절" 표시가 뜨도록 함 |
| 되돌릴 수 있는 작업으로 설계 | 실수해도 취소할 수 있게 한다 | 장바구니에서 상품을 잘못 담아도 결제 전까지는 자유롭게 뺄 수 있음 |
| 파괴적 작업은 확인받기 | 되돌리기 어려운 작업은 사용자 확인을 거친다 | "주문 취소" 버튼을 누르면 반드시 확인 팝업을 띄움 |
| 단기 기억 부담 줄이기 | 사용자가 이전 화면의 정보를 기억하고 있어야 하는 상황을 피한다 | 배송지 입력 화면에서도 장바구니 요약을 계속 보여줌 |
| 오류에 관대하게 | 사용자의 실수를 가정하고 복구 경로를 마련한다 | 우편번호를 잘못 입력하면 바로 오류 메시지와 함께 정정할 수 있는 입력창을 그대로 보여줌 |
이 원칙들은 서로 자연스럽게 얽혀 있다 — 피드백이 잘 되어 있으면 사용자가 굳이 이전 상태를 기억할 필요가 없고(단기 기억 부담 감소), 되돌릴 수 있는 설계는 파괴적 작업에 대한 불안을 줄여준다. 인터페이스를 설계할 때마다 이 표를 체크리스트처럼 훑어보는 것만으로도 흔한 실수 — 예를 들어 "주문 취소"를 확인 절차 없이 즉시 실행되게 만드는 것 — 를 상당수 걸러낼 수 있다.
GUI와 객체지향적 사고
오늘날 대부분의 인터페이스는 그래픽 사용자 인터페이스(GUI)로 구현된다. GUI는 화면의 각 요소(버튼, 입력창, 목록)를 독립적인 객체로 다룬다는 점에서 객체지향 설계와 자연스럽게 맞물린다. 책마루의 주문 화면에서 "상품 카드" 하나하나를 독립된 객체로 설계해두면, 카드 안의 "장바구니 담기" 버튼 동작이나 표시 방식을 다른 화면 요소에 영향을 주지 않고 바꿀 수 있다 — 12장에서 다룬 모듈 독립성의 원칙이 화면 요소 단위에도 그대로 적용되는 것이다.
이런 관점에서 보면 화면 요소 하나하나도 응집도·결합도의 대상이 된다. "상품 카드" 객체가 가격 표시뿐 아니라 결제 승인 로직까지 떠안고 있다면 응집도가 낮은 것이고, 여러 화면 요소가 서로의 내부 상태를 직접 들여다보고 있다면 결합도가 높은 것이다. 화면을 설계할 때도 "이 요소가 하는 일을 한 문장으로 설명할 수 있는가"를 스스로 물어보는 습관은 12장에서 모듈 설계에 적용했던 것과 똑같이 유효하다.
상세설계란 무엇인가
지금까지의 설계(12~14장)는 "이 모듈이 무엇을 책임지는가", "모듈끼리 어떻게 연결되는가"를 정했다. **상세설계(detailed design)**는 그 한 걸음 더 안쪽 — 모듈 내부에서 실제로 어떤 순서와 조건으로 처리가 진행되는지를 정하는 작업이다. 기본 설계가 "재고를 차감하는 모듈이 필요하다"까지 정했다면, 상세설계는 "그 모듈이 재고 수량을 어떤 순서로 검사하고, 부족할 때 어떤 예외 처리를 하는가"까지 구체화한다. 상세설계의 산출물은 곧바로 코드로 옮길 수 있을 만큼 구체적이어야 한다.
상세설계를 문서화하는 도구
상세설계 단계의 절차를 표현하는 도구는 여러 가지가 있다. 각각의 특성과 책마루 적용 예를 살펴보자.
순서도(flowchart)
네모, 마름모 같은 도형과 화살표로 처리 흐름을 그리는 가장 오래된 도구다. 직관적이지만 큰 약점이 있다. 화살표가 도형 사이를 자유롭게 넘나들 수 있어서, 복잡한 로직을 그리다 보면 순서도 자체가 얽히고설킨 "스파게티"가 되기 쉽다. 이 때문에 순서도는 요구사항 분석이나 기본 설계 단계에서는 거의 쓰이지 않는다 — 그 단계에서는 자료흐름도(DFD)나 ER 다이어그램처럼 "무엇이 어떤 데이터를 주고받는가"를 보여주는 도구가 더 알맞고, 순서도는 이미 확정된 절차 하나를 세부 단계까지 파고들 때만 제한적으로 쓰인다. 바꿔 말하면 DFD와 ER 다이어그램은 "무엇이 오가는가"를 보여주는 선언적 도구이고, 순서도는 "어떤 순서로 실행되는가"를 보여주는 절차적 도구다 — 아직 절차가 확정되지 않은 분석·기본설계 단계에 절차적 도구를 들이대면 아직 정해지지 않은 것을 억지로 정해버리는 셈이 된다.
N-S 다이어그램(Nassi-Shneiderman diagram)
순서도의 약점을 보완하기 위해 만들어진 도구로, 화살표 없이 순차·선택·반복을 정해진 상자 모양으로만 표현한다. 상자 안에 상자를 중첩하는 구조라 임의로 흐름을 건너뛸 수 없다는 것이 핵심 장점이다 — 즉 도구 자체가 다음 절에서 설명할 "구조적 프로그래밍"을 강제한다.
PDL(Program Design Language, 의사코드)
자연어와 프로그래밍 언어 문법을 섞어 절차를 서술하는 방식이다. 도형을 그릴 필요 없이 텍스트로 작성하므로 수정하기 쉽고, 실제 코드와 구조가 가장 가깝다는 장점이 있다. 책마루의 재고 차감 로직을 PDL로 표현하면 이렇다.
절차 재고차감(상품코드, 수량)
현재재고 ← 재고테이블에서 상품코드로 조회
만약 현재재고 < 수량 이면
"재고 부족" 예외를 발생시키고 종료
아니면
재고테이블의 수량을 (현재재고 - 수량)으로 갱신
만약 갱신된 수량 = 0 이면
해당 상품을 품절 상태로 표시
끝
끝
끝 절차
이렇게 작성된 PDL은 이후 실제 프로그래밍 언어로 옮길 때 거의 한 줄씩 대응되므로, 구현 단계(16장)로 넘어가는 다리 역할을 한다.
구조적 프로그래밍 — 세 가지 제어 구조만으로 충분하다
상세설계 도구들이 공통으로 지향하는 원칙이 **구조적 프로그래밍(structured programming)**이다. 이 원칙의 핵심 주장은 단순하다 — 어떤 절차든 순차(sequence), 선택(selection), 반복(iteration) 이 세 가지 제어 구조만으로 표현할 수 있고, 표현해야 한다는 것이다.
이 원칙이 자리 잡기 전에는 goto문으로 실행 흐름을 임의의 지점으로 건너뛰는 방식이 흔했다. goto는 짧은 프로그램에서는 편리해 보이지만, 프로그램이 커질수록 실행 순서를 눈으로 추적하기 어려운 코드를 만든다 — 순서도가 스파게티가 되는 것과 같은 문제가 코드 자체에서 발생하는 것이다. 이런 문제의식에서 "goto문은 해롭다(Go To Statement Considered Harmful)"는 유명한 주장이 나왔고, 이후 세 가지 제어 구조만으로 프로그램을 짜는 구조적 프로그래밍이 자리 잡았다.
책마루의 재고 차감 로직을 다시 보면, 앞서 PDL 예시가 이미 세 가지 제어 구조만으로 구성되어 있다는 것을 확인할 수 있다. "조회한다 → 검사한다"는 순차, "재고가 부족하면 예외를 던지고 아니면 갱신한다"는 선택이다. 만약 여러 상품을 한 번에 담은 장바구니 전체를 차감해야 한다면, 상품 목록을 하나씩 순회하는 반복이 추가된다. 이 세 구조는 N-S 다이어그램의 상자 모양과 정확히 대응하며, 상세설계 도구가 goto식의 임의 흐름 이동을 애초에 표현할 수 없게 만들어져 있는 이유도 여기에 있다.
단계적 정제와 상세설계의 관계: 12장에서 다룬 단계적 정제 원칙은 상세설계에서도 그대로 이어진다. "재고를 차감한다"는 한 줄을 처음에는 추상적으로 적어두고, 다음 단계에서 "현재 재고를 조회한다", "부족 여부를 검사한다", "갱신한다"로 풀어내며, 필요하면 그 각각을 또 한 단계 더 구체화한다. PDL은 이 정제 과정을 그대로 기록하기에 알맞은 도구다.
핵심 정리
- 사용자 인터페이스 설계는 12장에서 다룬 설계 활동의 하나이며, 명령어 언어·메뉴 방식·양식 채움·자연어 같은 인터페이스 스타일을 사용자 집단의 숙련도와 사용 빈도에 맞게 선택해야 한다.
- 일관성, 피드백, 되돌릴 수 있는 설계, 파괴적 작업의 확인, 단기 기억 부담 감소, 오류에 대한 관용은 인터페이스 설계 전반에 적용되는 원칙이다.
- 상세설계는 모듈 내부의 구체적인 처리 절차를 코드로 옮기기 직전 수준까지 문서화하는 작업이며, 순서도·N-S 다이어그램·PDL이 대표적인 도구다.
- 순서도는 흐름이 얽히기 쉬워 요구사항 분석이나 기본 설계에는 적합하지 않고, 이미 확정된 절차를 세부화하는 상세설계 단계에서 제한적으로 쓰인다.
- 구조적 프로그래밍은 순차·선택·반복 세 가지 제어 구조만으로 절차를 표현하는 원칙이며,
goto식의 임의 흐름 이동이 낳는 복잡성을 원천적으로 차단한다.
이것으로 Part 4 "소프트웨어 설계"를 마친다. 다음 장(16장)부터는 Part 5로 넘어가, 지금까지 설계한 구조와 절차를 실제 코드로 옮기는 프로그래밍 단계와, 그 코드를 실행 전에 미리 점검하는 코드 검사 기법을 다룬다.