왜 소프트웨어에도 "공학"이 필요한가
책방 겸 문구점을 운영하는 사장님이 "온라인 주문도 받아보자"고 마음먹었다고 하자. 개발자를 한 명 불러서 "장바구니랑 결제 되게 만들어주세요"라고 말하면 끝나는 일일까?
실제로 많은 소규모 프로젝트가 이렇게 시작한다. 그리고 상당수가 이렇게 실패한다 — 만들고 보니 재고가 두 곳(매장 POS와 온라인)에서 따로 놀거나, 배달 가능 지역을 나중에야 정의해야 한다는 걸 깨닫거나, 사장님이 원했던 기능과 실제로 만들어진 기능이 서로 다르다는 걸 오픈 당일에야 알게 되는 식이다.
소프트웨어 공학은 이런 사고를 줄이기 위한 원리와 절차의 집합이다. 정해진 예산과 기간 안에서, 처음 약속한 대로, 나중에 고치기 쉬운 형태로 소프트웨어를 만드는 것 — 이 챕터에서는 그 밑바탕이 되는 두 가지 개념, "공학이란 무엇인가"와 "소프트웨어 개발의 6단계 흐름"을 다룬다. 앞으로 이 시리즈 전체에서 반복 등장할 예제인 책마루 온라인 주문 시스템도 여기서 처음 소개한다.
공학과 과학은 다른 일이다
과학(science)은 "왜 그런가"를 밝히는 일이다. 물이 100도에서 끓는 이유, 중력이 작용하는 방식 같은 자연의 법칙을 탐구한다. 반면 공학(engineering)은 그렇게 밝혀진 법칙을 가져다 써서 사람에게 쓸모 있는 무언가를 만드는 일이다. 물리학자가 유체역학을 연구한다면, 엔지니어는 그 지식으로 배관을 설계한다.
소프트웨어 공학도 마찬가지다. 컴퓨터 과학이 "계산이란 무엇인가", "이 알고리즘이 왜 O(n log n)인가"를 다룬다면, 소프트웨어 공학은 그 지식을 가지고 "예산 300만원, 두 달 안에, 책마루 사장님이 실제로 쓸 수 있는 시스템을 어떻게 만들 것인가"를 다룬다. 즉 공학의 무게 중심은 지식 자체가 아니라 지식을 적용해 문제를 해결하는 과정에 있다.
시스템이란 무엇인가
시스템은 "공통의 목적을 위해 서로 관계를 맺고 함께 작동하는 요소들의 집합"이다. 책마루 온라인 주문 시스템을 예로 들면 이렇게 쪼개볼 수 있다.
| 구성 요소 | 역할 |
|---|---|
| 주문 웹페이지 | 손님이 상품을 고르고 결제하는 창구 |
| 재고 데이터베이스 | 매장 POS와 공유되는 재고 수량 |
| 매장 알림 태블릿 | 새 주문을 직원에게 알림 |
| 결제대행사 연동 | 카드·간편결제 처리 |
| 배달 담당자 앱 | 배달 목록과 경로 확인 |
이 다섯 개는 따로 있으면 아무 의미가 없다. "손님이 주문하면 재고가 줄고 직원에게 알림이 가고 결제가 이루어진다"는 관계 때문에 비로소 하나의 시스템이 된다. 시스템을 분석한다는 것은 결국 이 요소들과 그 사이의 관계를 파악하는 일이다.
시스템 공학은 기술적 측면과 관리적 측면, 두 축으로 나눠 볼 수 있다.
- 기술적 측면: 구성 요소를 어떻게 조합해야 효율이 극대화되는가 (예: 재고 DB를 매장 POS와 실시간 동기화할지, 5분마다 배치로 맞출지)
- 관리적 측면: 그 조합을 만들어내는 과정에서 사람·자재·일정을 어떻게 계획하고 통제하는가 (예: 개발자 배정, 마감일, 예산 집행)
이 시리즈의 뒷부분(4~5장은 관리적 측면, 6장 이후는 주로 기술적 측면)이 바로 이 두 축을 따라 구성된다.
카페 창업으로 보는 개발의 흐름
소프트웨어 개발 과정을 처음 접하면 추상적으로 느껴지기 쉽다. 대신 카페를 하나 여는 과정을 떠올려보자.
- 상권을 조사하고 예산을 정한다 (계획)
- 어떤 손님층을 노릴지, 메뉴 구성은 어떻게 할지 구체적으로 정한다 (요구사항 분석)
- 매장 인테리어 도면을 그리고 주방 동선을 설계한다 (설계)
- 실제로 인테리어 공사를 하고 장비를 들인다 (구현)
- 오픈 전 시범 운영을 하며 동선이 실제로 괜찮은지, 메뉴가 제대로 나오는지 확인한다 (시험)
- 오픈 후에도 손님 피드백을 받아 메뉴를 바꾸고 시설을 고친다 (유지보수)
소프트웨어도 정확히 이 여섯 단계를 거친다. 차이가 있다면 카페는 눈에 보이는 물리적 공간이라 설계 실수가 금방 드러나지만, 소프트웨어는 화면 뒤에 숨어있어서 잘못된 설계가 한참 뒤 — 흔히 사용자가 몰릴 때 — 에야 드러난다는 점이다. 그래서 소프트웨어 공학은 오히려 더 의식적으로 각 단계를 문서화하고 점검할 것을 요구한다.
1) 계획 — 문제를 문장으로 만드는 단계
책마루 사장님이 처음 개발사에 건네는 말은 대개 "온라인 주문 되게 해주세요" 정도로 막연하다. 계획 단계의 역할은 이 막연한 바람을 **문제 기술서(problem statement)**로 구체화하는 것이다 — 무엇을 만들 것인지, 예산은 얼마인지, 언제까지 필요한지. 이 단계의 산출물이 부실하면 그 다음 모든 단계가 흔들린다.
2) 요구사항 분석 — "무엇"이지 "어떻게"가 아니다
요구사항 분석의 핵심 원칙은 하나다: 이 단계에서는 무엇(What)을 만들지만 정하고, 어떻게(How to) 만들지는 다음 단계로 미룬다.
책마루 예제로 보면 이렇다.
무엇: 손님이 30분 이내 배달 가능 지역인지 자동으로 확인할 수 있어야 한다. 어떻게: 이건 설계 단계의 일 — 우편번호 매핑 테이블을 쓸지, 지도 API의 거리 계산을 쓸지는 아직 정하지 않는다.
이 구분이 흐려지면 무슨 일이 벌어질까? 분석가가 "지도 API를 씁니다"라고 이미 기술 방식을 정해버리면, 나중에 더 나은 방법이 나와도 요구사항 문서 자체를 다시 써야 한다. 요구사항은 목표를, 설계는 그 목표를 달성하는 방법을 담아야 서로 독립적으로 바뀔 수 있다.
이 단계의 산출물은 요구사항 명세서다. 이 문서는 단순한 참고자료가 아니라 개발사와 고객(책마루 사장님) 사이의 약속 문서에 가깝다 — 나중에 "이 기능이 원래 있었나 없었나"를 두고 다툴 일이 생기면 이 문서가 기준이 된다.
요구사항을 다듬는 네 단계
"온라인 주문 되게 해주세요" 한 문장이 요구사항 명세서로 완성되기까지는 보통 네 단계를 거친다.
- 요구사항의 규명: 사용자 관점에서 필요한 것을 모은다. 기능 요구("배달 가능 지역을 자동으로 판단한다"), 성능 요구("주문 목록은 3초 안에 뜬다"), 인터페이스 요구("결제대행사 API 규격을 따른다")로 나눠 정리한다.
- 타당성 조사: 이걸 정말 이 예산과 기간 안에 만들 수 있는가를 따진다. 경제적 타당성(500만원으로 충분한가), 기술적 타당성(직원이 매장 태블릿을 무리 없이 다룰 수 있는가), 법적 타당성(통신판매업 신고가 필요한가) 등을 점검한다.
- 비용과 일정에 대한 제약 설정: 기능별로 대략적인 개발 기간과 비용을 추정하고, 우선순위를 정한다. 책마루라면 "배달 가능 지역 자동 판단"은 필수, "회원 등급 할인"은 다음 버전으로 미루는 식이다.
- 요구사항 정의 문서화: 지금까지의 논의를 요구사항 명세서 한 장으로 정리하고, 사장님의 서명(또는 확인)을 받는다.
이 네 단계를 압축하면 책마루 요구사항 명세서의 일부는 이런 모습이 된다.
| 구분 | 요구사항 |
|---|---|
| 기능 요구사항 | 손님은 우편번호 입력만으로 배달 가능 여부를 확인할 수 있어야 한다 |
| 기능 요구사항 | 재고가 0이 되면 해당 상품은 자동으로 품절 표시된다 |
| 성능 요구사항 | 주문 목록 페이지는 3초 이내에 로딩된다 |
| 인터페이스 요구사항 | 결제는 PG사가 제공하는 표준 API 규격을 따른다 |
이렇게 표로 정리해두면 나중에 "이 기능 넣어달라"는 요청이 들어왔을 때 "원래 명세서에 있었는지"를 바로 확인할 수 있다 — 요구사항 명세서가 약속 문서로 기능하려면 이 정도의 구체성이 필요하다.
왜 이 단계에 공을 들여야 하나: 요구사항 분석에서 놓친 것은 설계 단계에서 발견하면 수정 비용이 몇 배, 구현이 끝난 뒤 발견하면 수십 배로 뛴다는 것이 소프트웨어 공학에서 반복적으로 확인되는 경험칙이다. 초반의 "느린" 분석이 결국 가장 빠른 길이다.
3) 설계 — 무엇을 어떻게로 바꾸는 단계
설계는 요구사항을 실제로 구현 가능한 구조로 바꾸는 작업이다. 책마루 시스템이라면 "주문 처리 서버", "재고 동기화 배치", "결제 모듈"처럼 시스템을 하위 구성요소(subsystem)로 나누고, 각 구성요소가 무엇을 책임질지, 서로 어떻게 통신할지를 정한다.
설계가 부실하면 어떤 일이 생기는지는 뒤에서(12~15장) 자세히 다루지만, 핵심만 미리 말하면: 설계가 흔들리는 시스템은 작은 변경 하나에도 여러 곳을 함께 고쳐야 하는 상태가 된다. "배달 가능 지역을 하나 추가했을 뿐인데 결제 로직까지 건드려야 했다"는 상황이 바로 설계 부실의 전형적인 증상이다.
4) 구현 — 설계를 코드로 옮기는 단계
구현(프로그래밍)은 의외로 전체 개발 비용에서 차지하는 비중이 크지 않다 — 대략 20% 안팎이고, 요구사항 분석과 설계에 40~50%가 들어간다. 이 비율이 뒤집혀서 "일단 코드부터 짜고 요구사항은 나중에 정리하자"는 식으로 진행되면, 개발 중간에 계속 방향이 바뀌면서 오히려 전체 기간이 늘어난다. 앞 단계에 들이는 시간은 아까운 시간이 아니라 뒤 단계의 시간을 줄여주는 투자다.
5) 시험 — 네 가지 층위로 확인한다
시험(테스트)은 보통 아래 순서로 진행된다.
- 단위 시험: 재고 차감 함수 하나만 떼어서 검증
- 통합 시험: 주문 처리 모듈과 재고 모듈을 합쳐서 검증
- 시스템 시험: 결제대행사 연동까지 포함해 전체 흐름을 검증
- 인수 시험: 책마루 사장님이 직접 써보고 "이 정도면 되겠다"고 확인
네 층위를 구분하는 이유는 단순하다 — 단위 시험에서 잡을 수 있는 버그를 인수 시험 단계까지 끌고 가면 원인을 찾는 비용이 기하급수적으로 커지기 때문이다. (17장에서 테스트 전략을 더 깊이 다룬다.)
6) 유지보수 — 개발이 끝난 게 아니라 시작이다
시스템을 오픈한 뒤에도 일은 끝나지 않는다. 유지보수는 크게 네 갈래로 나뉜다.
- 잘못된 부분을 고치는 유지보수 (버그 수정)
- 새 환경에 적응시키는 유지보수 (예: 배달앱 API가 바뀌었을 때)
- 새로운 기능을 추가하는 유지보수 (예: 정기구독 배송 추가)
- 앞으로의 관리를 위한 예방적 유지보수 (예: 코드 정리, 문서 갱신)
흔히 개발 비용만 예산에 잡고 유지보수 비용은 과소평가하는데, 실제로는 잘 만든 시스템도 유지보수 비용이 초기 개발 비용을 넘어서는 경우가 대부분이다. 계획 단계에서부터 "이 시스템은 앞으로 계속 바뀔 것"이라는 전제를 깔고 설계해야 하는 이유가 여기에 있다.
미리 보는 여섯 가지 생존 기술
이 시리즈가 22개 장에 걸쳐 다루는 내용을 관통하는 여섯 가지 축이 있다. 지금 당장 이해할 필요는 없고, 앞으로 어디서 다시 만나게 될지 미리 표시해두는 지도라고 생각하면 된다.
| 기술 | 한 줄 설명 | 어디서 다루나 |
|---|---|---|
| 객체지향 개발 | 데이터와 동작을 하나의 단위(객체)로 묶어 설계 | 10장, 11장 |
| CASE 도구 | 설계·문서를 도와주는 도구 활용 | 9장, 11장 |
| 소프트웨어 품질 보증 | 개발 전 과정에서 품질을 점검하는 체계 | 19장 |
| 구조적 방법 | 기능을 흐름 단위로 쪼개 분석·설계 | 7장, 13장 |
| 소프트웨어 계량화(메트릭) | 규모·복잡도·결함을 숫자로 관리 | 22장 |
| 리엔지니어링 | 낡은 시스템을 재구성해 되살리는 기법 | 18장 |
이 여섯 가지가 왜 "생존 기술"로 불리는지는 뒤로 갈수록 체감하게 될 것이다 — 하나같이 "처음엔 없어도 되지만 시스템이 커지는 순간부터는 없으면 버티기 힘든" 것들이다.
핵심 정리
- 공학은 과학 지식을 실제 문제 해결에 적용하는 일이다. 소프트웨어 공학은 컴퓨터 과학 지식을 정해진 예산·기간 안에서 쓸모 있는 소프트웨어로 만드는 일에 적용한다.
- 시스템은 요소들의 집합이 아니라 요소들 사이의 관계로 정의된다.
- 소프트웨어 개발은 계획 → 요구사항 분석 → 설계 → 구현 → 시험 → 유지보수의 6단계를 거치며, 각 단계는 다음 단계의 산출물을 위한 기반이 된다.
- 요구사항 분석의 핵심은 "무엇"과 "어떻게"를 분리하는 것 — 이 원칙은 이후 설계·구현 단계 전체에서 계속 등장한다.
다음 장(2장)에서는 "요구사항만 잘 쓰면 프로젝트는 성공한다"처럼 그럴듯해 보이지만 실제로는 틀린, 소프트웨어 개발에 대한 흔한 오해들을 짚어본다.