바로 적기 시작하면 안 될까
머리에 떠올랐으니 그냥 적으면 되는 것 아닐까요?
아주 짧은 프로그램이라면 그래도 됩니다. 실제로 몇 줄짜리는 생각나는 대로 적는 편이 빠릅니다. 문제는 조금만 커져도 그 방식이 무너진다는 것입니다. 무엇을 만들려던 것인지가 중간에 흐려지고, 고칠 때마다 다른 데가 어긋나기 시작합니다.
적기부터 시작하면 자주 벌어지는 일
- 다 만들고 나서야 「내가 원한 게 이게 아닌데」를 깨닫는다
- 절반쯤 적다가 미처 생각 못 한 경우를 만나 처음부터 다시 짠다
- 돌아가긴 하는데 왜 돌아가는지 나도 모른다. 그래서 고치질 못한다
- 친구와 나눠 만들기로 했는데 어디부터 어디까지가 내 몫인지 정할 수가 없다
그래서 프로그램을 만들 때는 일을 몇 단계로 나누어 밟습니다. 각 단계에서 답해야 할 질문이 다릅니다. 「무엇을 만들 것인가」를 정하는 단계와 「어떻게 만들 것인가」를 정하는 단계를 섞지 않으면, 한 번에 한 가지만 생각하면 되므로 훨씬 덜 헷갈립니다.
절차를 밟으면 실수가 없어지나요
아닙니다. 절차는 실수를 없애는 장치가 아니라 실수를 일찍 만나게 하는 장치입니다. 잘못 생각한 것을 설계 단계에서 알아채면 종이 한 장을 고치면 되지만, 다 만든 뒤에 알아채면 만들어 둔 것을 걷어내야 합니다. 고치는 비용이 뒤로 갈수록 커지기 때문에 앞 단계에 시간을 쓰는 것입니다.
친구가 「절차대로 만들었는데 테스트에서 틀린 답이 나왔으니 절차는 소용없었다」고 말합니다. 친구에게 무엇이라고 답할 수 있을까요?
다섯 단계로 나누어 본다
각 단계는 어떤 질문에 답할까요?
1. 요구 분석
「무엇을 만들 것인가?」
만들 것이 어떤 일을 해야 하는지, 어디까지가 이 프로그램의 몫인지를 글로 못박습니다.
2. 설계
「어떻게 만들 것인가?」
무엇을 입력받아 어떻게 처리해 무엇을 내놓을지 정하고, 푸는 순서를 짭니다. 아직 프로그래밍 언어는 쓰지 않습니다.
3. 구현
「정한 대로 적었는가?」
설계한 순서를 프로그래밍 언어로 옮겨 적습니다. 흔히 코딩이라고 부르는 단계입니다.
4. 테스트
「정말 그렇게 도는가?」
여러 값을 넣어 보며 원한 대로 도는지 확인하고, 어긋난 곳을 고칩니다.
5. 유지 보수
「계속 쓸 수 있게 하려면?」
쓰는 동안 드러난 문제를 고치고, 달라진 상황에 맞춰 수정해 가며 살려 둡니다.
이 다섯을 묶어 부르는 이름이 있습니다
프로그램이 만들어져서 쓰이다가 더 쓰이지 않을 때까지의 이 전체 흐름을 소프트웨어 생명 주기(software life cycle)라고 부릅니다. 사람의 한살이처럼 태어나서 자라고 나이 드는 과정 전체를 가리키는 말입니다. 「개발 과정」이라고 하면 만드는 데까지만 떠올리게 되는데, 이 말에는 만든 뒤에 쓰이는 긴 시간까지 들어 있습니다.
한 방향으로만 흐르지는 않습니다
단계를 1에서 5로 늘어놓았지만, 실제로는 뒤에서 앞으로 되돌아가는 일이 아주 흔합니다. 테스트하다가 요구를 잘못 이해했다는 것을 알게 되면 1번으로 돌아갑니다. 되돌아가는 것은 실패가 아니라 원래 그런 것입니다. 다만 어느 단계로 돌아가야 하는지 알려면 단계가 나뉘어 있어야 합니다.
다섯 단계 가운데 프로그래밍 언어를 처음 쓰는 단계는 몇 번일까요? 그보다 먼저 오는 단계들은 언어 없이 무엇을 하고 있었는지도 함께 말해 보세요.
1단계 · 무엇을 만들 것인가
하고 싶은 말을 그대로 적으면 요구 사항이 될까요?
여기서부터 끝까지 따라갈 예제
동아리 시간에 사 온 간식을 나눠야 합니다. 누군가 이렇게 말했습니다.
「간식을 사람들한테 똑같이 나눠 주는 프로그램을 만들자.」
이 한 문장을 가지고 마지막까지 갑니다. 지금은 만들 수 없습니다. 왜 만들 수 없는지부터 봅시다.
요구 사항은 「이 프로그램이 무엇을 해야 하는가」를 적어 둔 것입니다. 위 문장은 사람끼리는 통하지만 요구 사항이 되지 못합니다. 「성적이 높은 학생을 찾아 줘」라는 말에 몇 명인지, 기준이 무엇인지 되물어야 하듯, 여기에도 되물을 것이 남아 있기 때문입니다.
되물어야 할 것들
- 딱 나누어떨어지지 않으면? 남는 것을 어떻게 하나요
- 간식을 쪼갤 수 있나요? 쪼갤 수 있다면 몫이 소수가 될 수 있습니다
- 사람이 아무도 없으면? 0으로 나누는 일이 벌어집니다
- 간식이 사람 수보다 적으면? 한 사람당 0개가 되는데 그래도 괜찮나요
- 결과를 어떻게 보여 주나요? 숫자만 내놓을지 문장으로 알릴지
이렇게 되묻는 일이 요구 분석입니다. 답을 정하는 것보다 물어야 할 것을 빠짐없이 찾아내는 쪽이 어렵습니다.
되묻고 나서 이렇게 정했다고 합시다. 정답이 하나인 것은 아니어서 다르게 정해도 되고, 다르게 정하면 뒤 단계가 전부 달라집니다. 어떻게 정했든 정한 것을 적어 둡니다.
정리한 요구 사항
이렇게 적어 둔 문서를 요구 사항 명세서라고 부릅니다. 거창한 이름이지만 「무엇을 만들지 못박아 적은 종이」일 뿐입니다.
- 간식 개수와 사람 수를 사용자에게 입력받는다.
- 간식은 쪼개지 않는다. 한 사람이 가져가는 개수는 정수로 한다.
- 모두에게 같은 개수를 주고, 남는 것은 남았다고 알린다.
- 사람 수는 1명 이상이어야 한다. 0명이나 음수처럼 1보다 작은 수가 들어오면 나눌 수 없다고 알린다.
- 간식이 사람 수보다 적으면 한 사람당 0개로 하고 전부 남은 것으로 알린다.
- 결과는 「한 사람당 ○개, ○개 남음」 형태의 문장으로 보여 준다.
요구 사항을 적을 때 지킬 것
확인할 수 있게 적는다
「편리하게 만든다」는 지켰는지 아닌지를 판단할 수가 없습니다. 나중에 값을 넣어 보고 맞다 틀리다를 말할 수 있는 문장으로 적습니다.
하지 않을 것도 적는다
「간식을 쪼개지 않는다」처럼 범위 밖으로 밀어낸 것을 적어 두면, 나중에 「왜 이건 안 되지?」 하는 다툼이 줄어듭니다.
「되물어야 할 것들」 목록에 하나를 더 보태 보세요. 힌트 — 입력하는 사람이 숫자가 아닌 것을 넣으면 어떻게 될까요?
2단계 · 어떻게 만들 것인가
언어를 아직 쓰지 않는데, 무엇을 정할 수 있을까요?
요구 사항은 무엇을 할지를 적은 것이고, 설계는 그것을 어떤 방법으로 할지를 정하는 일입니다. 가장 먼저 하는 일은 프로그램을 입력 · 처리 · 출력 세 토막으로 나누어 보는 것입니다. 거의 모든 프로그램이 이 모양을 하고 있습니다.
| 토막 | 무엇을 정하는가 | 간식 나누기에서는 |
|---|---|---|
| 입력 | 무엇을 받아들일지, 어떤 값까지 받아들일지 | 간식 개수(0 이상 정수), 사람 수(1 이상 정수) |
| 처리 | 받은 것을 어떤 순서로 다룰지 | 사람 수가 1보다 작은지 먼저 보고, 아니면 몫과 나머지를 구한다 |
| 출력 | 무엇을 어떤 모양으로 내놓을지 | 「한 사람당 ○개, ○개 남음」 또는 나눌 수 없다는 안내 |
푸는 순서를 적어 본다
- 간식 개수를 입력받는다.
- 사람 수를 입력받는다.
- 사람 수가 1보다 작으면 「나눌 수 없습니다」를 보여 주고 끝낸다.
- 한 사람당 개수 = 간식 개수를 사람 수로 나눈 몫
- 남는 개수 = 간식 개수를 사람 수로 나눈 나머지
- 「한 사람당 (한 사람당 개수)개, (남는 개수)개 남음」을 보여 준다.
여기에는 어떤 프로그래밍 언어도 쓰이지 않았습니다. 그런데도 무엇을 할지가 빠짐없이 정해져 있습니다. 이렇게 적어 둔 순서를 알고리즘이라고 부릅니다.
왜 언어를 쓰지 않고 먼저 짜나요
언어로 적기 시작하면 문법을 맞추는 데 신경이 쏠려 순서를 놓치기 쉽습니다. 괄호를 닫았는지 확인하는 머리와 「사람 수가 0인 경우를 빠뜨리지 않았나」를 확인하는 머리는 다릅니다. 게다가 언어 없이 짜 둔 순서는 어느 언어로도 옮길 수 있습니다. 같은 순서를 C로도 Python으로도 적을 수 있다는 뜻입니다.
3번 줄의 자리를 눈여겨보세요
사람 수가 1보다 작은지 보는 검사가 나누기보다 앞에 있습니다. 순서가 바뀌면 안 됩니다. 0으로 나눈 다음에 확인하면 늦습니다. 그 시점에 프로그램이 멈춰 버리기 때문입니다. 설계 단계에서 정한 순서 하나에 따라 프로그램이 멈추기도 하고 끝까지 돌기도 합니다.
요구 사항 5번(간식이 사람 수보다 적을 때)은 「푸는 순서를 적어 본다」의 여섯 줄 중 어디에서 지켜지고 있을까요? 따로 처리한 줄이 없다면, 그래도 되는 이유를 말해 보세요.
3단계 · 정한 대로 적는다
설계가 끝났으니 이제 그대로 옮기기만 하면 될까요?
구현은 설계한 순서를 프로그래밍 언어로 옮겨 적는 단계입니다. 여기서 처음으로 언어를 고르게 되는데, 이때 무엇을 만드는가, 어디서 실행되는가를 기준으로 검토합니다. 설계를 언어 없이 해 두었기 때문에 이 선택이 늦어도 괜찮았습니다.
「그대로 옮기기만 하면 된다」고 하기에는 여기서도 정할 것이 남습니다. 지금 몰라도 되지만, 실제로 적기 시작하면 바로 만나게 되는 것들을 미리 봐 둡니다.
이름을 뜻이 드러나게 짓는다
값을 담아 둘 자리에 a, b, c 같은 이름을 붙이면 사흘 뒤의 내가 못 읽습니다. 간식개수, 사람수처럼 이름만 보고 무엇인지 알 수 있게 짓습니다.
조금 적고 바로 확인한다
전부 적은 뒤에 처음 실행해 보면 어디가 잘못됐는지 찾을 범위가 너무 넓어집니다. 입력까지 적고 한 번, 계산까지 적고 한 번 실행해 보면 방금 적은 곳만 의심하면 됩니다.
왜 그렇게 했는지를 남긴다
코드는 무엇을 하는지는 보여 주지만 왜 그렇게 했는지는 보여 주지 않습니다. 「사람 수가 0인지 먼저 보는 이유」 같은 것을 짧게 적어 두면 나중에 지우지 않게 됩니다.
설계와 어긋나면 설계를 고친다
적다 보면 설계에서 미처 못 본 것이 나옵니다. 이때 코드만 슬쩍 바꿔 두면 둘이 어긋납니다. 설계로 돌아가 고치고 다시 내려오는 편이 결국 빠릅니다.
돌아간다고 끝난 것이 아닙니다
번역기를 통과하고 화면에 결과가 나오면 다 된 것처럼 보입니다. 하지만 번역기는 규칙에 맞는지만 봅니다. 간식 6개를 4명에게 나눴는데 「한 사람당 2개, 2개 남음」이라고 나온다면 문법은 멀쩡하지만 답이 틀린 것입니다. 이런 것을 찾아내는 일이 4단계 테스트입니다.
「돌아간다고 끝난 것이 아닙니다」 상자의 「간식 6개를 4명에게」 예에서 맞는 답은 무엇이어야 할까요? 설계에 적어 둔 4번 · 5번 줄로 직접 계산해 보세요.
5단계 · 만든 뒤가 대개 더 길다
다 만들었는데 왜 아직 단계가 남아 있을까요?
테스트까지 마치면 프로그램을 쓰기 시작합니다. 여기서는 그 뒤를 봅니다. 쓰이는 프로그램은 만들어진 뒤에도 계속 손이 갑니다. 쓰는 기간이 만드는 기간보다 대개 훨씬 길기 때문입니다.
간식 나누기에도 이런 일이 생깁니다
- 쓰다 보니 남은 간식을 누가 가져갈지도 정해 주면 좋겠다는 말이 나온다
- 동아리가 커져서 사람 수를 매번 입력하는 게 번거롭다는 불평이 나온다
- 아무도 안 건드렸는데 어느 날 갑자기 안 되는 일이 생긴다
남은 간식 이야기와 사람 수 입력 이야기는 요구가 늘어난 것이고, 갑자기 안 되는 일은 주변 환경이 달라진 것입니다. 셋 다 처음에 잘못 만들어서 생긴 일이 아닙니다.
그래서 앞 단계의 흔적을 남겨 둡니다
고치려면 원래 무엇을 하려던 것이었는지부터 알아야 합니다. 적어 둔 요구 사항과 설계가 없으면, 고치는 사람은 코드만 보고 의도를 짐작해야 합니다. 그래서 요구 사항과 설계를 글로 남기는 것은 만들 때 편하려는 것이 아니라 나중에 고칠 수 있게 하려는 것입니다. 그 「나중에 고치는 사람」은 대개 몇 달 뒤의 자기 자신입니다.
그리고 다시 1단계로
「남은 간식을 누가 가져갈지도 정해 달라」는 말이 나왔다면, 그것은 새 요구 사항입니다. 코드부터 열지 말고 1단계로 돌아가 되묻습니다. 순서대로 돌아가며 주나요, 제비뽑기인가요? 다섯 단계는 한 번 지나가고 끝나는 줄이 아니라 계속 도는 고리에 가깝습니다.
간식 나누기에 생긴 일 가운데 「처음에 잘못 만들어서 생긴 일」은 하나도 없다고 했습니다. 그렇다면 유지 보수가 필요하다는 것은 프로그램이 나쁘다는 뜻일까요? 왜 그렇게 생각했는지 적어 보세요.
핵심 정리
왜 절차를 밟는가
실수를 일찍 만나려고
- 단계마다 답해야 할 질문이 다르다 — 섞지 않는다
- 고치는 비용이 뒤로 갈수록 커진다
- 절차는 실수를 없애 주지 않는다
다섯 단계
각 단계의 질문
- 요구 분석 무엇을 · 설계 어떻게 · 구현 적기
- 테스트 정말 그런가 · 유지 보수 계속 쓰려면
- 앞 단계가 정한 것을 뒤 단계가 이어받고, 되돌아가는 것이 정상이다
요구 분석과 설계
언어를 쓰기 전에 끝내는 일
- 요구 분석은 되물어 애매한 곳을 없애는 일
- 요구 사항은 확인할 수 있게, 안 할 것도 함께 적는다
- 설계는 입력 · 처리 · 출력으로 나누고 순서를 짠다
구현과 유지 보수
적는 일과 살려 두는 일
- 이름을 뜻이 드러나게, 조금 적고 바로 확인한다
- 돌아간다고 답이 맞는다는 뜻은 아니다
- 요구 사항과 설계를 남기는 것은 나중에 고치기 위해서다
확인 퀴즈
배운 내용을 확인해 봅시다.
설계 단계에서 하는 일로 알맞은 것은?
요구 사항으로 가장 알맞게 적힌 문장은?
프로그래밍의 절차에 대한 설명으로 옳지 않은 것은?