Recommanded Free YOUTUBE Lecture: <% selectedImage[1] %>

Contents

순서도

원래 그다지 머리를 굴리지 않고 프로그램을 개발하는 스타일이다. 물론 슈도 코드 정도는 만들기는 하는데, 이걸로는 충분하지 않다는 생각이 자꾸 든다. 한눈에 들어오지 않기 때문이다. 테스트 기반의 방법론인 TDD는 충분히 활용할만 하지만 개별 단위 모듈에 너무 집중하다 보니, 전체의 흐름을 놓치는 느낌이 든다.

모듈단위로는 제대로 테스트 한게 분명한데, 전체 시스템을 놓고 봤을 때 올바른 흐름을 타고 있는가 하는 기분. 전문화의 함정에 빠지는것 아닌가 하는 느낌. 예컨데 전문화된 개별 모듈은 잘 돌아가는데, 시스템은 산으로 향하는 느낌.

TDD를 높은 수준에서 사용하면, 전체 흐름까지 정리될런지도 모르겠다. 아직 나는 TDD를 심각하게 프로젝트에서 사용해 본적은 없어서 말이다.

그렇다고 굳이 TDD(:12)를 그 수준까지 다룰 생각은 없어서 TDD는 그냥 단위 테스트를 위한 방법론으로 하고, 전체 흐름을 따라가기 위한 나름의 방법론을 생각해 보기로 했다.

프로그램을 개발하기 전에 순서도를 그리는 것은 지금은 고리타분한 일로 여겨진다. 슈도 코드 정도로 넘어가는게 일반적이다. 하지만 슈도코드는 한눈에 들어오지 않는다. 자고로 흐름이란 것은 한눈에 들어와야지 내가 어느 위치에 어떤 상태로 놓여있는지, 그래서 어떤 흐름을 타야 하는지를 알수 있을 것이다. 그러자면 역시 순서도가 좋기는 한데, 문제는 순서도 그리는게 좀 기분이 그렇다는 것.

순서도를 그리는 것을 꺼리는 가장 큰 이유는 귀찮아서가 아닐까 ? 일단 순서도에 나오는 도형 객체의 사용방법도 알아야 하는데, 이 도형 객체를 보면 알겠지만 현대적인 소프트웨어와는 상당히 동떨어진 객체들이 많다. 그리는 것도 그다지 쉽지가 않다. XP어쩌고 해서 나오는 방법론에 비하면 너무 구식인 듯한 느낌도 든다.

하지만 순서도를 그려본 결과 흐름을 보는데 이보다 더 좋은 것이 없는 것 같다. 커뮤니케이션 할 때도 좋은데, 한눈에 쫙 들어오기 때문이다.

그래서 타협을 하기로 했다. 타협점은 아래와 같다.
  1. 선택, 종료, 처리, 입력/출력 정도의 도형 객체만 사용하고 나머지는 쓰지 않기로 했다.
  2. 구글 Docs를 사용하기로 했다. 어디에서나 접근 가능하고 가볍게 사용할 수 있다는 게 맘에 들었다.

순서도 기반 프로그래밍

이제 순서도를 프로그램의 완성도를 높이는데, 적용하기로 했다. TDD와 유사한데, 방법은 다음과 같다.

  1. 먼저 순서도를 그린다.
순서도는 어디까지나 자기 자신을 위함이다. 도형 객체 선택이라든지 흐름 구성은 자기 기호에 맞게 선택한다. 이미지의 특성상 슈도코드보다 훨씬 이해하기 쉬워서 커뮤니케이션에 문제되는 경우는 없다. 70-80년대식 하드코어 슈도코드를 요구하는 깐깐한 사람이라면 객체 선택이 왜 이럼 ? 할지도 모르겠지만, 그런 사람이 있을런지는 모르겠다. 요즘에는 기업도 순서도 객체의 의미를 제대로 고민해서 그리는 걸 요구하지는 않는다.
  1. 순서도를 보고 프로그램을 대략 개발한다.
대략 개발한다. 처음부터 완전한 프로그램을 만들 것을 고민하지 않는다. 어차피 TDD등과 함께 사용할 경우 흐름을 이루는 각 모듈은 빠른 사이클로 개발할 것이니 말이다.
  1. 대략 개발이 되었으면, 세심하게 흐름을 따라가면서 빠진 부분이 없는지 추가해야할 부분이 있는지 확인한다. 순서도를 이루는 각 객체들은 연결선으로 연결이 된다. 개발자는 연결선의 굵기와 색을 다르게 해서, 흐름의 완성 상태를 변경할 수 있다. 나는 다음과 같은 상태룰을 만들었다.
    1. 처음에는 모든 연결선을 회색으로 한다. 흐름이 한번도 검토되지 않은 상황임을 의미한다.
    2. 확인된 흐름은 검은색으로 바꾼다.
    3. 검증까지 완전히 끝났다면, 굵은 검색은색으로 바꾼다.
    4. 흐름의 모든 영역이 완전히 정리되었다면, 흐름에 대한 개발이 끝난다. 이러한 과정은 TDD를 통한 단위 모듈 테스트와 함께 진행된다.
    5. 몇몇 검증해야할 중요 데이터를 가지고 있는 흐름이 있을 수 있는데, 이 경우 도형객체의 색을 바꾸는 것으로 표시한다. 이를테면 빨간색으로 표시한다. 이 구간의 자료구조는 검증되지 않았음을 의미하는데, 검증이 되면 검은색등으로 상태를 변경한다.
개발자는 순서도를 보는 것으로 각 흐름의 완성도와 집중해야 할 곳을 한눈에 파악할 수 있다.

다음은 활용 예 이다. 박스의 내용과 흐름은 대략 그렸다.

어느 흐름을 개발해야하고 검증해야 하는지 한눈에 알 수 있다. 이 순서도를 본 개발자는 딱히 설명해 주지 않아도 ObjectReload의 흐름을 타는 영역을 개발 해야 하며, SendThreadSignal에서 관리하는 자료구조에 대한 검증과 에러처리를 하지 않았음을 알 수 있다.

실제 적용해 봤더니

한눈에 들어와서 좋다.

굳이 많은 시간을 들여서 시각화 하는 이유는 머리로 생각하는 것보다는 이미지로 나타내는게 훨씬 이해하기 쉽기 때문이다. 이해하기 쉽우면, 문제가 발생할만한 지점을 더 쉽게 찾아낼 수 있다.

흐름의 중요한 부분에서 에러코드를 포함한 처리를 제대로 했는지 알 수 있다.

프로그램을 개발하다보면 에러코드에 대한 상세 처리는 뒤로 미루는 경우가 있는데, 나중에 테스트와 디버깅에서 애를 먹게 된다. 발생할만한 에러를 모두 검사해서 처리하는 방법을 생각해 볼 수 있겠다. 그러나 그다지 좋은 방법이라고 생각되지는 않는다. 많은 종류의 에러가 흐름을 통해서 만들어지기 때문에, 전체 흐름을 이해하고 있어야지만 제대로된 에러처리가 가능해지기 때문이다.

어느 부분의 흐름이 취약한지알 수 있다.

이 방식은 각 흐름을 체크한다. 그러므로 어느 부분의 흐름이 취약한지를 빠르게 판단할 수 있다. 문제가 생겼을 때, 탐색구간이 줄어들기 때문에 문제해결도 그만큼 빨라진다.

개발 진행 상황을 파악할 수 있다.

개발 진행 상황을 파악해서 적절히 대처할 수 있다. 예를 들어 다른 개발파트와의 연동을 위해서 기본 기능을 충족하는 프로그램을 제공해야 한다고 했을 때, 어느 부분을 개발해야 할지 알수 있다. 위의 예제 순서도에서 에러처리와 ThreadCheck 흐름을 보완하면, 연동에 필요한 수준의 프로그램을 만들 수 있음을 판단할 수 있다. 마찬가지로 개발이 지지부진한 흐름을 파악해서, 일정을 조정하거나 해당 흐름의 모듈을 분리개발하거나 등의 정보를 얻을 수 있다.

TDD의 단점을 보완할 수 있다.

TDD의 가장 큰 단점은 알면서도 사용하지 않는 다는 점이다. 그게 좋다는 것과 그걸 실천하는 것은 별개의 문제다. 습관적으로 정신없이 코드를 개발하다 보면, 테스트를 해야 한다는 걸 알면서도 나중에 모아서 하지머하면서 그냥 지나치기는 경우가 허다하다. 간만에 코딩 진도 쫙쫙 나가는데, 지금 테스트를 진행하면 왠지 흐름이 끊길 것 같고 시간낭비할 것 같은 생각에 건너뛰기도 한다.

그건 TDD의 문제가 아니고 사람의 문제니 사람을 족치면 된다!? 라는 것은 공허한 외침이다. 사람이 도구를 사용하는 거지, 도구가 사람을 사용하는 것은 아니기 때문이다. 도구가 좋은 줄 알면서도 사용하지 않는다는 것은 그 도구에 무언가 문제가 있다는것을 의미한다.

예컨데, 지금 당장 편한 것을 찾고자 하는 인간의 습성 때문에 TDD가 잘 적용되지 않고 있다고 가정해 보자. 이것을 사람의 문제로 보고 사람을 족친다고 해서 문제가 해결될까 ? 극히 예외적인 경우를 제외하고 거의 대부분 해결되지 않는 다는 것을 오랜 경험으로 알고 있을 것이다. 사람의 습성은 그리 쉽게 바뀌는게 아니다.

이 경우 TDD가 잘 적용되지 않는 것은 그 도구의 문제로 보고 도구를 보완할 대책을 찾는게 낫다는게 개인적인 생각이다.

TDD를 잘 사용하지 않는 문제는 지금 당장 사람을 너무 귀찮게 한다는 점과 단위 모듈에 너무 집착하게 만든다는 점이다. 사람은 얼기 설기 만들어진 것일지언정 일단은 눈에 돌아가는 것을 보는데에서 재미를 느끼는 법이다. 흐름 기반은 일단 뼈대를 만든다음 뼈대를 완성시키는 방향으로 프로젝트가 진행된다. 결과를 볼 수 있으며, 결과가 점점 나아지고 있다는 것을 시각적으로 체감할 수 있다. 그리고 어차피 흐름을 만족시키려면 흐름에 위치하고 있는 모듈을 완성시켜야 하니 그 와중에 모듈에 대한 유닛 테스트를 진행하는 식으로 TDD를 적용하게 된다. 테스트를 위한 테스트가 아닌 프로그램을 완성시키기 위한 테스트라는 느낌이 든다고나 할까 ? 뭐 그런 느낌을 가질 수 있다.