4.2 프로그램 디자인의 중요성
분석과 디자인 과정을 대충 수행하거나 생략하고 바로 코딩에 들어가고 싶은 경우가 많다.
그 수준이야 어떻든 코드가 컴파일되고 구동되면 뭔가 진도가 나가는 것 같고 마음이 편하다. 반면 프로그램을 어떤 식으로 개발할지 이미 어느 정도 머릿속에 들어 있는데 따로 형식에 맞춰서 문서화하는 것은 시간 낭비처럼 느껴진다. 그리고 문서화는 코딩에 비하면 재미도 ㅇ벗고 지루하다.
하루 종일 문서 작업을 하는것이 프로그래머라면 프로그래머가 되지 않았을지도 모른다.
프로그래머라면 다들 코딩부터 하고 보자는 유혹에 빠지기 쉽다. 하지만 정말 단순한 프로젝트가 아니라면 나중에 문제가 발생할 가능성이 거의 100%다. 사전 디자인 단계 없이도 구현에 성공하려면, 개발자로서의 경험, 공통으로 사용되는 디자인 패턴, C++언어에 대한 능숙함, 다루어야 할 문제에 대한 도메인 지식과 요구 조건의 이해정도가 충분해야 한다.
디자인의 중요성을 일꺠우기 위해 다음과 같은 상황을 상상해보자. 교외의 땅을 구한 당신은 멋진 전원주택을 짓고 싶다.
건설업자가 집을 짓기 위해 나타났을 때 집이 어떻게 지어질지 청사진을 보자고 했는데, 건설업자는 다음과 같이 대답한다.
"청사진 그런건 필요 없읍니다. 나는 내가 무얼 하는지 잘 압니다. 한두번 지어본 것도 아니고, 이층집이요? 전혀 문제없습니다. 몇달 전만 해도 단층집을 잘 지었거든요. 바로 공사 시작하죠."
일단 건설업자를 믿고 그냥 공사를 진행했다고 생각해보자. 몇 달 뒤에 가서 보니 배관이 벽체 안에 숨겨져있지 않고 집밖으로 나와있다. 건설업자에게 이상하다고 이야기 하자. 건설업자는 이렇게 대답한다.
"벽체 안에 배관용 공간을 두는걸 미처 생각하지 못했어요. 새로 나온 석고판 벽체 공법을 쓰는 데 정신이 팔려서 그랬습니다. 배관이 밖에 있어도 수도를 사용하는 데는 아무런 문제가 없습니다. 물만 쓸 수 있으면 됐지 밖에 있든 안에 있든 상관없잖아요."
이제 당신은 건설업자에게 의문을 품기 시작한다. 마음에 들지 않지만 별 수 없으니 계속 집을 짓도록 내버려둔다.
드디어 건축이 마무리 단계에 접어들어 진행상태를 점검하러 간다. 그런데 부엌에 싱크대가 없는 것을 발견한다.
건설업자는 이렇게 변명한다.
"이미 공정이 2/3이나 진행됐는데 싱크대를 넣으려고 보니 부엌에 공간이 없었습니다. 공사를 다시할 수는 없고, 부엌 옆방에 싱크대를 만들어드리겠습니다. 괜찮으시죠?"
건설업자의 변명을 집짓기 대신 소프트웨어 개발로 바꿔놓고 보아도 전혀 낯설지 않다. 배관을 둘 자리를 미처 생각하지 못해서 집 밖에 배관을 만드는 부자연스러운 구현을 해본 경험이 있을 것 이다. 예를들어 여러 스레드에서 공유하는 큐 데이터 구조를 만들면서도 미처 스레드 락을 생각하지 못해서 큐에 접근하는 모든 코드마다 일일이 락을 만들어 넣을 수도 있다.
그러한 코드는 지저분하고 부자연스럽긴 하지만 자기 역할을 하기는 한다. 하지만 새로운 프로그래머가 해당 코드를 유지모수하게 되면 이야기가 달라진다.
새로운 프로그래머는 당연히 큐 데이터 구조가 스레드 세이프하게 구현되어 스레드 락킹 메커니즘이 데이터 구조 안에 포함되어 있을 것으로 예상할 것이다. 그래서 새로운 코드를 추가하면서 스레드 락을 넣지 않을 수 있다.
이렇게 되면 나중에 경쟁 조건(race condition) 문제가 발생하고 나서야 문제 원인을 밝히기 위해 몇 주를 허비한다.
이러한 상황은 마감 시간에 임박하여 문제를 대충 무마해버리는 부자연스러운작업의 한가지 예일 뿐이다.
C++ 전문가라면 절대로 데이터 접근 코드마다 락을 삽입하지 않는다. 대신 데이터 클래스에 락킹 기능을 내장하거나 데이터 관리 알고리즘 자체를 락 없이도 스레드 세이프하게 구현한다.
코딩에 들어가기 전 디자인 내용을 형식화 하면 각 부분을 어떻게 연결할지 결정하는데 도움을 준다. 집을 지을때 청사진이 방과 거실의 배치와 동선을 설명하여 집이 의도대로 지어질 지 알게 해주듯이 프로그램 디자인도 각 서브시스템의 구성과 연동 방식을 설명하여 목적하는 요구 조건에 따라 프로그램이 작동할지 판단할 수 있게 해준다.
디자인 계획이 없으면 서브시스템 간의 연결이나 데이터 공유를 빼먹을 수도 있고 훨씬 간단한 방법 대신 복잡한 방법을 채용할 수도 있다. 디자인이 주는 큰 그림이 없으면 세부적인 구현에 몰입되어 중요한 아키텍처적 요소나 목표를 잃어버릴 수 있다.
더욱이 문서화된 디자인은 모든 프로젝트 멤버가 상시 참조할 수 있는 공유 정보 역할도 한다. 만약 나선형 개발 모델을 채용하고 있다면 각 반복 사이클마다 디자인 문서를 업데이트하여 항상 최신 정보를 갖게 해야 한다.
프로그램을 디자인부터 했다면, 대부분 비슷한 구조는 비슷하다는걸 깨닫고 공통부분을 묶어내려고 노력할 것 이다. 공통부분을 묶어냄으로써 해당 속성과 기능은 한번만 코딩하면 된다.
공통부분만이 문제가 아니다. 좀 더 진행하다보면, 각 프로그램의 서브시스템과 연동해야하는 부분이 있다는걸 꺠닫게 될 수 있다.
디자인 작업의 대부분은 이러한 서브시스템간의 관계를 정의하는 것으로 이루어진다.
'전문가를 위한 C++정리' 카테고리의 다른 글
4. 전문가를 위한 C++ 프로그램 디자인 4.4 C++ 디자인의 두 가지 원칙 4.4.1 추상화 (0) | 2024.01.22 |
---|---|
4. 전문가를 위한 C++ 프로그램 디자인 4.3 C++ 디자인의 특징 (0) | 2024.01.22 |
4. 전문가를 위한 C++ 프로그램 디자인 4.1 프로그램 디자인이란? (0) | 2024.01.19 |
3. 코딩 스타일 3.6 포메팅 3.7 스타일 적용의 장애물 (0) | 2024.01.19 |
3. 코딩 스타일 3.6 포메팅 3.6.2~ 3.6.3 (0) | 2024.01.19 |