명언

가장 큰 약점은 약점을 보일 것에 대한 두려움이다 - 보쉬에우리는 종종 뭔가 나아지게 하려다가 괜찮은 것 마저 망친다 - 리어왕


지식에 대한 투자가 언제나 최고의 이윤을 낸다 - 벤자민 프랭클린

당신이 가진 생각이 딱 하나밖에 없다면 그것만큼 위험한 것은 없다 - 에밀 사르티에

언어의 한계가 곧 자기 세계의 한계다 - 루트비히 비트겐슈타인

진보라는 것은 변화와는 거리가 멀고 오히려 기억에 의존한다. 과거를 기억하지 못하는 사람은 과거를 반복할 운명이다 - 조지 산타야나

참으로 고통스러운 일입니다. 자신이 겪는 어려움을 보고는 알게 되죠. 다른 누가 만든 게 아니고 바로 자신이 문제를 만들었다는 걸. 소포클래스(아이아스)

상식과 정직만큼 사람을 놀라게 하는 것은 없다 - 랄프 왈도 에머슨

자기 비난에는 사치성이 있다. 우리가 자신을 비난할때, 다른 사람은 우리를 비난할 권리가 없다고 우리는 느낀다. - 오스카 와일드

좋은 울타리는 좋은 이웃을 만든다 - 로버트 프로스트

아무리 뛰어난 천재라도 세부사항에 집착하면 그 재능이 발휘되지 않는 법이다 - 레바의 8번째 법칙

주변을 둘러보니 변화와 쇠퇴뿐 - 라이트 “함께 하소서”

완성이라는 것은 더 이상 더할 것이 없을 때가 아니라, 더 이상 뺄 것이 없을 때 얻게 되는 것이다. - 생텍쥐페리

가끔은 망설이는 자가 재난을 모면한다 - 제임스 써버

생각없이 행할 수 있는 중요한 작업의 수가 늘어남에 따라 문명은 발전한다. - 알프레드 노스 화이트헤드

아무리 흐른 먹물이라도 가장 훌륭한 기억력보다 낫다 - 중국속담

Tip
자신의 기술에 관심과 애정을 가져라

자신의 일에 대해서 생각하면서 일하라

어설픈 변명을 만들지 말고 대안을 제시하라

깨진 창문을 내버려두지 말라

변화의 촉매가 되라

큰 그림을 기억하라

품질을 요구사항으로 만들어라

지식 포트폴리오에 주기적으로 투자하라

읽고 듣는 것을 비판적으로 분석하라

무엇을 말하는가와 어떻게 말하는가 모두 중요하다

DRY(Don’t Repeat Yourself) - 반복하지 마라

재사용하기 쉽게 만들어라

관련 없는 것들 간에 서로 영향이 없도록 하라

최종 결정이란 없다 (불변하는 결정은 없다)

목표물을 찾기 위해 예광탄을 써라(지금 무엇을 얼마만큼 하고 있는지를 확인하라)

프로토타입을 통해 학습하라

문제 도메인에 가깝게 프로그래밍하라

추정을 통해 놀람을 피하라

코드와 함께 일정도 반복하며 조정하라

지식을 일반 텍스트로 저장하라

명령어 셀의 힘을 사용하라

하나의 에디터를 잘 사용하라

언제나 소스코드 관리 시스템을 사용하라

비난 대신 문제를 해결하라

디버깅을 할 때 당황하지 마라

“Select”는 망가지지 않았다. (컴퓨터는 고장나지 않는다. 내가 코드를 잘못짠거다)

가정하지 마라. 증명하라

텍스트 처리 언어를 하나 익혀라

코드를 작성하는 코드를 작성하라

완벽한 소프트웨어는 만들 수 없다

계약에 따른 설계를 하라

일찍 작동을 멈추게 하라 (문제가 있을 때)

단정문을 사용해서 불가능한 상황을 예방하라

예외는 예외적인 문제에 사용하라

시작한 것은 끝내라

모듈간의 결합도를 최소화하라

통합하지말고 설정하라 (Config 기능을 따루 둬라. 코드에 상수를 박아넣지 마라)

코드에는 추상화를, 메타데이터에는 세부 내용을

작업흐름 분석을 통해 동시성을 개선하라

서비스를 사용해서 설계하라

언제나 동시성을 고려해서 설계하라

모델에서 뷰를 분리하라

칠판(개별 컴포넌트들이 모두 참조할 수 있는 공용 메모리공간)을 사용해 작업흐름을 조율하라

우연에 맡기는 프로그래밍을 하지 말라

여러분의 알고리즘 차수를 조율하라 (알고리즘의 대략적인 소요 시간을 예측하라)

여러분의 추정을 테스트하라

일찍 리펙터링하고, 자주 리펙터링하라

테스트를 염두에 두고 설계하라

소프트웨어를 테스트하라. 그렇지 않으면 사용자가 테스트하게 될 것이다

자신이 이해하지 못하는 마법사가 만들어준 코드는 사용하지 말라

요구사항을 수집하지 말고, 채굴하라

사용자처럼 생각하기 위해 사용자와 함께 일하라

구체적인 것보다 추상적인 것이 더 오래간다

프로젝트 용어사전을 사용하라 (팀원들 간에 공통의 용어를 사용할 수 있도록 하라 - 의사소통의 효율을 위해)

생각의 틀을 벗어나지 말고, 틀을 찾아라

준비가 되었을 때 시작하라

어떤 일들은 설명하기보다 실제로 하는 것이 더 쉽다

형식적 방법의 노예가 되지 마라

비싼 도구가 더 좋은 설계를 낳지는 않는다

팀을 기능 중심으로 조직하라

수작업 절차를 사용하지 말라

일찍 테스트하고, 자주 테스트하라. 자동으로 테스트하라

모든 테스트를 통과하기 전엔 코딩이 다 끝난 것이 아니다

파괴자(고의로 만들어놓은 버그)를 써서 테스트를 테스트하라

코드 커버리지보다 상태 커버리지를 테스트하라 (테스트 할때, 개별 코드에 빠지지 말고 전체적인 맥락을 놓치지마라)

버그는 한번만 잡아라 (같은 버그가 계속 나와서는 안된다)

한국어도 하나의 프로그래밍 언어인것 처럼 다뤄라 (문서를 작성할때도 코드를 쓰는 것처럼)

문서가 애초부터 전체의 일부가 되게 하라. 나중에 집어넣으려고 하지 마라

사용자의 기대를 부드럽게 넘어서라 (사용자의 기대를 제대로 이해하고, 그것보다 약간 더 좋게 만들면 좋아한다)

자신의 작품에 서명하라 (스스로에게 부끄럽지 않은 코드를 만들어라)


Posted by 엘키 엘키

댓글을 달아 주세요

버그는 프로그래머의 숙명이다.

 

섬세하게 만들려한 IOS, OS X에도 버그는 종종 있으며, 사실 많은 사람이 M$ 부르지만 나의 경우는 매우 감사하고 있는 MS 경우에도 버그는 많다. 구글도 예외는 아니고. (구글 apps 초창기 패치할 마다  언어 관련, IME 관련 문제를 겪게 했던 일은 나름 유명한 일화다.)

 

이러한 회사는 분명히 업계의 엘리트가 모여있을 텐데 어째서 이렇게 버그가 나오는걸까?

 

어찌보면, 버그는 당연한 숙명이다.

 

하나의 어플리케이션을 작성하기 위해, 작성된 위지윅 툴을 사용하더라도, 버그가 없다고 단정 지을 없다.

하물며, 코드가 들어가고, 각종 코드를 재사용하고, 다른 코드를 얹는 과정에서는 복잡도와 결합도는 증가하고, 당연히 버그가 생길 여지도 많아진다.

 

그렇다면 버그를 없애려는 노력과 기반은 당연히 마련해야 할테고… (나의 디버깅 관련 글들은 대부분 주제에 대한 글로 이루어져 있다) 그렇게 했는데도 발생한 버그들에 대해선 어떻게 대처해야 것인가?

 

나는 대안으로 기록. 버그 노트를 작성해야 한다고 생각한다.

 

꽤나 많은 프로그래머들이 버그를 부끄러워한다.

숨기려고도 하고, 괴로워 하기도 하고.

 

하지만 나의 경우는 꽤나 많은 버그가 환경에 영향을 준다고 생각한다. , 기존에 작성된 코드가 버그의 수나 버그의 수위를 조절한다고 생각하고.

 

, 그렇다면 버그는 부끄러워 대상이 아니고 개선해야 대상이다.

 

그럼 하나 질문.

 

개선을 위한 습관으로  어떤 노력을 해보셨나요?

 

흔히들 하는 핑계가 경력이 쌓이면 저절로 고쳐져요같은 경험론이다.

주변 지인들과 수많은 얘기와 경험 해보고 내린 결론은 절대 버그는 경험과 비례하지 않는다. (물론 절대적 경험치나 기본기가 부족한 경우는 버그를 양산하기도 한다. 혹은 절대적으로 촉박한 일정도 그런 문제를 만들기도 하고)

 

오히려 위에 언급한 시스템이 버그를 줄여든다.

 

추가적으로 개인적인 노력도 반드시 필요하다고 생각한다.

나의 경우는 그런 의미로 버그 노트를 작성해왔다. 대략 9년여 되가는 습관은, 나의 버그 수를 줄이진 않았어도 같은 종류의 버그 재발은 급격히 줄여줬는데, 자체적인 회고를 주기적으로 거치는 것도 병행하는 덕택일거다.

 

반드시 자신의 버그를 돌아봐야 한다고 생각한다.

그러기 위해 버그 노트를 작성하고, 과정에서 기록되어야 것은 다음과 같다.

 

  • 현상
  • 추정
  • 과정
  • 원인
  • 해결책

 

항목을 채우다보면, 잘못된 해결책이나, 미흡한 원인 파악, 잘못된 추정등이 밝혀진다. (종종 잘못된 현상 보고도 있긴 하고)

 

그런 과정을 반복하다보면, 자신의 잘못된 습관이 보인다. 습관을 고쳐나갈 수록, 퀄리티 높은 프로그래머가 된다고 생각한다.

 

물론 이런 노력없이도, 좋은 퀄리티의 프로덕트를 만들어 내는 분들이라면 괜찮지만, 아니라면 버그를 줄이기 위해 버그 노트를 써보면 어떨까?


Posted by 엘키 엘키

댓글을 달아 주세요

꽤나 많은 상황에서 우리는 기존 코드를 분석해야 한다.

 

빌드업이라 불리는 프로젝트에 필요한 기능들을 만져나가는 과정에서도 우리는 라이브러리나, 오픈소스 코드등을 통해서 기존 코드를 분석해나가야 한다.

 

물론 과정은 섬세하게 만져나갈 여지가 있고, 그간의 결합도를 조절해나갈 여지가 있으므로 상대적으로 코드 분석의 여지가 적다.

 

심지어 사용하는 라이브러리들이 익숙하거나, generic하게 구현되어있다면 더더욱이 쉽고.

 

 

 

사실 가장 곤욕스러운 과정은 프로젝트 dependency 코드를 분석하게 때이다.

 

과정에서, 코드간의 결합도를 낮출려고 노력해온 흔적이 있는 경우는 그래도 상대적으로 쉬운 편에 속한다.

예를 들어 패킷으로만 다른 티어와 통신을하고, 패킷 핸들링 코드가 명확하다면 기존 코드가 난해하다해도 결합도를 풀어가는데에 상대적으로 수월하다.

 

하지만 진입점의 종류가 곳이고, 기능별로 핸들링 코드가 분리되어있음에도 객체간의 관계가 명확하지 않고, 쓸데 없이 복잡하게 보이는 일은 비일비재하다.

 

 

이럴때 당신은 어떻게 분석하는가?

, 인수인계를 위해 어떻게 준비해야 하는가?

 

많은 코드 분석과정을 해본결과, 지켜본 결과 많은 사람들이 두가지 방법정도로 코드를 분석하더라.

 

상향식 코드분석과, 하향식 코드 분석이다.

 

그림. , 전체적인 구조 설계의 전제 파악, entry point 분석, 스레드 디자인 분석과 같은 프로젝트의 룰을 파악하는데에 주력하는 것을 하향식 코드 분석이라 부른다.

 

반대로 컨텐츠별로 하나씩 기능들을 분석하며, 실제 컨텐츠별 사용중인 클래스들을 분석해나가는 것을 상향식 코코드 분석으로 부른다.

 

 

두가지 모두 적절히 이루어지면 좋겠지만, 사실 대부분의 경우 입사나 부서이동 직후 업무를 바로 진행해야되는 경우가 수두룩 하다.

 

이럴 경우 어떤 방법을 먼저 채택할 것인가?

 

나의 경우는 항상 하향식 코드 분석을 선호해왔다.

 

프로젝트의 , 전제를 모르고선 다른 코드들의 디테일을 봤을 , 코드가 과연 작성된 코드인지, 혹은 자연스레 녹아든 코드인지 판단도 안된다고 여겨서이다.

 

그렇다고 상향식 코드 분석이 나쁘다고 없다.

 

일관된 규칙으로 코드가 관리되어왔고, 간결하면 간결할 수록, 상향식 코드 분석이 빛을 발하기 때문이다.

 

하지만 그런 상황은 그다지 자주 벌어지지 않는다. 어찌보면 작성되어있는 코드 양이 많으면 많을수록 이상론적인 이야기이고, 꽤나 많은 경우에는 하향식 코드 분석을 선행하고, 이후 상향식 코드 분석으로 전환하는 과정이 옳다고 본다.

 

여기에 문서화에 대한 이야기를 빼놓을 없다.

 

그렇다면 인수인계 자신의 작업 기록을 위한 문서화는 어떻게 해야 하는가?

 

나는 작업 규칙과, 설계 기준을 명세하면 충분하다고 생각한다.

작업의 디테일은 고생한 과정을 기반으로 기록해 수록 좋다.

만약 두사람 이상이 같은 작업 과정에서 고생했다면, 작업 자체가 집중을 요하는 작업이거나, 혹은 실수의 여지가 많은 빈틈있는 기반 작업이 되었다는 것을 (혹은 그러한 툴이나 라이브러리, 코드 등을 이용하거나) 의미하기 때문이다.

 

겪었던 문제들에 대한 기록만 취합되어 있더라도 상대적으로 많은 시간을 아낄 있다고 생각한다.

그래서 나는 버그 노트를 작성하기 시작했는데, 이에 대한 이야기는 다음 글에서 이어서 하려 한다.


Posted by 엘키 엘키

댓글을 달아 주세요

내가 코드를 작성할 때 신경쓰는 코딩 규약들을 정리해본다.

 

소유권

  • 객체의 소유 주체는 (생성과 소멸의 관리 주체는하나로 규정한다.
  • 객체의 생성,소멸 스레드도 하나로 규정한다.
  • 다른 클래스에서 호출되어야만 하는 메소드를 만들지 말라.
  • Has a 관계가 명확하다면 관계를 혼란 시킬  있는 메소드는 절대 만들지 마라.

 

진입점

  • 진입 점은 명확하게한곳으로 관리하자
  • 만약 다양한 진입 점이 있을  밖에 없다면다른 각각의 진입 점에서 왔음을   있게 하라.

 

중복

  • 중복을 허용하지 말라.

 

단일 규칙

  •  가지 이상의 규칙을 허용하지 말라새로운 규칙을 도입하고 싶다면기존 규칙대로 작성된 전부를 고쳐라.
  •  가지 이상의 규율이 존재하는 것은코드 작성/분석  모든 과정에서 해가 된다.

 

전치 검사, 후치 검사

  • 메소드는 정상적으로 실행되기 위한 선결 조건에 대한 검사를 해야 한다.
  • 메소드는 정상적으로 실행되었을 때의 기대 값을 충족 시키는지 검사해야 한다.

 

호출 주체

  • 누가 호출해도 문제가 없는 메소드만 외부로 개방하라.
  • 만약 특정 클래스에서만 호출해야 정상 동작한다면, 잘못된 설계이고, 잘못된 사용법을 제공하는 것이다.

 

호출 순서

  • 호출 순서에 영향을 주는 코드는 지양하라.
  • 피치 못할 사정으로 함수의 호출 순서가 일정해야만 한다면, 정해진 호출순서대로 실행하는 상위 함수를 만들고, 내부를 숨겨라.


Posted by 엘키 엘키

댓글을 달아 주세요

유닛 테스트를 내가 접한 지도 어언 10년이 되간다.

그간 내가 거쳐온 많은 회사에서 사용되기도, 무시되기도, 우선 순위에 밀리기도 하더라.

 

과정에서 제안도 여러 해보고, 설득 과정에서 자주 나왔던 질문이 있었다.

 

유닛 테스트하면 뭐가 좋은가요?

 

처음 질문을 받았을 당시, 답변은

 

테스트야 하면 당연히 좋은 거다

 

라고 답변했었다.


 

사실 누구나 테스트의 중요성은 배운다. 그래서 아주 작은 팀이고 여력이 부족하다면, 개발팀 테스트라도 소화하려고들 하는 것은 사실이긴 하다.

 

하지만 많은 사람들에게 테스트란 재미없고, 지루하지만 해야만 하는 교리 같은 것에 불과하다는 것이 문제다.

듣는 사람도 고개는 끄덕였지만, 막상 실천으로 이끌어 들이는 데에는 실패했다.

결과적으로 동기부여에 실패했다.

 

 

이어진 고민은, 과연 유닛 테스트의 장점이라고 주장해야, 테스트 검증 개발 (TDD is dead - http://likelink.co.kr/29242 - 이후, 나는 생각을 굳게 굳혔다. Test Verify Development. 테스트를 통해 검증을 하며 이뤄지는 개발을 말한다) 동조 있게 만들 있을지 였다.

 

과정에서 유닛 테스트 시스템 테스트 코드에 대해 여러 가지 대화를 나누곤 했다.

과정에서, 그리고 내가 직접 겪었던 테스트 코드의 가장 장점은, 바로 작업자의 의도를 테스트로 강제한다는 점이다.

 

건즈2 팀에서 당시, 테스트가 깨지는 것은 build 깨지는 것으로 간주됐다. 왜냐하면 테스트 프로젝트는 프로젝트와 대응되어 함께 build 되었으며, post build 이벤트로 테스트가 수행되는 것이 프로세스였는데, 과정에 strict 검사가 많으면 많을 수록, 새로 작성한 코드나 수정된 코드가 기존 작업자의 의도를 벗어난다는 것을 있었다.

 

그렇다. 유닛 테스트를 통해, 동작하는 코드만으로 부족한 작업자의 의도를 전달하고, 의도가 지켜질 있었다.

 

이야기를 해보면, 유닛 테스트를 프로젝트에 밀접해 적용해온 팀들의 개발자 분들은 비슷한 의견을 내비치셨다.

 

여기서 중요한 점이 있다.

 

바로 자신의 코드가, 자신이 의도한 대로 동작하는지를 먼저 확인해준다는 점이다.

 

나는 DHH 위에서 언급한 TDD is dead라는 글을 쓰기 전에도 이미, TDD 하지 않고 있었다. Post Test Development 해왔다고 있다.

 

그렇게 해오다 보니, 테스트를 작성하는 과정에서 내가 작성한 코드가 의도대로 동작하는지 확인하는 과정을, 그리고 예외 상황에 대한 고민을 테스트 작성하는 과정에서 진행했다.

 

물론 과정이 너무 늦어, 설계를 변경해야 되면 어떻게 할거냐는 질문을 받기도 했는데, 사실 설계가 테스트를 통과하지 못해 무너지게끔 구성되어 있다면, 유연하지 못한 코드를 작성한 거라고 봐도 무방하다고 생각한다.

 

사실 아무리 commit message 작성해도, 문서를 작성해도, 주석을 달아놓아도, build 깨지는 것만큼 강한 메시지는 없다.

 

그것도 논리적 모호함이 가장 적은 언어의 문법에 맞춰 작성된 코드라면 나위 없이 명확하다.

 

그래서 우리는 유닛 테스트를, 시스템 테스트를 진행 해야만 한다.


Posted by 엘키 엘키

댓글을 달아 주세요

2000년대 중후반은 모두가 유닛 테스트에 미쳤다. 아니 TDD에 미쳤다.

Test Driven Development에 대한 서적이 넘쳐났으며, 모두가 TDD를 통해 구원 받을거라는 희망찬 상상에 들떠 있었다.


이 붐을 주도했던 개발자중 한명인 DHH (rails를 만든 이)도 이 흐름에 동참했었다. 

그를 비롯한 많은 이의 주장은 테스트 우선 신앙 (Test first fundamentalism)라 불릴 만큼 테스트를 바탕으로 코드를 작성하면 그 퀄리티가 비약적으로 상승 할 것이라는 의견이었다.



여지껏 내가 해온 테스트는 다음과 같았다.


독립적으로 동작할 수 있는 클래스에 대한 유닛테스트.

- 화이트 박스 테스트로써의 유닛 테스트. (나는 크게 선호하진 않았지만, 가끔 진행했고 유닛테스트를 실천한 초반에 특히 많이 진행했다.)

- 블랙박스 테스트로써의 유닛 테스트. (블랙박스 테스트를 난 매우 선호했는데, 외부에서 사용하는 메소드야 말로 기대치대로 동작하는지 검증되어야 한다고 믿고 있고, 그 믿음에 대해선 변함이 없다.)


외부 프로세스 내지는, 외부 입력을 시뮬레이션 해서 진행하는 컴포넌트 테스트

- input이 패킷이 주가 되는 서버 프로그램의 경우에는, 시뮬레이터 내지는 테스트 클라이언트라 불리우는 어플리케이션을 통한 테스트.


외부 입력을 통한 부하 테스트

- 프로파일링을 겸한, 임계치 측정 및 검증.

- 부하 발생시의 안정성에 대한 검증.


위 테스트중 유닛테스트는 일일 빌드를 통해 검증

컴포넌트 테스트는 업무시간 도중에.

부하테스트는 퇴근하고 난 이후부터 익일까지.


이런식으로 시간을 나누어 관리했다.


헌데 이렇다보니, 컨텐츠 개발하고 버그에 쫓기고 하다보면 막상 테스트를 들여다보고 개선하고, 테스트 코드를 추가하는 일이 만만치 않았다.

당연히 개발 후 테스트 코드 추가보다 더 오래 걸리는, 테스트를 추가하며 기능을 검증하는 일. 즉 테스트 주도 개발과는 거리가 멀게 개발해오고 있었고, 심적으로 매우 불편했다.

꼭 안생겨도 될 버그를, 시간을 조금만 더 쓰면 커버리지를 갖출 수 있는 상황을, 테스트 주도 개발을 외면하면서 맞이한게 아닐까 하는 생각이었다.



이런 생각을 이사님과 토의한적이 있었고, 이사님은 비용이 많이 드는 테스트에 대한 부정적인 의견을 피력하셨다.


"테스트를 작성하기 위한 비용이 너무 크다면, 테스트 코드를 작성하는 것마저 낭비라고 생각한다."


테스트 코드가 주는 이득을 많이 체감했던지라 나는 당시 크게 공감하진 못했다. 특히나 이 말을 하신 이사님은 테스트 코드 추가를 위해 많은 비용을 감내하시고, 여러 객체의 mocking과 단위 테스트, 시뮬레이트 코드를 위해 시간을 많이 쏟으신 분이셔서 더더욱 놀랐었다.


헌데 DHH의 고백을 읽고나서 다시금 떠올려본 이사님의 말은 나에게 큰 공감을 가져다 주었다.


가장 크게 와닿은 단락은 아래와 같다.

  • 두번째 단계는, unit 부터 system 사이의 테스팅 스펙트럼의 균형을 잡는 것이다.


그렇다! TDD는 유닛 테스트의 중요성만을 지나치게 강조해왔다.

유닛테스트를 통해 해당 클래스의 단독 동작은 보장되지만, 여러개의 클래스가 mocking 없이 묶였을 때의, 다양한 입력과 다양한 상태(state)에서의 출력(동작)은 보장하지 않는다.


실제로 이 부분을 커버하기 위해 나는 컴포넌트 테스트라 불리우는 (시스템 테스트라는 용어가 있는지 이제 알았다. 나도 앞으로 이렇게 써야겠다.) 시스템 테스트를 해오긴했으나, 유닛 테스트를 위한 시간 투자를 덜한다는 찜찜한 마음은 버릴 수 없었다.


하지만 이제 편해졌다.

너무나 당연한 얘기지만 시간은 돈이다. 테스트를 작성하기 위한 시간도 돈이고, 테스트를 유지하기 위한 비용도 돈이다. mocking을 위해, 혼자 일때만 잘 동작할지도 모르는 녀석을 위한 시간낭비가 될 수도 있는 유닛 테스트를 위해 강박을 가질 필요까진 없다.


물론 DHH의 이야기도 테스트의 중요성을, 매우 강조한다. 하지만 테스트 "주도" 개발은 하지 않고 있다는 것을 고백했다.

테스트 "주도" 개발이 얼마나 느리고, 비효율적이며, 그 성과가 미약했음을 고백한 것이라고 볼 수 있다.


이런 얘기가 다른 사람도 아닌 DHH에게서 나온 것은 너무나도 반갑다.


테스트 코드나 테스트를 줄이자는 얘기가 아니라는 것은 다들 알 것이다.

유닛 테스트와 시스템 테스트간의 밸런스를 맞추고, 테스트에 대한 투자 대비 효율에 대해 지금보다 심도 있게 고민해보자.

그리고 TDD에선 자유로워 지자!



TDD는 죽었다 - Rails를 만든 DHH의 글

http://yisangwook.tumblr.com/post/83725422949/tdd-is-dead-long-live-testing


TDD is dead. Long live testing. (DHH) — likelink

http://likelink.co.kr/29242

Posted by 엘키 엘키
 TAG TDD

댓글을 달아 주세요

지난해 10, 미국의 북동부 지역은 어딜 가나 아셀라(Acela) 광고 천지였다.아셀라란 암트랙(Amtrak) 워싱턴-보스턴간 노선에서 운행할 새로운 초고속열차의 이름. 끊임없이 쏟아지는 TV 광고와 전광판 광고, 도처에 나붙은 포스터들을 보면서, 누구라도  정도의 물량 공세라면  새로운 초고속열차 서비스에 대한 수요 창출에 상당히 기여했으리라 생각했을 것이다.


글쎄, 그랬는지도 모르지. 하지만, 정작 암트랙사는 이를 확인해  기회가 없었다. 아셀라 프로젝트가 계속 지연되는 바람에 상용서비스가 개시되지도 않은 상태에서 광고 캠페인만 진행되고 있었던 것이다. 어떤 회사의 신제품 시판을 한달 앞두고  제품이 우수한 평가 등급을 받자 마케팅 책임자가 했다는말이 떠오른다. “대단한 홍보 효과야! 이럴  시장에 물건만   있었으면얼마나 좋았을까!”


남성호르몬이 철철 넘치는 게임 업체들은 자사 웹사이트에 제품 개발이 완료되는 대로 새로운 게임이 출시될 것이라고 떠들어대기를 좋아한다. 스케줄?스케줄 같은  필요하지 않다. 그들은 나는 게임 개발자들이니까! 하지만,대부분의 평범한 소프트웨어 업체들에게는 스케줄이 필요하다. 로터스의 경우가  좋은 예로, 로터스사가 처음 123 버전 3.0 개발을 완료했을   소프트웨어는  당시만 해도 아직 보급 대수가많지 않던 80286 기종의 컴퓨터를 필요로 했다. 로터스는 제품 출시를 16개월이나 미뤘고  기간 동안 8086 기종의 메모리 한계인 640K 맞춰 제품의 용량을 줄였다. 수정된 제품이 완성되었을 때엔 이미 엑셀을 시판중인 마이크로소프트사가 시장에서 16개월 정도 앞서나가고 있었으며,  무슨 가혹한 운명의 장난인지, 8086 기종은 이미 시장에서 폐물 취급을 받고 있었다!


 글을 쓰고 있는 지금도 넷스케이프의 인터넷 브라우저 5.0 경쟁사에 비해 거의 2가까이뒤쳐져있다. 개발된 코드를 모두 폐기하고 처음부터 코딩을 다시 시작하는 치명적인 실수를 저질렀기 때문이다. 애시톤-테이트, 로터스, 애플사의 MacOS 등도 똑같은 실수를 저지르는 바람에 소프트웨어 역사의휴지통(Recycle-bin) 속으로 내던져지는 신세가 되고 말았다.  사이 넷스케이프사의  브라우저의 시장점유율은 80%대에서 20%대로 곤두박질쳤지만 회사는 아무것도   없었다. 주력 소프트웨어 제품이 산산조각으로 분해되어 있는 상태에서는 달리 손을   있는 방도가 없었기 때문이다.  한번의 잘못된 결정이 넷스케이프를 자폭시킨 핵폭탄이  셈이었다. ( 자세한내용은 Jamie Zawinski  world-famous tantrum 참조한다).


그래서, 스케줄관리가필요한것이다. 거의 모든 프로그래머들이 하기 싫어하는 일이 바로 스케줄 관리다. 필자의 경험에 따르면, 대다수의 프로그래머들은어떻게 해서든 스케줄 같은  아예 짜지 않고 버텨 보려고 든다. 스케줄을 짜는 극소수의 프로그래머들도 대부분 상사가 하라고 하니까 억지로 하고 있을,  스케줄대로 프로젝트가 진행되리라고 믿는 사람은  상사 밖에 없다. 상사는 스케줄을 믿는 한편으로, “기한 내에 완료되는 소프트웨어 프로젝트는 없다고도 믿으며 , UFO 존재도 믿는 사람이다.

그렇다면,  아무도 스케줄을 만들려 하지 않을까? 주된 이유는  가지다. 첫째는 스케줄을 짜고 관리하는 것이 매우 골치 아픈 일이기 때문이고,  번째이유는 아무도 그것이 그만한 수고의 가치가 있는 일이라고 믿지 않기 때문이다. 스케줄이 지켜지지도 않을 거라면 도대체  그런 수고를 해야 한단 말인가? 스케줄이란 애당초 지켜지는 법이 없고 시간이 지날수록 현실과의 괴리는점점  커지기만 하는데,  하러 그런 헛수고를 한단 말인가?


여기, 정확하게지켜지는스케줄을만드는간단하고손쉬운방법이있다.


1) 엑셀프로그램을사용하라. MS Project 같은 거창한 프로그램을 사용하려들지 말라. MS Project 사용자가 종속성의 문제를 해결하기 위해 많은 시간을 할애할 것이라는 가정하에 만들어진 프로그램이다. 종속성이란,  가지 작업을 진행해야 하는 상황에서 하나의 선행 작업이 먼저 완료된 후에만 다음 작업을 시작할  있는 경우를 말한다. 소프트웨어 프로젝트의 경우, 작업들간의종속성은 너무나 당연한 것이기 때문에 굳이 수고스럽게 종속성을 추적할 필요가 없다.

MS Project 사용하는 경우에 생길  있는  다른 문제는  프로그램을 사용하다 보면 자꾸 스케줄 균형 조정 기능을 실행하고 싶어진다는 것이다. 스케줄 균형 조정에는 불가피하게 모든 작업을 재조정하여 다른 사람에게 재할당하는 과정이 포함되는데, 소프트웨어 프로젝트의 경우 이런 재조정은 말이되지 않는다. 프로그래머들간의 호환이 불가능하기 때문이다. 가령, 리타가 작업한 코드의 버그를 존이 수정하려면 리타 자신이 수정할 때보다 시간이 일곱배는  걸린다. , UI 담당 프로그래머에게 WinSock 관련된 문제를 해결하라고 시키면, WinSock 프로그래밍에 익숙해지는 데에만 일주일은 걸릴 것이다. 결론은 MS Project 소프트웨어 개발 프로젝트보다는 건축 공사 프로젝트에 적합한 프로그램이라는 것이다.


2) 단순하게만들라. 필자가 이용하는 스케줄 포맷은 너무나 단순해서 한번만봐도 기억할  있을 정도다. (컬럼) 개수는 일곱 개면 된다.

개발자가 여러 명인 경우에는 개발자별로 시트를 각기 따로 만들 수도 있고,아니면  작업을 담당하는 개발자의 이름으로 컬럼을 만들 수도 있다.


3) 하나의기능은여러개의작업으로분해하라. 여기서, 기능이란 프로그램에추가되는 맞춤법 검사 기능 같은 것을 말한다. 실제로 맞춤법 검사 기능을 추가하려면, 프로그래머는 여러 단계의 작업을 수행하게 된다. 스케줄을  가장 중요한 부분은 바로 이와 같은 구체적인 작업들의 목록을 만드는 것이다.따라서 다음 규칙을 명심해야 한다.


4) 코딩을직접담당할프로그래머만이스케줄을만들있다. 관리자가 임의로만든 스케줄을 프로그래머에게 던져주고는 따르라고 말하는 프로젝트는 실패할  밖에 없다. 코딩을 직접 담당할 프로그래머만이  기능을 구현하기 위해 어떤 작업들이 필요한가를 구체적으로 예측할  있고  작업에 어느 정도의 시간이 소요될 것인가도 추정할  있다.


5) 작업단위를세분화하라. 실효성 있는 스케줄을 만들기 위해 반드시 유념해야  부분이다. 작업량은 날짜가 아니라 시간 단위로 계산해야 한다. ( ,또는   단위로 작업 기간이 계산되어 있는 스케줄은 처음부터 지킬 생각으로 만든 스케줄이 아니다). ‘작업 단위를  잘게 쪼개면  정밀한 스케줄이나오겠지 정도로 생각하는 독자가 있을지도 모른다. 천만의 말씀! 대략적인작업 개요를 바탕으로 스케줄을 세워보고, 다시 작업 단위를 보다 세분화하여스케줄을 세워보면, 단순히  정밀한 스케줄이 얻어지는 것이 아니라 전혀다른결과 나온다. 완전히 다른 수치가 나오는 것이다. 어째서 이런 일이 생기는 걸까?


작업 단위를 세분화하기 위해서는 실제 코딩 과정에서 구체적으로 어떤 일들을 수행하게  것인가를 생각해보지 않으면  된다. 서브루틴을 저작하고,이러저러한 대화상자들을 만들고, wawa 파일을 읽어내고 등등.  같은 각각의 단계에 소요되는 시간을 추정하는 것은 어렵지 않다. 프로그래머라면 서브루틴을 저작하고 대화상자를 만들고 wawa 파일을 읽어내는 작업들은 모두해봤을 것이기 때문이다.


만일 어떤 스케줄이 적당히 얼버무린  덩어리 작업들로만 (가령, “문법검사 기능 구현하기 ) 채워져 있다면, 이는 프로그래머가 구체적으로 어떤일들을 하게  것인가에 대해 제대로 생각해보지 않았다는 증거다. 그리고,어떤 일들을 하게  것인지 제대로 생각해보지 않았다면, 거기에 어느 정도의시간이 소요될 것인지도   없다.


개별 작업에는 어림잡아 2시간에서 많게는 16시간 정도까지가 소요된다. 스케줄에 40시간(1주일)짜리 작업이 포함되어 있다면, 작업 단위를 충분히 세분화하지 않았다는 이야기다.


스케줄을   작업 단위를 세분화해야 하는  다른 이유는 그런 과정을 통해 해당 기능을 머리 속으로 설계해보게 된다는 것이다. 만일 인터넷 통합이라는  떨리는 기능에 대한 스케줄을 수립하면서 무턱대고 3주일을 배정했다면  프로젝트는 실패할  밖에 없다. 구체적으로 어떤서브루틴들을만들어내야것인가 생각해내다 보면,  기능을 명확하게규정하게 된다.  같은단계에서 미리 계획을 세워봄으로써 소프트웨어 프로젝트와 관련된 불안정성을 크게 줄일  있다.

 

6) 최초추정시간과현재추정시간을지속적으로추적하라. 어떤 작업을 처음스케줄에 추가할 때는  작업에 어느 정도의 시간이 소요될 것인가를 추산한,  결과를 Orig Est (최초 추정시간) 컬럼과 Curr Est (현재 추정시간) 컬럼에 모두 입력한다. 


시간이 흐름에 따라, 작업 진도가 당초의 예정보다 지연 (혹은 단축)되면, 현재 추정시간 컬럼을 필요에 따라 업데이트할  있다.  같은방식으로 관리하다 보면, 특정 작업에 필요한 시간을 보다 정확하게 추정하는방법을 스스로 터득할  있다. 


대부분의 프로그래머들은 각각의 작업에 어느정도의 시간이 소요되는지  모른다. 그래도 걱정할 필요는 없다. 스케줄을지속적으로 관리하고 그에 따라 업데이트하는 , 결국 스케줄과 프로젝트 완료 시기는 일치하게 된다. (최종 납기를 맞추기 위해 일부 기능이나 항목을 잘라버려야만 하는 경우도 생길  있지만, 그와 같은 추려내기가 필요한 시점이언제인가를 일관되게 보여준다는 점에서 스케줄의 정확성은 여전히 유지될것이다). 필자의 경험으로  , 대부분의 프로그래머들은 일년 정도만 연습하면 스케줄 짜는  도사가 된다.


작업이 완료되면, 현재 추정시간 컬럼과 Elapsed (경과시간) 컬럼의 값이 똑같아지고 Remain (잔여시간) 컬럼의 값은 0 된다.


7) 경과시간을매일업데이트하라. 물론, 스톱워치를 들여다보며 코딩을 진행할 필요는 없다. 퇴근하기 직전에, 혹은 회사에서 밤을 새워가며 일하는 경우라면 책상 밑에 기어들어가 잠깐 눈을 붙이기 직전에, 하루에 한번만 경과시간을 업데이트하면 된다. 8시간 동안 근무했다고 가정하고 (하하!), 그날 진행한작업들에 대한 경과시간 필드에 8시간을 쪼개서 입력한다.


 잔여시간 컬럼의값은 엑셀이 자동으로 계산해  것이다.


그와 동시에, 현재 추정시간 컬럼도 업데이트하여 변화된 현실을 반영한다. 스케줄을매일업데이트하는걸리는시간은고작2정도밖에되지않는다. 그래서  방법을 손쉬운 스케줄 관리법이라고 부르는 것이다. 빠르고 간편하기 때문에.


8) 휴가기간과휴일등도항목에포함시켜라. 1 정도 진행되는 스케줄이라면, 사이에 프로그래머들의 휴가일수가 대개 10일에서 15 정도 포함될 것이다. 스케줄의 기능 컬럼에는 휴가, 휴일  기타 시간을 잡아먹는 모든 것들에대한 항목이 전부 포함되어야 한다. 잔여시간 컬럼의 값을 모두 더한  이를40(1주일)으로 나누면, 휴가  모든 요소를 포함하여 작업 기간이   주일이나 남아있는지를 산출할  있고 제품 출시 일자도 계산할  있다.


9) 디버깅시간도고려하라! 디버깅은 소요시간을 추정하기가 가장 어려운 항목이다. 가장 최근에 작업했던 프로젝트를 떠올려보라. 아마도 코딩 단계에서소요된 시간의 100% 내지 200% 해당하는 시간이 디버깅에 소요되었을 것이다. 스케줄의 기능 컬럼에는 반드시 디버깅 항목이 포함되어야 하며, 아마도가장 값이  항목이  것이다.


스케줄 업데이트 방법은 다음과 같다. 가령, 어떤 개발자가 wawa 파일을 코딩한다고 하자. 처음 스케줄을   예상했던 최초 추정시간은 16시간이었지만,현재까지 이미 20시간이 소요되었고 앞으로도 10시간 정도는  걸릴 것으로예상된다.  경우, 개발자는 현재 추정시간 컬럼에 30 입력하고 경과시간컬럼에 20 입력하면 된다.


주요 작업 단계가 완료된 , 모든 항목들의 값들을 더해보니 상당한 수치가나왔다. 이론상으로 제품 납기를 맞추자면 몇몇 기능을 잘라내 버려야 한다.이렇게 시간에 쫓길  프로그래머들이 가장 먼저 잘라낼  있는 기능이 바로디버깅 항목이다. 다행히도, 처음 스케줄을   디버깅 항목에 많은 시간을할당해 두었으니까.


원칙적으로, 개발자들은 코딩과 동시에 디버깅을 병행해야 한다. 절대로, 수정할  있는 버그를 뒤로 미뤄둔  새로운 코딩에 착수해서는  된다. 미해결버그의 수는 가능한  최소한으로 유지해야 한다.  이유는  가지다.


1) 버그는 코딩 직후에 곧바로 수정하는 것이 가장 수월하다.  달쯤 지난 후에 버그를 수정하려고 하면, 정확한 코딩 방식을 기억하지 못하기 때문에 버그수정도  어려워지고 시간도  많이 걸릴  있다.


2) 버그 수정은 과학적 연구와 비슷해서, 언제 새로운 과학적 사실을 발견할 있을지 정확히 예측하기 어려운 것처럼 언제 버그를 해결할  있을지 정확히 예측하는 것도 쉽지 않다. 수정해야  버그가  개나  개뿐이라면 제품출시 시기를 예측하는 것은 어렵지 않겠지만, 미해결 버그가 수백 개나 수천개쯤 되는 경우에는 이것들을 언제 전부 수정할  있을지 예측하기란 불가능하다.


그렇다면, 개발자가 코딩 과정에서 버그를 발견할 때마다 곧바로 버그를 수정하는데  디버깅 스케줄을 따로 만들어야 하는가? 프로그래머가 모든 버그를그때그때 수정한다 하더라도, 작업 단계가 완료되면 불가피하게 버그 수정 과정이 필요하다. 테스트 (내부 테스트  베타 테스트) 단계에서 정말로 어려운버그들이 발견되기 때문이다.


10) 통합시간도고려하라. 여러 명의 프로그래머가 함께 작업하는 경우, 프로그래머들 간에 서로 일치되지 않아 조정이 필요한 부분이 생기게 마련이다. 가령, 유사한 기능의 대화상자를  명의 프로그래머가 서로 다른 방식으로 구현할 수도 있다. , 여러 명의 프로그래머들이 각자 마음대로 추가한 메뉴 항목이나 키보드 단축키, 툴바 등을 누군가는 전체적으로 정리하고 통일시켜야만한다.  사람이 코드에 체크인하는 순간 컴파일러 에러가 발생할 수도 있다. 모든 것들을 수정할 시간이 필요하며, 이는 별도의 기능 항목으로 스케줄에포함시켜야 한다.


11) 여분의시간을포함시켜라. 시간은  모자라게 마련이다. 스케줄을  고려해야  여분의 시간(버퍼)  가지 종류가 있다. 첫째는 당초 추정했던것보다 시간이  많이 걸리는 작업을 고려한 버퍼이고, 둘째는 관리자가wawa 구현이 너무나도 중요해서 다음 버전으로 미룰  없다고 결정하는 경우 등과 같이, 계획에 없이 갑자기 추가된 작업을 고려한 버퍼다.


혹시라도 휴가, 휴일, 디버깅, 통합 시간  버퍼 항목 등을 모두 더한 값이 실제 작업 시간을 모두 더한 값보다  크다는 사실을 알고는 놀랄 수도 있다. 이런 사실에 놀라는 독자라면 아마 프로그래밍 경력이 아직 그리 길지 않은 개발자일 것이다. 책임질 자신이 있거든, 이런 항목들을 빼버려도 좋다.


12) 절대로관리자가프로그래머에게스케줄단축을요구해서는된다. 풋내기 소프트웨어 관리자 중에는 프로그래머들에게 빡빡한” (비현실적으로 짧은) 스케줄을 던져주는 방법으로 그들을 자극하여 작업을 보다 빨리 진행시킬  있다고 생각하는 사람들이 많다. 필자의 생각으로는 이런 식의 자극은멍청한 짓일 뿐이다. 필자의 경우, 스케줄에 뒤쳐지면 오히려 좌절감이 생기고의욕이 저하되며, 스케줄보다 진도가 빠를  활기도 생기고 생산성도 높아진다. 관리자는 스케줄을 심리전의 도구로 이용해서는  된다.


그럼에도 불구하고, 관리자가 스케줄 단축을 요구하는 경우에는 이렇게 대처하라. 릭의추정시간이라는 새로운 컬럼을 하나  추가한다 (물론, 프로그래머의 이름이 릭이라고 가정하고.) 프로그래머 자신이 예상하는 추정시간을 컬럼에 입력한다. 관리자가 원하는 새로운 스케줄은 현재추정시간 컬럼에 업데이트 한다. 관리자의 추정시간은 무시하고 작업을 진행하라. 프로젝트가 완료된 후에 누구의 스케줄이  현실적이었는지 비교해 보라. 필자의 경험에 따르면, “누구 스케줄이  맞는지 한번 볼까요?” 라고 관리자를 위협하는것만으로도 놀랄만한 효과가 있다. 자칫하면 프로그래머들과 얼마나 느릿느릿 일할 있는지 두고 보자는 식의 내기를 하는 꼴이 되고 만다는 사실을 관리자도깨닫게  테니까!


 풋내기 관리자들은 프로그래머의 스케줄을 단축하려고 노력하는가?


프로젝트가 처음 시작되면, 기술 관리자들은 비즈니스 담당자들과 회의를 하고는 그들이  3개월 정도 소요될 것으로 생각하는, 하지만 실제로는 9개월이 걸리는 제품 기능들이 적힌 목록을 만들어 온다. 어떤 작업들을 수행해야하는가를 구체적으로 생각해 보지 않고 스케줄을 짜는 경우, 항상 실제로는3n 시간 이상 걸릴 일이n 시간 정도 걸릴만한 일인 것처럼 보이게 된다. 현실적인 스케줄을 짜다 보면, 모든 작업 시간을 전부 더하게 되고  프로젝트가당초 생각했던 것보다 훨씬 시간이 많이 걸릴 것이라는 사실을 깨닫게 된다.현실은 가혹한 것이다.


풋내기 관리자들은  같은 문제를 해결하기 위해, 사람들이 보다 빨리 일하도록 만들  있는 방안을 찾아내려 애쓴다. 하지만, 이런 식의 접근은 그다지 현실적인 방법이 아니다. 작업 인원을  늘릴 수는 있겠지만, 그렇더라도 신입프로그래머들이 작업에 익숙해질 때까지 상당한 시간이 필요하기 때문에  정도는 작업 효율이 50% 정도 밖에 되지 않을 것이다 (게다가, 그들에게 일을 가르쳐야 하는 사람들의 작업 효율까지 떨어진다). 무엇보다, 소프트웨어업계에서 쓸만한 프로그래머를 새로 뽑자면 6개월 정도는 시간이 걸린다.


모든 에너지가 일년 안에 100% 소진될 만큼 팀원들을 쥐어짠다면 혹시 일시적으로 코드 산출량이 10% 정도 늘어날지도 모른다. 하지만, 별로 남는 장사는 아니다. 무엇보다, 이것은 배가 고프다고 종자용 옥수수까지 먹어치우는 것과 비슷한 꼴이다.


모든 사람들에게 아무리 피곤하더라도  참고 초인적으로 열심히 일해달라고 애원한다면 혹시 코드 산출량이 20% 정도 늘어날  있을지도 모른다. 하지만, 디버깅 시간은  배로 늘어날 것이다. 이야말로 숙명적으로 실패가 예정된 악수(惡手)   있다.


하지만, 아무리 해도 절대로 n 가지고 3n 이룰 수는 없다. 만일   있다고 믿는 회사가 있다면, 필자에게 이메일로  회사의 나스닥 상장기호를 일러주기 바란다. 필자가  상장기호를 반으로 줄여줄 테니까.


13) 스케줄은나무블록과같다. 집짓기 놀이용 나무 블록이  꾸러미 있는데이걸 주어진 상자에 전부 담을 수가 없다면, 방법은  가지다.    상자를구해오거나, 아니면 나무 블록 중에서  개는 포기하는 것이다. 6개월이면 제품을 완성할  있을 거라고 생각했었는데 작업을 진행하다 보니 12개월짜리스케줄이 됐다면, 제품 출시를 늦추든가 아니면 몇몇 기능을 포기해야 한다.나무 블록이 작아지게 만들 수는 없으니까. 만일 작아지게 만들  있는 것처럼 행동한다면, 이는 지금  앞에 보이는 것에 대해 스스로에게 거짓말을 함으로써 장래를 예측할  있는 기회마저 스스로 박탈하는 일이다.


이와 같은 스케줄 관리를 통해 얻을  있는  다른 부수적 효과는 많은 기능들 중에서 일부를 포기하게끔 만든다는 것이다. 포기하게끔 만드는 것이  좋으냐고? 여기  가지의 기능이 있다고 가정하자. 하나는 진짜로 쓸모 있고 장차 제품을 빛내줄 기능이고 (예를 들면, 넷스케이프 2.0 테이블 기능),  다른 하나는 코딩하기도 아주 쉽고 프로그래머가 만들어보고 싶어하지만 쓸모는 별로 없는 기능이다 (예를 들면, BLINK 태그).


스케줄 없이 프로젝트를 진행할 경우, 프로그래머들은 쉽고 재미있는 기능 먼저 코딩하기 시작할 것이다. 그러다가 나중에 시간이 부족하게 되면,   없이 유용하고 중요한 기능을 포기하게 된다.


프로젝트를 개시하기 전에 미리 스케줄을 수립하는 경우, 무언가를 포기해야만 하는 상황이 되면, 쉽고 재미있는 기능을 포기하고 유용하고 중요한 기능을작업하게  것이다. 스케줄을 관리하다 보면, 버려야  기능들을 프로그래머들이 스스로 추려내게 되기 때문에, 보다 나은 기능들로 구성된 강력하고 좋은제품을 만들  있게 된다.


필자가 엑셀 5.0 개발 프로젝트에 참여했을 때의 일이다.  당시 우리 팀이 계획했던 기능들이 워낙 방대한 양이었기 때문에 스케줄을 맞출 수가 없게 되었다. 팀원들은 고민했다. 이를 어쩌나! 전부  너무나도 중요한 기능들인데. 매크로 편집 마법사는 절대로 포기할  없어!


시간이 촉박해지자 별다른 도리가 없었다. 제품 출시 기한을 맞추기 위해 우리팀은 자식 같은 기능들을 잘라내야 했다. 포기하게  기능들에 대해 모두 마음 아파했다. 아픔을 달래기 위해 팀원들은 스스로에게 이야기했다.  기능들을 포기하는 것이 아니라 그저 조금  중요한 기능들을 위해 엑셀 6.0 버전으로 잠시미뤄두는 것뿐이라고.


엑셀 5 거의  완성되어갈 무렵, 필자는 동료인Eric Michelman 함께엑셀 6 버전에 대한 스펙을 만들기 시작했다. 

 사람은 머리를 맞대고 앉아엑셀 5.0 스케줄을 조정하면서 엑셀 6”용으로 미뤄둔 기능들을 다시 살펴보았다. 


우리는  기능들이라는 것이 너무나 조악한것들 일색이라는  놀라지 않을  없었다. 쓸만한기능이라고는 하나도 없었다. 물론,  기능들은  다음,  다음 버전에서도제품화되지 않았다.

 스케줄을 맞추기 위해 필요한 기능들만 추려낸 것이야말로 우리 팀이   중에서 가장 잘한 일이었다. 

그렇게 하지 않았다면, 엑셀5.0 개발 기간은  배쯤 길어졌을 것이고 아무짝에도 쓸모없는 쓰레기 같은 기능들로 50% 채워졌을 것이다. (넷스케이프 5.0이나 모질라(Mozilla)경우에도 분명히 이와 같은 상황이 벌어졌을 것이다. 스케줄도 없고, 확정된기능 목록도 없고, 쓸만한 기능만 추려내는  아무도 원치 않고, 그러다 보니제품을 출시할  없게  것이다. 그들은 결국 IRC 클라이언트처럼 시간을 들일만한 가치라고는 없는 기능들만 잔뜩 들어있는 제품을 내놓게  것이다.)


부록: 엑셀을이용할알아두어야것들

엑셀이 소프트웨어 스케줄 관리에 편리한 제품이라고 주장하는 이유 중의 하나는 대부분의 엑셀 프로그래머들이 오로지 엑셀 하나만 가지고 스케줄을 관리한다는 사실이다 (what-if 시나리오 같은 것을 분석하는 사람은 별로 없다...프로그래머들한테 그런  기대하면  되지!)


목록공유: 파일/목록 공유 명령을 이용하면 팀원 모두가 한꺼번에 파일을 열어두고 편집할  있다.  전체가 지속적으로 스케줄을 업데이트해야 하기 때문에,  기능은 아주 유용하다.


자동필터: 자동 필터 기능은 가령, 특정 프로그래머가 자신에게 할당된 작업만 전부 골라서 보고 싶을  스케줄을 필터링하는  편리하다. ‘자동 정렬 기능과 함께 사용하면, 자신에게 할당될 모든 작업을 우선순위에 따라 순서대로조회할  있다.  자체로 효과적인 작업 계획서 되는 것이다. 끝내주지?


피벗테이블: 피벗 테이블 기능은 요약정보나 크로스테이블을 보고 싶을 매우 편리하다. 가령, 각각의 우선순위에 대해,  개발자에게 필요한 잔여시간을 보여주는 도표를 만들  있다. 피벗 테이블은 결코 어렵지 않다. 반드시 기능을 사용하는  익숙해져야 한다. 엑셀을 백만 배쯤 편리하게 써먹을 있기 때문이다.


작업일기능: 엑셀의 분석 툴팩에 포함된 작업일(Workday) 기능을 활용하면 스케줄에 해당하는 실제 달력상의 날짜를 손쉽게 확인할  있다.


출처 : 조엘 온 소프트웨어 한국어 블로그 (http://korean.joelonsoftware.com/Articles/PainlessSoftwareSchedules.html)

Posted by 엘키 엘키

댓글을 달아 주세요

모든 사람들이 명세서 작업을 해야한다고 생각은 하지만, 아무도 명세서 작업을 하지 않습니다.

왜 명세서 작업을 하지 않을까요?

명세서 작업단계를 건너뛰면 시간을 절약할 수 있다고 말합니다.

이런 사람들은 명세서 작성 작업이 NASA에서 우주 왕복선을 만드는 공학도나 큰 규모의 보험회사 직원에게나 필요한 사치쯤으로 치부합니다.

명세서 작업을 하지 않는 관례는 소프트웨어 프로젝트에서 가장 크고 불필요한 위험 요인을 짊어지는 행동입니다. 이는 등에 옷가지만을 걸친 다음에 날기를 기대하며 모하비 사막을 건너려고 출발하는 것만큼이나 바보스럽습니다.

명세서 작업을 생략하고 바로 코드 작성으로 뛰어드는 프로그래머나 소프트웨어 개발자는 스스로를 허리춤에서 순식간에 총을 뽑는 멋진 총잡이라고 생각하는 경향이 있습니다.

하지만 결코 그렇지 않으며, 이런 개발자일수록 놀라 자빠질 정도로 생산성이 낮습니다.

즉, 형편 없는 코드를 작성하거나 조잡한 소프트웨어를 양산하며, 결국 전혀 쓸데없느 ㄴ거대한 위험을 자초해 프로젝트를 위협합니다.


기능 명세 - FUNCTIONAL SPECIFICATION

완전히 사용자 관점에서 제품이 어떻게 동작할지를 기술합니다. 어떻게 구현했는지는 신경도 쓰지 않습니다. 기능에 대해 이야기하고, 화면, 메뉴, 대화상자와 같은 사용자 인터페이스 부품을 명세합니다.


기술 명세 - TECHNICAL SPECIFICATION

프로그램 내부 구현을 기술합니다. 자료구조와 관계형 데이터베이스 모델과 프로그래밍 언어, 도구, 알고리즘 선택과 같은 항목을 다룹니다.



 * 좋은 기능 명세에 대한 아이디어!


1. 면책 조항 

방어적인 내용 "이 명세는 완벽하지 않습니다." 시간이 흘러 명세가 완벽하게 되면 다음과 같이 면책 조항을 바꿀 수 있다. "제가 알기로는 이 명세는 거의 완벽합니다. 하지만 무언가 빠뜨렸을 경우에는 제게 말씀해주세요"


2. 저자

명세는 1명이 전담해서 작성해야만 합니다. 큰 제품일 경우라면, 여러 부문으로 쪼갠 다음에 각각을 개인에게 할당해서 독자적으로 명세하게 합니다. 어떤 회사는 명세에 이름을 넣어서 개인의 공로를 인정하는 관례를 이기적인 행동이나 팀워크를 해치는 일이라고 생각합니다.

하지만 이는 허튼 소리입니다. 사람들은 자신이 명세한 사항에 대해 책임감과 소유의식을 느껴야 합니다. 명세에서 무언가 잘못되면, 이를 수정할 책임이 있는 명세서 소유자를 지정해야 하며 이 사람 이름이 바로 명세서에 찍혀 있어야 합니다.


3. 시나리오

생생하고 현실적인 시나리오를 만들수록, 실 사용자나 가상으로 창조한 사용자 모두를 위한 제품을 더 잘 만들 수 있습니다.


4. 회피목표

팀 단위로 제품을 만들 때 없으면 못살겠다는 이유만으로 실제든 상상이든 간에 각자 좋아하는 상큼한 기능을 넣으려는 경향이 있습니다. 이렇게 불필요한 기능을 쳐내는 가장 좋은 방법으로 명세에 회피목표 항목을 추가합니다. 


5. 개괄

개괄은 명세를 위한 목차와 유사합니다. 개괄은 간단한 흐름도이거나 광범위한 아키텍쳐 관점에서 본 토론일 수도 있습니다. 모든 사람이 숲을 보기 위해 목차를 읽습니다. 이렇게 해야 나무도 의미가 있을 것입니다.


6. 세부사항

웹 타입 서비스를 설계할 때 세부사항을 정리하는  좋은 방법은, 모든 가능한 화면에 기준이 되는 이름을 붙인 다음, 너무나도 자세해 못 견딜 만큼 따분한 세부사항을 매 화면마다 기술하는 장을 제공하는 겁니다.

세부사항은 기능 명세에서 가장 중요한 핵심입니다.


7. 미해결 문제

명세 첫 버전에 미해결 문제를 남겨놓아도 나쁘지 않습니다. 문제점을 쉽게 찾을 수 있도록 특별한 스타일을 적용해서 표시를 하고, 적당한 대안이 있으면 이를 논의합니다. 프로그래머가 작업을 시작할 무렵에 이런 모든 미해결 사항들을 짚어놔야 합니다.

단순히 프로그래머가 모든 쉬운 작업부터 시작하도록 내 버려두고, 나중에 미 해결 문제를 푸는 방법이 옳다고 생각할지도 모르겠습니다. 하지만, 이는 잘못된 생각입니다. 프로그래머가 코드를 구현하려고 시도할 무렵에 나타나는 새로운 문제점과 씨름하는 과정에서 또 다른 문제점이 나타날 것이며, 당신이 미리 알고 있었으며, 예전에 끝냇어야 하는 미해결 문제 역시 그대로 남아 있을 것입니다. 설상 가상으로 난이도 높은 문제를 해결하는 과정이 코드를 작성하는 방법에도 상당한 영향을 미칠지도 모르겠습니다.


8. 방주 (SIDE NOTE)

명세를 작성하는 동안에 프로그래머, 테스터 , 마케팅팀원, 기술집필가와 같은 다양한 청중이 있음을 기억해야 합니다. 명세를 작성할 때 단지 특정 그룹에만 유용한 활자화한 사실을 고려하면 좋겠습니다. 예를 들어 프로그래머를 위해 기술적으로 유용한 몇가지 세부 사항을 기술하는 메시지를 '기술노트'항목으로 구분해서 기록할 수 있습니다. 마케팅 팀원은 이런 메시지를 무시하지만 프로그래머는 이런 메시지를 탐독합니다.


9. 명세는 지속적으로 개정해야 합니다.

주기적으로 개정하여 현실을 반영합니다. 명세는 항상 제품이 동작하는 원리를 최대로 반영하는 그림자 입니다. 명세는 단지 제품이 코드완료시점에서 굳어질 따름입니다.



 * 명세서 작성 팁


1. 재미있게 씁시다.

여러분이 작성한 명세가 유쾌하며 재미있고 읽기 쉽다는 이유로 당신을 얕보는 회사에 근무한다면, 어서 다른 회사를 찾는 게 낫습니다.


2. 명세를 쓰는 작업은 머리가 돌아가도록 코드를 쓰는 작업과 유사하다.

문서를 소개하려는 대상층을 감안하고, 단계마다 그 사람이 무엇을 이해하길 바라는지 먼저 상각해보세요. 문장마다 독자가 내용을 깊이 이해했을지, 문맥의 의미는 파악했는지 스스로 되물어보십시오. 그래야 명세를 읽는 높으신 분께서 수많은 기술 용어에 압도당해 처음부터 문서 읽기를 포기하거나 멈추지 않게 될 겁니다.


3. 최대한 단순하게 작성하라.

쉬운 문장으로 작성하는 방식은 왠지 프로답지 않다는 생각에, 형식적이며 현학적인 언어를 남발하지는 마세요. 가능한 가장 쉬운 언어를 사용해야 합니다. 실제화면 보다 명세서를 더 효과적으로 개선하는 방법은 없습니다. 그림은 천마디 말보다 낫습니다.


4. 여러차례에 걸쳐 검토하고 다시 읽어라.


5. 표준양식은 해롭다고 간주한다.

모든 명세는 일정한 형식을 갖춰야 한다라는 생각은 버리십시오.


-출처 - 조엘 온 소프트웨어 - 

Posted by 엘키 엘키

댓글을 달아 주세요


블로그 이미지
Software Engineer
엘키

공지사항

Yesterday31
Today29
Total1,605,483

달력

 « |  » 2020.8
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31          

글 보관함