336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.
마틴 파울러는 그의 저서인 ‘리팩토링’에서 리팩토링을 다음과 같이 정의했습니다.

“리팩토링은 외부의 동작을 바꾸지 않고 내부의 구조를 개선하는 것”

검증의 시각에서 이 정의를 볼 때 우리가 리팩토링을 하며 개선 외에 추구해야 할 또 다른 목표를 알 수 있습니다. 바로 리팩토링을 하더라도 외부의 동작을 바꾸지는 않는 것입니다. 다시 말해 리팩토링을 어떻게 하든 예전의 동작은 그대로 유지되어야 합니다. 지난 글에서 이 부분을 ‘검증’이라 불렀습니다. 검증을 하려 하다 보면 항상 반복적으로 고려하는 요소가 있음을 알게 됩니다. 바로 영향력 검토, 검증방법 결정, 검증시점입니다.

영향력 검토는 내가 수행하는 리팩토링이 어디에 영향을 미치는지 확인하는 단계입니다. 예를 들어 사용자가 남자이면 True를 반환하는 메서드가 있고 이 메서드는 프로젝트 전반에 걸쳐 광범위하게 사용되고 있다고 가정해봅시다. 이때 리팩토링 중 실수로 남자임에도 False가 반환되게 되었습니다. 이때 프로젝트에는 어떤 영향이 미칠까요? 아마 이 메서드를 사용하는 모든 곳의 기능이 정상적으로 동작하지 않을 것입니다. 이것이 바로 해당 메서드가 가지고 있는 영향력이며, 우리는 리팩토링 전에 이 영향력을 반드시 알아내야 합니다. 때로 리팩토링 시 내가 변경하는 곳으로 인해 생기는 영향력에 대해 정확히 파악하기가 어려운 경우가 있습니다. 이런 경우는 정확한 검증을 할 수 없다는 뜻과 동일하기 때문에 영향력을 파악하기 전에는 리팩토링 진행을 멈추는 것이 좋습니다,

그 다음으로는 검증방법을 결정해야 합니다. 특정 부분을 리팩토링 한 후에 이 부분의 동작이 예전과 정확히 동일한지를 실제로 검사하는 단계입니다. 예를 들어봅시다. F를 리팩토링 할 예정입니다. 이 부분은 기능 A와 B에 영향을 미칩니다. 따라서 리팩토링 후 A와 B에 대한 기능을 테스트 인력이 검토하기로 했습니다. 이 예는 영향력 검토를 하고 검증방법을 결정하는 예를 보여줍니다. “A와 B에 대한 기능을 테스트 인력이 검토하기로 했다” 부분이 검증방법을 결정한 것이라 볼 수 있습니다. 예에서처럼 테스트 인력이 검증할 수도 있지만 자동화 된 단위 테스트 등을 이용할 수 있습니다.

마지막으로 검증시점에 대한 고려가 필요합니다. 검증시점은 말 그대로 검증을 수행하는 시점을 뜻합니다. 앞선 내용에서 이미 언급했지만 보다 빠르게 검증하는 것은 비용 면에서 많은 유익을 줍니다. 지난 글에서는 표를 이용하여 개발 중, QA 중, 서비스 중으로 나눠서 설명을 했었는데 이 것은 서비스 흐름 관점의 구분이라 볼 수 있습니다. 좀 더 기술적으로는 컴파일 시점과 실행 시점으로 분류해볼 수 있습니다. 이 경우 컴파일 시점(Compile Time)이 실행 시점 보다 이르며 따라서 문제는 컴파일 시점(Runtime)에 발견되는 것이 좋습니다. 이 점은 컴파일러 검증의 필요성을 나타냅니다. 또한 실행 시점 중에서도 고객에게 서비스를 하고 있는 실행 시점보다는 테스트를 수행하고 있는 실행 시점에 문제가 발견되는 것이 더 좋습니다. 이 점은 단위 테스트와 CI서버 도입의 필요성을 나타냅니다.

위 세 가지 점에 대해 고려한 후에는 리팩토링을 하기 위해 필요한 비용과 리팩토링 후 검증을 하기 위해 필요한 비용, 즉 리팩토링에 대한 투자비용을 생각해볼 수 있습니다. 투자비용을 생각해보는 이유는 리팩토링 또한 일종의 투자이기 때문입니다. 리팩토링은 현재 어떤 노력을 기울여 이후의 유지보수 등의 노력을 적게 들이려는 노력의 일환입니다. 그렇기 때문에 리팩토링에 대한 투자비용을 따져보고 우리가 투자를 할 때 의례 하듯이 이 투자로 인해 얻어질 거라 생각하는 이익보다 투자비용이 크다고 판단한다면 리팩토링을 진행할지에 대해 다시 한번 생각해보는 것이 좋습니다. 또한 투자의 관점에서 리팩토링을 보면 적게 투자해서 많이 얻는 것도 중요합니다. 주식투자에서 이것을 가능하게 가능 것이 저 평가 된 우량주를 발견하는 것이라면, 리팩토링에서는 아래 그림과 같이 영향력과 검증방법에 따른 비용을 줄이고 검증시점을 앞당기는 것이 적게 투자해서 많이 얻는 열쇠라 할 수 있습니다.


그림#1. 영향력, 검증비용을 감소시키고 검증시점을 앞당기는 것

수정 이력
2010/05/07 : 이 주제가 여러 편에 걸쳐 게시되었기 때문에 내용이 중복되지 않고 읽는이가 부드러운 흐름을 타게하기 위해 내용을 다소 수정합니다.

WRITTEN BY
차민창
르세상스 엔지니어가 사회를 이끌어나가는 상상을 하며!

,
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.
최근 진행했던 두 번의 프로젝트는 내게 무척 새로운 프로젝트였습니다. 왜냐하면 프로젝트의 목적이 특정 기능의 개발이 아닌 기존 코드의 리팩토링이었기 때문입니다. 첫 프로젝트를 진행할 때 저의 최초 관심은 '개선'이었습니다. 어떻게 하면 소스를 좀 더 유지보수하기 좋게 만들 수 있을까? 하지만 실제로 프로젝트를 시작하고 전반적인 작업의 진행을 시작하자 저의 관심은 개선에서 점차 '검증'쪽으로 향하게 되었습니다. 왜냐하면 개선을 하며 자연스레 발생하는 영향력이 어마어마하다는 것을 깨달았기 때문입니다. 좋은 예로써 핵심 클래스의 인터페이스를 수정해야 하는 경우가 있었습니다. 그런데 그 수정으로 인해 영향 받는 부분을 살펴보자 영향 받는 하위 프로젝트만도 10개[1]가 넘었습니다. 따라서 개선도 개선이지만 검증을 성공적으로 하는 것이 매우 중요하게 느껴졌습니다.

어떻게 하면 검증을 성공적으로 할 수 있을까? 가장 먼저 생각난 것은 QA(Quality Assurance)였습니다. 제가 일하는 환경에는 능력이 매우 뛰어난 QA부서가 있었고, 사내 표준 프로세스상 배포해야 하는 모든 제품은 반드시 QA를 거쳐야 했습니다. 따라서 열심히 리팩토링을 한 후 QA에게 검증을 요구하는 것은 매우 자연스러운 일이었습니다. 하지만 곰곰이 생각해볼 때 몇 가지 면에서 문제를 느꼈습니다.

첫째는 위에서 얘기했던 것처럼 영향 받는 범위가 매우 크다는 점이었습니다. 제가 일하는 환경의 QA는 보통 블랙박스 관점으로 기능 중심의 검증을 수행했습니다. 따라서 보통의 경우 개발자가 특정 부분을 수정하면 수정한 부분으로 인해 영향 받는 기능을 QA에게 이야기 했습니다. 이 경우 QA는 매우 기본적이며 핵심적인 주요 기능에 대한 검증을 진행하는 것과 더불어 수정으로 인해 영향 받은 기능을 추가적으로 검증했습니다. 하지만 제가 진행했던 리팩토링의 경우 위와 같은 방법으로 수정범위를 얘기하려고 하면 거의 모든 기능을 검증 해달라고 말해야 했습니다. 왜냐하면 위에서 얘기했듯이 영향력이 어마어마했기 때문입니다. 더욱이 당시 QA 자원이 많이 부족한 상태였는데 거의 모든 기능에 대해 검증해달라고 말하는 것은 바람직하지 못해 보였습니다.

둘째는 문제 발견 시점에 따른 비용증가 때문이었습니다. FEDEX에는 1-1-100원칙이 있습니다. 이 원칙은 제품을 출고하기 전에 문제를 발견하면 비용이 1만 필요하지만 출고 후에는 10의 비용이 필요하며 고객에게 항의가 들어오면 100의 비용이 필요하다는 원칙입니다. 이 원칙은 소프트웨어에도 그대로 적용된다고 봅니다. 아래 표는 실제 내가 일하는 환경에서 발생하는 현상을 바탕으로 작성했습니다.

 문제 발견 시점  관련 자원(문제 처리 비용)
 개발자가 개발 중  담당 개발자
 QA 중  BTS(Bug Tracking System)
 외부와 의사소통 담당하는 개발자
 담당 개발자
 배포 후 서비스 중
 고객
 문제/장애 알림 시스템
 서비스 기획자
 서비스 운영 책임 개발자
 BTS(Bug Tracking System)
 담당 개발자
 QA
 배포 담당자(재배포가 필요하기 때문에)

각 환경에 따라 다소 차이는 있겠지만 큰 맥락에서 위 표와 크게 다르지는 않을 것이라 생각합니다. 위 표를 보면 FEDEX 원칙과 유사하게 문제가 늦게 발견되면 될수록 처리하는 데 필요한 관련 자원이 증가함을 볼 수 있습니다. 따라서 특수한 환경이 아니라면 QA 단계에서 문제를 발견하는 것 보다는 개발자가 문제를 발견하는 것이 조직 전체 비용 관점에서는 유리합니다.

마지막으로 QA가 탐지하기 어려운 영향력이 있다는 점 때문입니다. 위에서 잠시 애기했듯이 QA는 블랙박스 관점으로 기능중심의 검증[2]을 수행합니다. 이 경우 화면으로 즉시 보여지는 부분에 대해서는 매우 높은 수준의 검증이 가능합니다. 예를 들어 화면상의 특정 부분이 일그러져 보이거나, 확연히 구분할 수 있게 문자 등으로 오류가 보이는 등의 문제점입니다. 하지만 월말이 되어 통계 화면에서 보여지는 데이터의 입력이 누락되거나 하는 문제는 발견하기 어렵습니다. 이러한 문제는 외부로 즉시 드러나지 않기 때문입니다.

따라서 저는 QA에게 모든 검증을 의존하는 것은 좋지 못한 선택이라고 생각합니다. 그것보다는 개발자가 최전방에서 적극적으로 보다 많은 검증을 수행해야 한다고 봅니다. 물론 QA를 배제할 생각은 없습니다. 다만 일차적으로 개발자가 나름의 방법으로 검증을 먼저 진행한 후 이차로 QA가 검증하는 이중검증이 더 좋은 결과를 만들 것이라 생각합니다. 이중검증은 동일한 문제를 전혀 다른 방법으로 검증하여 검증의 정확도를 더욱 높이는 방법입니다. 일반적으로 개발자와 QA의 시각은 많이 다른 편이기 때문에 각자가 생각하는 최선의 방법으로 이중검증[3]을 하면 분명히 긍정적 효과가 있으리라 봅니다.

참고 설명

[1] 제가 리팩토링을 진행했던 프로젝트는 공통 라이브러리 성격의 프로젝트였습니다.
[2] 제가 일하는 환경에는 QA가 블랙박스 테스트만 하지만, 개발자 출신의 QA가 코드검토와 같은 화이트박스 테스트를 진행하는 곳도 있다고 합니다.
[3] 켄트벡의 익스트림 프로그래밍이라는 책에 보면 재확인(Double Checking) 원칙이 소개됩니다. 이 원칙은 문제를 해결할 때 전혀 다른 방법 두 가지로 각각 문제를 해결한 후에 결과를 비교해 보아 결과의 정확성을 보장하는 방법입니다. 마찬가지로 개발자는 개발자의 관점에서 QA는 QA의 관점에서 각기 다르게 검증을 수행한다면 좀더 정확한 검증을 할 수 있을 것이라 생각합니다.

수정 이력
2010/05/07 : 이 주제가 여러 편에 걸쳐 게시되었기 때문에 내용이 중복되지 않고 읽는이가 부드러운 흐름을 타게하기 위해 내용을 다소 수정합니다.

WRITTEN BY
차민창
르세상스 엔지니어가 사회를 이끌어나가는 상상을 하며!

,
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.
최근 리팩토링 경험담이라는 시리즈 글을 쓰고 있습니다. 해당 시리즈 글의 흐름상 이 글의 내용이 부분적으로 들어가게 되어 아래 글을 해당 문백에 맞도록 약간의 수정을 하고 이동시키게 되었습니다. 원래 글의 내용은 취소선을 그어 남겨놓았으며, 내용은 거의 유사하오니 가능하면 아래 링크를 통해 해당 글과 관련 글을 읽어보시기를 추천드립니다. 불편을 드려 죄송합니다.

이동한 주소 리팩토링 경험담 #8 - 검증시점을 앞당기기 위한 빠른 실패

올해 초 저는 서버에서 발생하는 NullPointerException를 수정하는 업무를 하게 되었습니다. 로그를 보니 다양한 상황에서 다양한 형태로 NullPointerException이 발생하고 있었습니다. 그런데 업무을 진행하며 문제를 분석하다보니 그동안 어렴풋이 생각하던 부분이 좀더 명확해졌고 저는 이번 글에서 당시 했던 생각을 나눠보고자 합니다.

아래는 오류의 원인을 찾고있는 한 개발자의 가상사례입니다.
어느날 한 개발자가 웹 애플리케이션의 오류로그를 살펴봅니다. 그런데 데이터베이스에 나이를 저장하는 쿼리 부분에서 제약조건위배 오류가 발생하고 있습니다. 오류에 대해 자세히 살펴보니 나이 필드에 NOT NULL 제약이 걸려있음에도 Null 값이 입력되고 있다는 내용입니다. 곧바로 쿼리 부분에 문제가 있나라는 생각이 머리에 스칩니다. 소스를 재빨리 찾아 쿼리에 값을 넣어주는(Binding) 부분을 자세히 살펴봅니다. 그런데 큰 문제가 없어보입니다. 자연스럽게 비즈니스 레이어(Business Layer)를 살펴보게 됩니다. 혹시 나이 부분에 대해 뭔가 다루는 부분이 있나 자세히 살펴봅니다. 하지만 특별한 것을 발견하지 못합니다. 마지막으로 프리젠테이션 레이어(Presentation Layer)를 살펴봅니다. 그리고 프리젠테이션 레이어에서 나이 값이 잘 들어왔는지에 대한 검사를 하고 있지 않다는 것을 발견합니다. 거의 이 부분이 원인일 것이라 생각하지만 확신할 수는 없습니다. 왜냐하면 프로그래밍에는 너무 다양한 상황이 있다는 것을 알고 있기 때문입니다. 

2010/02/18 추가 
위의 경우는 오류로그가 Stacktrace를 포함하지 않는 경우에만 유효한 이야기입니다. 왜냐하면 Stacktrace를 볼 수 있다면 원인을 금방 알아낼 수 있기 때문입니다. 따라서 좀 억지스럽지만 Stacktrace를 찍지 않았다고 가정한 경우로 생각하시고 본래 전달하고자 하는 의미에 집중해주시면 좋을 것 같습니다.

위의 예를 통해 저는 두 가지 문제점을 봅니다. 첫 번째는 개발자가 원인을 조사하기 위해 여러 파일들을 살펴보아야 했다는 점입니다. 두 번째는 시간을 들여 여러 파일을 살펴보았음에도 불구하고 명확한 결론이 아닌 거의 확실한 추정 정도의 수준에서 조사를 끝낼 수 밖에 없다는 것입니다.  

여기서 위 사례에 한 가지 가정을 더해보겠습니다. 마지막에 개발자가 추정한 것이 실제원인이였다는 가정입니다. 이 가정 하에서 보면 위와 같이 일을 어렵게 만든 원인을 알 수 있습니다. 바로 '오류 희석'입니다.

널리 사용되거나 공식적인 용어는 아니지만 오류 희석은 시간 혹은 공간을 지남에 따라 오류가 본래의 모습을 점점 잃어버리는 것을 뜻합니다. 위 사례의 경우 근본 원인은 사용자가 나이를 입력하지 않았다는 것입니다. 하지만 실제적으로 문제는 프리젠테이션 레이어와 비즈니스 레이어를 지나 데이터베이스에 질의하는 부분에서 전혀 다른 모습으로 발생하였습니다. 그 결과로 개발자는 문제를 찾기위해 문제가 발생한 지점 까지 도달할 수 있는 모든 경로를 역추적해야 했습니다. 

그렇다면 해결책은 무엇인가요? 해결책은 무척 간단합니다. 바로 프리젠테이션 레이어에서 나이가 정확히 들어오는지를 검사하고 만약 나이가 정상적으로 들어오지 않는다면 엄격하게 예외처리를 해주면 됩니다. 사용자에게 '나이를 입력해주세요.'라는 문구를 보여줄 수도 있고, 바로 에러를 발생시켜 처리를 중지할 수도 있습니다. 이렇게 처리한다면 문제가 발생했을 때 사용자든 개발자든 문제를 정확히 알 수 있습니다. 특히 개발자가 에러로그를 보았을 경우 개발자는 소스 파일을 탐색하거나 추정을 할 필요가 없습니다. 왜냐하면 에러로그 그 자체만으로도 무슨 문제인지 너무나도 명확하게 알 수 있기 때문입니다.

Fedex에는 1-10-100 원칙이라는 것이 있다고 합니다. 간단히 설명하자면 문제를 조기에 처리하지 않으면 처리비용은 점점 증가한다는 것입니다. 저는 소프트웨어 개발의 많은 부분에서도 동일한 원칙이 적용된다고 봅니다. 문제가 발생했을 때 그 문제가 시간 혹은 공간을 지나기 전에 가능한 빨리 인지하고 처리하면 보다 낮은 비용으로 처리가 가능하지만, 그렇지 못했을 경우에는 위 가상사례와 같이 더 많은 비용이 필요하게 되는 것입니다. 특히 S/W분야에서는 추구하는 방향 관점에서 보았을 때 빠른 실패(Fail-Fast)가 Fedex의 1-10-100 원칙과 유사점을 가집니다. 좌측 링크가 걸린 위키피디아 내용에서 직접적으로 언급되지 않았습니다만, 필요한 곳에서 적절히 사용된 빠른 실패는 많은 비용을 줄일 수 있을 것입니다.

하지만 주의해야 할 점은 모든 곳에서 빠른 실패가 필요하지는 않다는 점입니다. 때로는 문제 혹은 결함을 허용하는 것이 매우 중요한 일인 경우가 있습니다. 예를 들어 포털의 메인화면을 생각해볼 수 있습니다. 포털의 메인화면은 매우 다양한 구성요소로 이루어져 있습니다. 그런데 그 중 우측 하단 쇼핑 정보를 가져오는 부분에 문제가 생겼다고 가정을 해봅시다. 이 경우 화면을 보여주기 위한 모든 처리를 중지한 후 화면을 표시하지 않는 것 보다는 그 부분을 제외하고 다른 부분은 정상적으로 보여주는 것이 현명한 판단일 것입니다. 

2009/05/06 ~ 2009/12/02




'

WRITTEN BY
차민창
르세상스 엔지니어가 사회를 이끌어나가는 상상을 하며!

,
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.
많은 프로젝트에서 문서화를 합니다. 문서화는 프로젝트 중간에 진행되기도 하지만 보통 프로젝트 종료 후 진행 됩니다. 제가 보기에 문서화의 필요성에 대해서는 많은 사람이 공감하고 있는 듯 합니다. 그렇지만 그 사람들에게 문서화를 통해서 만들어진 문서가 실제로 도움이 되었느냐 묻는다면 얼마나 고개를 끄덕일지 모르겠습니다. 우리는 경험적으로 그동안 보아왔던 문서들은 큰 도움이 되지 않는다는 것을 알고 있습니다. 도대체 왜 이러한 일이 발생하나요? 

제가 생각했던 가장 큰 문제는 문서에 너무 많은 내용을 담으려고 한다는 것입니다. 보통 문서화에 할당되는 시간은 한정되어 있습니다. 그런데 보통 문서화를 요구하는 사람들은 개발 프로세스로부터 정의 된 몇 가지 고정된 필수항목들을 요구합니다. 이런 경우 한정된 시간에 문서화를 완료하려하다보면 자연스레 구색만 맞춘 문서가 만들어집니다. 전달하고 싶은 내용이 있어도 적절한 항목이 없거나 시간이 없어서 못 만드는 경우도 있습니다. 이렇게 만들어진 문서를 읽다보면 어려움을 느낄 때가 많습니다. 조금 읽어보면 내가 필요로 하는 정보는 찾을 수 없고 다른 정보만 잔뜩 들어있기 때문입니다.

그 다음은 변화하지 않는 문서입니다. 즉, 소프트웨어는 변했는데 문서는 변화하지 않는 경우입니다. 이런 문서에 근거하여 어떤 일을 진행하다 많은 시간을 허비하거나 문제를 일으키는 경우가 있습니다. 왜냐하면 문서의 내용이 잘못 되어있기 때문입니다. 사실 이런 문서라면 아예 없는 것이 나을 수도 있다고 생각합니다. 왜냐하면 문서가 없다면 해당 일을 진행할 때 자체적으로 조사를 해서 더 원활히 일을 진행할 수도 있기 때문입니다.

사실 위에서 얘기했던 왠만한 개발자라면 누구나 알만한 매우 기초적인 문제점들에 대한 지적입니다. 오히려 중요하지만 제가 미처 언급하지 않은 문제점이 있을 수도 있겠지요. 아무튼 위와 같은 문제점을 지적했느니 저는 제가 생각하는 효율적인 문서화에 대해서 얘기해보고자 합니다.

제가 생각하는 효율적 문서화의 구조는 크게 두 가지 부분으로 나눌 수 있습니다. 첫 번째 부분은 잘 변하지 않는 즉 가장 추상화 된 부분을 다루는 소프트웨어 구조에 대한 문서입니다.

예)
설계 배경
설계에 대한 근거
주요 구성요소의 역활

위와 같은 내용은 거의 변하지 않습니다. 왜냐하면 소프트웨어를 만들 때의 배경과 설계 근거는 이미 과거에 일어난 사실이기 때문입니다. 또한 소프트웨어의 주요 구성요소도 정말 큰 변화가 없는한 그대로 유지됩니다. 이것은 이 문서가 한번 만들어지면 문서의 유지보수에는 더 이상 크게 신경쓰지 않아도 된다는 것을 뜻합니다.

위 문서의 목표는 유지보수 하는 개발자가 문서를 보았을 소프트웨어에 대한 전반적 이해를 가질 수 있게 하는 것입니다. 만약 해당 개발자가 이 문서를 통해 제대로 된 이해를 갖게 할 수 있다면 나머지 세부적으로 파악해야 할만한 내용은 해당 개발자가 코드를 보며 빠르게 파악할 수 있을 것입니다. 그렇지만 누군가는 이런 의문을 제기할 수도 있습니다.

당장 1시간 안에 접근 허용 IP 목록을 추가해야 할 때는 어떻게 합니까? 구조를 아직 파악하지 못했다면요? 혹 구조를 파악했다 하더라도 신속히 수행하기 힘들지 않나요?

예, 이런 문제를 보완하기 위해 두 번째 문서가 존재해야 합니다. 윈도우 운영체제 이론에 정통한 교수님이라 하더라도 윈도우의 창의 폰트를 바꾸는 법을 찾기 위해 1시간 이상 헤맬수도 있는 것이죠.

위와 같은 부분은 운영 문서에서 다루어야 합니다. 운영 문서는 철저하게 실용적이고 가장 구체적으로 구성되어 있어야 합니다. 또한 운영하는 입장에서 빈번히 필요할 만한 상황을 고려하고 있어야 합니다. 예를 들자면 아래와 같은 것들이 될 수 있습니다.

서버 시작하고 정지하기
접근 IP 추가하기
컴포넌트 추가하는 절차 및 방법

이렇게 두 개의 문서가 구성된 후 유지보수 하는 개발자는 선택을 할 수 있습니다. 해당 소프트웨어의 이슈가 많지 않아 최소한의 운영만 해주면 된다면 굳이 시간을 들여 구조에 대한 문서를 보지 않고도 운영에 대한 문서를 필요 시마다 참고할 수 있습니다. 만약 운영 문서에서 다루지 않는 문제가 발생한다면 스스로 해결 후 문서를 수정해주면 됩니다. 하지만 만약 해당 소프트웨어에 이슈가 많고 장기적으로 많은 수정과 개선이 필요하다면 구조 문서를 숙지하면 됩니다. 구조에 대한 확실한 이해를 바탕으로 소프트웨어를 견고하게 유지보수 하고 개선해 나갈 수 있을 것입니다. 

이러한 방식으로 문서화를 했을 때 서두에서 제기했던 문제들도 어느정도 해결 될 수 있습니다. 첫째로 얘기했던, 문서에 너무 많은 내용을 담으려 할 때 생기는 문제는 위에서 제가 얘기한 구조를 채택함으로써 자연스레 해결될 수 있습니다. 두 개의 문서만 만드는 접근 방식은 그동안 보아왔던 보편적 문서화와 비교할 때 문서량이 매우 적습니다. 또한 특별한 필수 형식을 요구하지 않기 때문에 문서화를 하는 사람은 자신의 판단에 근거하여 전달하고 싶은 부분을 중점적으로 문서를 만들 수 있게 됩니다.

두 번째 변화하지 않는 문서의 문제 역시 많이 경감될 수 있습니다. 왜냐하면 위 구조의 경우 운영문서만이 변화에 대한 영향을 받기 때문입니다.


#그림1. 소프트웨어 문서화 대상

결론적으로 제가 주장하고 싶은 부분은 위 그림과 같이 소프트웨어의 양극단만을 문서화 하자는 것입니다. 소프트웨어의 개발 흐름을 보면 아이디어로 부터 시작되어 소프트웨어 구조 작업이 시작 됩니다. 그 후 구현 코드가 만들어지고, 마지막으로 구현 코드를 쉽게 작동시킬 수 있는 운영 도구가 나옵니다. 이 때 우리는 구현 코드와 같이 자주 변하면서도 문서화 했을 때 큰 가치를 주지 못하는 중간 영역을 문서화 하려고 노력하기 보다는 잘 변하지 않는 소프트웨어 구조와 구체적인 운영 도구에 대한 설명에 집중함으로써 최소한의 노력으로 최대의 효과를 거둘 수 있을 것입니다.

2009/03/16 ~ 2009/10/19

수정 이력
2009/10/19 22:30 : 전반적으로 문장을 부드럽게 고침.

WRITTEN BY
차민창
르세상스 엔지니어가 사회를 이끌어나가는 상상을 하며!

,
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

저는 현재 회사에서 실무자로 일하고 있습니다. 일을 하며 관리자들에게 종종 아쉬움을 느낄 때가 있습니다. 이런 아쉬움은 여러 가지 사건들을 경험하며 생기는데요, 저는 앞으로 이러한 아쉬움들을 제 시각에서 정리해보자 합니다.

첫 글로써, 최근에 생각해보았던 '관리자의 의견과 대립하는 실무자의 의견'라는 주제에 대해 써보고자 합니다. 때때로 실무자와 관리자 사이에 논쟁이 벌어질 때가 있습니다. 예를 들어 실무자는 A라는 안으로 일을 추진해야 한다고 강력히 주장하는 데, 관리자는 B라는 안으로 일을 추진해야 한다고 주장하는 경우를 생각해볼 수 있습니다. 왜 이런 일이 발생을 할까요?

제가 보기에 관리자의 의사결정은 보통 추상적인 수준에서 이루어집니다. 관리자는 현실적 여건상 세부적인 것들을 모두 상세히 알기가 힘듭니다. 따라서 마치 어떠한 현상을 숫자로 간단히 표현하는 것처럼, 세부적인 것을 좀더 단순한 형태로 변환하여 개념적으로 바라보고 그것을 바탕으로 의사결정을 합니다. 하지만 이로인한 부작용이 생깁니다. 왜냐하면 추상화라는 것은 사고할 때는 유용하지만 어찌됐던 세상은 구체적인 상황 속에서 돌아가고 있기 때문입니다. 관리자는 시간이 지남에 따라 추상적인 사고에 익숙해지고,  결국 구체적인 부분에 대한 감각을 잃어버리게 됩니다. 이 경우 제가 보아왔던 관리자들이 취하는 행동은 크게 두 가지 정도가 있었습니다.

하나는 실무자의 의견을 존중하는 것입니다. 즉, 비록 실무자의 의견에 대해 깊이 이해할 수는 없지만 본인이 관리자로써 가지는 한계를 인정하고 이해를 시도하며 의사결정을 하는 것입니다. 이것은 관리자가 실무자를 현장 전문가로써 인정하고 신뢰한다는 것을 의미합니다.

다른 하나는 이해를 할 수 없기 때문에 실무자의 의견을 받아들이지 않고 추상적인 수준의 사고를 통해 나온 본인의 주장만을 거듭하는 것입니다. 이 경우 실무자는 포기하고 관리자의 의견을 따르거나, 아니면 관리자가 이해할 수 있게하기 위해 근거를 계속적으로 제시합니다. 하지만 저는 이러한 성향을 가지는 관지자가 실무자의 의견을 채택하는 경우를 거의 보지 못했습니다.

첫 번째 실무자를 인정하고 신뢰하는 관리자의 경우는 제가 보아온 가장 좋은 사례로써 저는 더 이상 할 얘기가 없습니다. 물론 실무자의 의견에 근거하여 의사결정을 한후 잘못된 방향으로 갈 수도 있습니다. 어쨌든 관리자는 실무자보다 더 많은 정보를 가지기 때문에 의사결정에 있어 더 나은 통찰력을 가지는 경우가 많기 때문입니다. 하지만 비록 때로 실패가 있다 하더라도 관리자가 실무자를 인정하고 신뢰한다면 실무자는 어떠한 형태로든 그것을 보답한다고 봅니다. 그것이 강한 책임감의 형태로 나타나든 혹은 자신감으로 인한 적극적인 업무자세로 나타나든 말입니다. 결국 실패로 잃어버린 것보다 더 많은 유익을 얻을 수 있을 것입니다.

두 번째 본인의 주장만을 거듭하는 관리자의 경우가 참 어려운 경우입니다. 이 경우 다행히 합리적인 관리자는 본인이 이해할 수 있도록 근거를 요구합니다. 하지만 이 때도 두 가지 정도의 문제점이 있습니다. 첫째는 근거를 제시하는 것에 미숙한 실무자들이 많다는 점입니다. 이것은 실무자의 문제로써 다른 말로 하자면 의사소통 능력이 떨어진다고 볼 수 있습니다. 둘째는 실무자가 근거를 잘 제시함에도 불구하고 관리자가 받아들이지 않는 경우입니다. 이런 경우는 관리자가 실무를 제대로 이해하지 못하기 때문에 발생합니다. 첫째 문제에 대해 제가 생각하는 해결책은 실무자가 노력해야 한다는 것입니다. 의사소통은 실무자가 신경 쓰지 않아도 될 부분이 아니라고 생각합니다. 오히려 실무자들이 의사소통 능력의 중요성을 인식하고, 본인이 갖춰야 할 매우 기본적인 능력 중 하나로 생각하는 것이 필요하다고 봅니다. 둘째 문제는 관리자의 변화가 필요하다고 생각합니다. 가장 이상적인 모습은 관리자가 실무에 대한 이해의 폭이 넓어 실무자와 원활한 의사소통을 하는 것이라고 봅니다. 하지만 현실적 여건으로 인해 실무를 제대로 이해하지 못한다면 본인의 한계, 즉 추상적인 사고의 한계를 겸허히 인정하고 구체적인 것을 항상 다루는 실무자의 의견을 존중하는 것이 해결책이 될 수 있을 것이라 생각합니다.


WRITTEN BY
차민창
르세상스 엔지니어가 사회를 이끌어나가는 상상을 하며!

,
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.
'나누어 해결하기'는 많은 사람들이 익히 잘 알고 있는 매우 친숙한 문제해결지침입니다. 친숙한 만큼 개념 또한 매우 간단합니다.

In computer science, divide and conquer (D&C) is an important algorithm design paradigm based on multi-branched recursion. A divide and conquer algorithm works by recursively breaking down a problem into two or more sub-problems of the same (or related) type, until these become simple enough to be solved directly. The solutions to the sub-problems are then combined to give a solution to the original problem.

출처 : http://en.wikipedia.org/wiki/Divide_and_conquer_algorithm

(위 위키 페이지에서는 나누어 해결하기가 가진 여러 가지 장점들을 얘기하고 있습니다. 이 글은 그 중 'Solving difficult problems' 에 대한 상세한 내용이라고도 볼 수 있습니다.)


이렇게 단순한 개념이라 그런지 몰라도 제게는 왠지 현실과 거리가 있는 개념으로 보였습니다. 예를 들어 누군가 "소프트웨어 개발을 잘하는 방법이 무엇인가요?"라고 물어보았을 때 "잘 개발해라"라고 대답해주는 느낌이라고 할까요. 그렇지만 얼마 전 저는 '나누어 해결하기'가 가진 아름다움에 대해 엿보는 경험을 하게 되었습니다. 그래서 이번 글에서 나누어 해결하기에 대해 제가 본 부분을 써보고자 합니다.

소프트웨어 개발을 하다보면 필연적으로 어려운 문제를 만나게 됩니다. 설계를 하다 어려운 문제를 만나기도 하고 코딩을 하다 어려운 문제를 만나기도 합니다. 때때로 이러한 문제들은 절망스럽게 느껴집니다. 문제가 복잡하면 머리가 아프고 어디서부터 시작해야 할지 감이 잡히지 않을 때가 있습니다.  예전 개발에 익숙하지 않은 시절에 저는 복잡하고 어려운 문제를 만나면 허둥될 수 밖에 없었습니다. 문제 해결을 시도하면 할수록 문제가 해결되어 간다는 느낌보다는 오히려 문제가 더욱 복잡해지는 듯한 느낌을 받았습니다. 그 늘어가는 복잡함에 기가 질려 결국 프로젝트를 포기한 적도 몇번 있었습니다. 저는 당시 왜 이런 일이 일어나는지 알 수가 없었습니다.

다행히 경험이 쌓이면서 복잡한 문제를 해결하지 못하는 일은 점점 줄어들어 갔습니다. 하지만 여전히 저는 예전에 복잡한 문제를 잘 해결하지 못했던 이유에 대해 명확히 알 수 없었습니다. 그냥 경험을 쌓다보니 문제해결능력이 향상 되었구나라고 생각했습니다. 이렇듯 무의식 속에 지내던 저는 얼마전 실마리를 찾게 되었습니다. 바로 경험이 쌓임에 따라 자연스레 나누어 해결하기를 사용해왔다는 사실이였습니다.

우리는 소프트웨어를 개발할 때 구조를 설계합니다. '이 시스템을 구현하려면 A,B,C 세 부분이 있으면 되겠네.'라고 얘기합니다. 이것이 바로 나누어 해결하기 입니다. 시스템 구현이라는 문제를 해결하기 위해 문제를 A,B,C로 나누었고 A,B,C는 시스템 구현이라는 문제를 해결하기 위해 상호작용합니다. 서두에 소개한 위키피디아의 나누어 해결하기 정의와 같습니다. 또한 하나의 클래스를 만들 때 우리는 해당 클래스가 지향하는 목적을 달성하기 위해 여러 메서드를 만듭니다. 이것 역시 나누어 해결하기의 예라고 볼 수 있습니다.

좀더 큰 관점에서 소프트웨어 개발이라는 것은 추상적인 아이디어로 시작하여 소프트웨어 구조 그리고 소프트웨어의 코드들로 점점 구체화 되가는 과정이라 볼 수 있습니다. 이 과정에서 나누어 해결하기가 계속적으로 사용됩니다. 이 때문에 소프트웨어 개발을 잘한다라는 것은 결국 나누어 해결하기를 잘 한다라고 보아도 무방할 것 같습니다.

더욱 흥미로운 것은 나누어 해결하기는 소프트웨어의 세계를 뛰어넘어 실세계의 많은 부분에서 적용될수 있고 실제로 무의식적으로라도 사용되고 있는 강력한 문제해결지침이라는 것입니다. 예를 들어 우리가 가계부를 적을 때 주별로 혹은 월별로 소계를 내서 총계를 구합니다. 즉 총계를 구하기 위해 그것을 작은 단위로 나누어 각각을 해결한 후에 소계를 더하는 방법으로 원래의 문제를 해결한다는 것입니다. 이것은 소프트웨어에서 사용하는 나누어 해결하기와 동일합니다. 또한 회사 조직도를 보며 나누어 해결하기를 발견할 수 있습니다. 회사의 목적을 위해 여러 부서들로 나누고 해당 부서들은 회사의 목적을 위해 상호작용 합니다. 이러한 조직도를 통해서도 나누어 해결하기의 철학을 엿볼 수 있습니다.

끝으로 나누어 해결하기 원칙에 대해 몰랐던 어떤 구독자가 이 글을 통해 나누어 해결하기를  배우고 이해한다 하더라도 갑자기 소프트웨어 개발을 잘 하게 되지는 않을 것 같습니다. 하지만 현재 직면한 복잡한 문제를 해결하기 위한 좋은 접근 방법은 될 수 있다고 생각합니다. 또한 '소프트웨어 개발은 나누어 해결하기의 연속이다.'라는 시각을 갖는 것은, 문제에 대해 체계적으로 접근할 수 있게 도와줄 것이라 생각합니다.

2008/05/13~2009/05/04



WRITTEN BY
차민창
르세상스 엔지니어가 사회를 이끌어나가는 상상을 하며!

,
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.
저는 개발에 재미를 느껴 개발자가 된 사람입니다. 그런데 언제부터인가 개발의 재미가 없어지기 시작했습니다. 좀더 정확히 말하자면 어떤 때는 개발이 재미있었지만 어떤 때는 재미가 무척 없었습니다. 이 때부터 저의 고민이 시작되었습니다. 왜 개발이 재미없어지는 것일까? 열정이 사라진것일까? 꽤 오랜 시간 고민을 했습니다. 그리고 저는 한 가지 결론에 이르게 되었습니다. 그것은 바로 제가 즐기고 좋아했던 것은 개발 공정 전체가 아니라 그 중 한 부분인 코드를 '쓰는' 일이였다는 사실입니다.

저는 글을 쓸 때 개발, 좀더 정확히 말하자면 코드를 쓸 때와 비슷한 즐거움을 느낍니다. 아마 그 이유는 글을 쓰는 것이 코드를 생산하는 것과 매우 유사한 일이기 때문일 것입니다. 코드를 다듬듯이 글을 다듬고, 코드의 구조를 생각하듯이 글의 구조를 생각합니다. 이것은 제가 생각하는 활동을 통해 무엇인가를 만들어내는 것을 좋아한다는 사실을 보여주는 증거라 생각합니다.

별거 아닌 깨달음이지만 이 깨달음을 얻는 것이 제게는 쉽지 않은 일이였습니다. 스스로를 돌아보고 내 자신을 알아가는 일은 무척 어려운 일이기 때문입니다. 짧은 인생, 가급적 재미난 일을 하며 시간을 보내면 좋을텐데 회사에서 스스로 원하는 재미를 찾기란 쉬운 일이 아닌 것 같습니다. 특히 주위의 다른 선배 개발자들을 보면 회사에서 인정 받으면 받을수록 코드를 쓰는 일과는 점점 멀어지게 되는 것 같습니다. 코드를 쓰는 것을 좋아하는 개발자의 입장에서는 조금은 받아들이기 어려운 현상입니다. :)

2009/02/07 ~ 2009/05/04

WRITTEN BY
차민창
르세상스 엔지니어가 사회를 이끌어나가는 상상을 하며!

,
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

최근 주위를 보면 개발자들 사이에서 코드 가독성에 대한 관심이 높아지고 있는 것 같습니다. 아마 켄트벡이나 마틴 파울러 같은 대가들이 자신의 블로그를 통해 코드 가독성의 중요성을 강조하고 있기 때문일 것입니다. 켄트벡이 최근에 쓴 Implmentation Pattern을 관통하는 핵심 아이디어 중 하나는 다른 개발자들과의 의사소통입니다. 즉, 내가 만든 코드에 담겨있는 의도를 다른 개발자에게 잘 전달할 수 있어야 한다는 것입니다. 또한 이에 관한 마틴 파울러의 명언이 있습니다. 바로 '좋은 프로그래머는 사람이 이해할 수 있는 코드를 만든다.'입니다.

저는 올해 들어 개인적으로 프로젝트를 시작했습니다. 프로젝트를 시작하게 된 여러 동기 중 하나는 이렇습니다. 저는 최근에 출시된 스포츠카를 사고 싶었습니다. 그런데 가격을 알아보니 제가 버는 돈으로는 구매는 하더라도 유지가 힘들다는 판단이 들었습니다. 힘이 빠졌습니다. 어떻게 하면 스포츠카를 살 수 있을까 생각해보았습니다. 제가 내린 결론은 스스로 더 많은 가치를 산출 해야한다는 것이였습니다. 결국 저는 재미 있으면서도 이후 저의 작은 꿈을 이루는 데 도움이 될 만한 것으로 Robust-Task개발을 생각해냈습니다. 좀 세속적이긴 하지만 재밌는 동기죠? ㅋ

동기야 어찌됐든 창의적인 코딩에 굶주려 있던 저는 저는 너무도 즐겁게 개발을 진행했고, 개발을 하며 여러 지인들에게 의견을 구했습니다. 여러 지인들의 보편적 의견은 아이디어는 괜찮다(하지만 난 참여 안 하겠다 ㅋ)는 것이였습니다. 그래도 괜찮아 보인다는 말에 힘을 얻어 진행하다보니 어제 'Robust-Task 0.1 concept' 버전을 릴리즈하게 되었네요.

Robust-Task의 주요 의도는 복잡하고 긴 업무흐름(Business Flow)을 가독성 좋은 코드로 표현하자는 것입니다. 예를 들어 어떤 작업을 실행하는데 3번 이상 실패하면 뭔가 특별한 처리를 해주어야 한다고 가정해봅시다. 머리 속에 어떤 유형의 코드가 떠오르시나요? Robust-Task를 이용하면 이런 작업을 구현할 때 아래와 같이 두 가지 유형의 표현이 가능합니다.

new ToBeFailedTask()
  .wrapByRetryFailover()
    .failover(new LoggingFailoverTask())
    .retryCount(3)
  .execute();
    
retryFailOver(
    task(new ToBeFailedTask()),
    failover(new LoggingFailoverTask()),
    retryCount(3)
).execute();


어떤가요? 간단한가요?

또한 순차적인 작업의 흐름에 대해 아래와 같은 표현도 제공합니다.

new TaskChain()
  .add(new GenesisCoupeTask())
  .add(new TuscanyCoupeTask())
  .add(new TiburonCoupeTask())
.execute();


위 코드는 추가된 순서대로 정확히 실행이 됩니다.

더욱 재밌는 것은 이 두 가지 형태를 결합할 수 있다는 점입니다. 예를 들어 아래와 같은 표현이 가능합니다.

new TaskChain()
  .add(new GenesisCoupeTask())
  .add(new TuscanyCoupeTask())
  .add(new TiburonCoupeTask())
.wrapByRetryFailover()
  .failover(new LoggingFailoverTask())
  .retryCount(3)
.execute();

retryFailOver(
    task(new TaskChain()
              .add(new GenesisCoupeTask())
              .add(new TuscanyCoupeTask())
              .add(new TiburonCoupeTask())),
    failover(new LoggingFailoverTask()),
    retryCount(3)
).execute();


위 예제는 RetryFailover라는 Robust-Task에서 제공하는 Task Decoration을 이용하여 순차적인 흐름을 가지는 Task Chain에 대해 RetryFailover 기능을 부여해주는 것입니다. Task Decoration은 0.1 concept 버전에서 4개 정도가 제공되고 있는데요. 아래와 같이 전처리 후처리를 처리해주는 Task Decoration도 있습니다.

new GenesisCoupeTask()
  .wrapByAspect()
    .before(new TiburonCoupeTask())
    .after(new TuscanyCoupeTask())
  .execute();

aspect(
    beforeTask(new TiburonCoupeTask()),
    mainTask(new GenesisCoupeTask()),
    afterTask(new TuscanyCoupeTask())
).execute();


결론적으로 Robust-Task는 Task와 Task Chain 그리고 Task Decoration을 이용하여 업무흐름을 쉽고 이해하기 쉽게 표현하기 위한 프레임웍이라 할 수 있겠습니다.

이렇게 간단하지만 예제 위주로 소개를 드렸습니다. 전달이 잘 되었는지는 모르겠네요. 현재 Robust-Task는 오픈소스로 개발되고 있으며 구글코드에서 호스팅을 받고 있습니다. 오픈소스이기 때문에 소스에 패치를 해주시거나 혹은 메일링에서 의견을 제시함으로써도 프로젝트 참여가 가능합니다. 관심이 가는 분들의 많은 참여와 의견 부탁드립니다.

[프로젝트 홈 바로가기]
[프로젝트 한국 메일링 리스트 바로가기]
[Robust-Task 0.1 concept 소개 문서 바로가기]


WRITTEN BY
차민창
르세상스 엔지니어가 사회를 이끌어나가는 상상을 하며!

,
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.
* 특정인을 비난하자는 의도가 있는 글은 아니며, 단지 마음에 있는 생각을 솔직히 적은 글일 뿐임을 밝힙니다.

처음에는 단지 개발하는 게 재미있었습니다. 제가 무언가를 만들어내는 것에 대해 큰 기쁨과 자부심을 느꼈습니다. 개발하는 일은 정말 굉장한 일이라 생각했습니다. 그래서 저는 개발자가 되었습니다. 그런데 개발자로써 몇년을 살다보니 새로운 것이 보이기 시작했습니다. 바로 돈과 명예로 바꿔 부를 수 있는 성공이였습니다. 그리고 성공을 하게 도와줄 수 있는 강력한 도구인 정치라는 것도 알게 되었습니다.

주위를 가만히 살펴보았습니다. 그러자 개발 하는 데 모든 힘을 쏟는 것이 어리석은 일로 여겨졌습니다. 오히려 약간의 정치를 하는 것이 내게 더 유익할 것이라는 생각이 들었습니다. 극단적으로는 정치에 주로 힘을 쏟으며 약간의 개발을 하는게 성공하는 지름길이 아닌가라는 생각도 들었습니다. 실제로도 개발만 열심히 하는 사람보다는 정치를 잘 하는 사람들이 더 인정 받고 승승장구 하는 것으로 보였습니다.

이런 현실 속에서 제 마음에 갈등이 일어났습니다. 내 마음에서 옳다고 생각하는 개발자가 될 것인가 아니면 이러한 소신을 버리고 성공을 좇는 개발자가 될 것인가? 이것은 제 자신과의 치열한 싸움이였습니다. 그리고 저는 흔들리는 제 마음을 정리하기 위해 아래와 같은 '개발자 지침'을 생각해보았습니다.
개발자 지침

  하나.  개발하는 즐거움과 학습하는 자세를 잃지 않는다.
  둘.     다른 개발자들을 존중하고 사랑한다.
  셋.     불완전한 내 자신을 잊지 않으며 보잘것 없는 능력을 과신하지 않는다.
  넷.     내가 한 것 이상으로 혹은 할 수 있는 것 이상으로 나를 과대포장하지 않는다.
  다섯.  목표를 높게 잡고, 꾸준히 정진한다.
저는 앞으로 제게 남은 개발자로써의 인생에 있어 스스로 세운 위 지침을 준수하며 살고자 합니다. 이 글을 읽으시는 다른 분들도 소신을 가지고 추구하고 계신 지침이 있으시다면 함께 나누어보았으면 좋겠습니다.

2008/06/25 ~ 2008/07/23

WRITTEN BY
차민창
르세상스 엔지니어가 사회를 이끌어나가는 상상을 하며!

,
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.
예전에 "13C 유럽의 교육"이란 글을 쓴 적이 있습니다. 그 글의 주제는 읽기,쓰기,말하기,듣기와 같은 의사소통이 매우 중요하다는 것이였습니다. 그리고 최근에는 코드도 마찬가지가 아닐까라는 생각이 들었습니다.

언제인가 회사의 동료 분과 페어 프로그래밍을 하고 있었습니다. 우리의 목표는 특정 코드를 분석하여 이 코드가 우리가 원하는 바를 이루는 데 도움이 될 수 있는지 판단을 하는 것이였습니다. 키보드는 동료분이 가지고 있었고 우리는 함께 자리에 앉아 코드를 살펴보기 시작했습니다. 잠시 후 그 분은 "이건 가능하겠네요.","이건 좀 고쳐야겠군요"하며 판단하고 화면을 넘겼습니다. 그렇게 몇몇 페이지를 넘나들다 밝은 표정으로 말했습니다. "가능할 것 같습니다. 여기 저기를 좀 수정하면 될 것 같네요." 일은 이렇게 잘 끝났습니다.

그런데 그 동료 분이 돌아간 후 전 부끄러움을 느꼈습니다. 왜냐하면 동료 분이 코드를 읽고, 파악하고, 문제 해결을 시도할 때 전 그 속도를 전혀 따라가지 못했기 때문입니다. 제가 코드를 읽으며 이해하려 할 때 그 분은 이미 판단을 끝내고 다음으로 넘어갔기 때문에 저는 뒤에서 그냥 바라보고 있을 수 밖에 없었습니다.

왜 이런 일이 발생을 했는지 생각해보았습니다. 저의 결론은 제가 쓰기에만 집중하고 읽기에 대해 훈련하지 않았기 때문이라는 것이였습니다. 실제로 저는 여러 문서를 참고하며 코드를 잘 쓰기 위한 훈련을 해왔습니다. 그러나 코드 읽기에 대해서는 학습도 훈련도 하지 않았습니다. 어쩔 수 없이 남의 코드를 봐야 할 때를 제외하곤 읽기에 대해 고민하는 시간이 많지 않았던 것이였습니다.

최근 많은 곳에서 코드 잘 쓰기의 중요성을 강조합니다. 반면에 코드 읽기에 대한 중요성은 많이 얘기 되지 않는 것 같습니다. 보편적인 경우 소프트웨어를 개발하는 기간보다 유지보수 하는 기간이 더욱 길다고 합니다. 이러한 점을 생각해보면 코드 쓰기 능력과 더불어 코드 읽기 능력도 균형 있게 훈련해야 하지 않을까 생각합니다.

2007/10/16 ~ 2008/07/01

WRITTEN BY
차민창
르세상스 엔지니어가 사회를 이끌어나가는 상상을 하며!

,