리뷰 - 실용주의 프로그래머
한국에 들어온 이후로 적지 않은 사람들로부터 추천을 받아서 항상 마음 속 한 구석에 꼭 읽어봐야지 하는 책으로 남아 있던 책이었다. 도서관에서 찾은 이 책은 그 추천수에 걸맞는 낡고 헤진 모습을 하고 있어 나를 더 설레게 했다.
생각보다 분량이 많아서 읽는데 적지 않은 시간이 들었지만 전체적으로 후회없는 선택이었다. 책에서 하는 말은 대개 여느 경력자 프로그래머들이라면 다 겪어보고 당연시 하는 것들이다. 하지만 사람은 대개 잊어먹기 마련. 이 책은 내가 그동안 세월이 흐르며 잊고 있던 부분들을 하나 하나 지적하며 뜨끔거리게 했다. 내가 얼마나 비효율적으로 일하고 있었는지를 부끄러워 하며, 허나 한 편으로는 깨닫는 과정을 즐기며 한 장 한 장 넘겼다. 몇가지 기억에 남기고 싶은 작가의 충고가 있어 나만의 언어로 남기어 본다.
1. 자신의 코드에 대한 책임을 져라.
어설프게 번명하지 말고 자신이 한 것은 했다고 시인하고 대안을 제시하라. 그 만큼 프라이드도 가져라.
2. 깨진 창문을 내버려 두지 마라.
깨진 창문을 중심으로 모든 것들이 조금씩 무질서해 진다. 그 것들을 그냥 지나치지 마라. 발견하는 즉시 고쳐라(리펙토링 하라.) 다른 사람의 코드도 마찬가지이다. 정 시간이 없다면 마크업 이라도 해 두어라.
3. 무엇을 해야 하는지, 어떻게 해야 하는지 알면 해라.
만약 지금 무엇을 해야 하는지 명백함에도 누구도 선뜻 나서지 않는다면 먼저 손을 들고 하라. 그리하여 다른 사람들도 조금씩 기여할 수 있게. 변화의 촉매가 되어라.
4. 요구사항과 요청사항을 구분하라.
이 것을 구분해야 하는 이유는 자명하다. 바로 시간과 자원이 제한되어 있기 때문이다. 실용주의 프로그래머는 “요청사항”을 구현하느라 반드시 요구되는 요구사항의 구현을 미루어서는 안될 것이다.
5. 지식의 포트폴리오를 점검-발전 시켜라.
다변하는 기술 위에서 사는 프로그래머에게 이러한 변화의 흐름을 지각하고 그에 적응하는 것은 당연한 것이다. 기본을 잊지 말되 기술과 IT의 흐름을 읽고 새로운 기술들을 익히고 적응하며 진화하는 프로그래머가 되어라. 그리고 새로운 기술을 읽힐 때는 겉할기 식으로 말고 깊이 있는 접근으로 새로운 기술을 익힐 때의 자양분이 되게 하라. 하나의 기술을 익히는 것은 여러 개의 또 다른 Aspect를 얻는 것이니깐.
6. 생각하라.
항상 생각하라. 지금 내가 무엇을 하고 있는지 분명히 알아라. 내가 비효율적이게 일하는 부분은 없는지. 불필요한 반복을 하고 있지는 않은지. 자동화 할 수 있는 것은 아닌지. 생각하고 생각하라. 비판적인 시야를 항상 열어 놓아라.
7. 소통하라.
소통을 하지 않으면 어떠한 아이디어도 소용이 없다. 진행되고 있는 당장 멈추어야 할 어떤 것을 멈출 수도 없다. 상대방과의 소통을 위해선 먼저 청중을 이해 해야 하는데, 다음이 청중을 이해하고 소통하는 데에 도움을 줄 것이다:
- What : 무엇을 배우길 원하는가?
- Interest : 말하려는 것에서 그들이 관심있어 하는 것은 무엇인가?
- Sophisticated : 얼마나 소양이 있는가?
- Detail : 어느 정도 구체적인 내용을 원하는가?
- Owe : 누가 정보를 소유하길 원하는가?
- Motive : 그들이 경청하도록 동기를 주려면 어떻게 해야 할까?
8. 반복하지 말라. (DRY : Don’t Repeat Yourself )
코드를 반복하지 말아라. 중복은 언제나 해악이 된다. 특히 개발자 간의 코드 중복은 시간을 허비하게 만들고 혼란을 가중시킨다. 재사용하기 쉽게 만들어라.
9. 추정하라.
사실상 추정은 불가피한 악처럼 느껴진다. 하지만 그것을 기억하라. 추정은 추정일 뿐이며 데드라인이 아니다. 따라서 추정하는 데 겁을 내지 말자. 일단 무슨 일을 할 때 얼마나 걸릴지 추정하는 습관을 길러라. 만약 실제 걸린 시간이 많이 차이가 났다면 괜찮다. 추정일 뿐이었으니까. 하지만 왜 추정이 빗나갔는지는 생각해 보아라. 이것이 추정하는 능력을 길러준다.
그리고 다음과 같은 단계를 반복하는 점증적 개발을 연습하라:
- 요구사항 체크 -> 위험 분석 -> 설계, 구현, 통합 -> 사용자와 함께 검증
- 1차 반복이 끝나면 구현과 함께 2, 3, 4차 반복을 하며 일정을 조절해 나가라. 점차 정확도가 올라갈 것이다.
10. 쉘을 사용하라.
쉘은 처음 접하는 사람에겐 좀 낯설지만 조금만 익숙해지면 생산성이 급증하는 것을 느끼게 된다. 윈도우 환경에서는 Cygwin이라는 유닉스의 인기 유틸들을 포함한 툴박스를 활용할 수 있다.
11. 디버깅의 원칙
마인드 비난 대신 문제를 해결하라. 아무리 급박해도 당황하지 마라. 절대 그럴리가 없다거나 불가능 하다면 특정 가능성을 배재하는 가정을 하지 말고 직접 증명하라. 가장 속이기 쉬운 자는 자기 자신이라는 격언을 기억하고 자신의 방어 시설을 모조리 해제하라. 버그를 고치고 나면 왜 그 문제가 일어났으며 어덯게 하면 좀 더 쉽게 이 버그를 잡을 수 있었을지 고민하라.
디버깅
- 트레이싱 (특정 값이나 실행 순서를 출력하여 확인 하는 것) 하라.
- 다른 사람에게 문제를 설명하라. 그러면 혼자 코드를 살펴 볼 때에는 당연히 여기고 지나갈 것을 명시적으로 이야기 하며 알게 된다.(고무오리)
- 서드 파티 라이브러리나 OS는 가장 나중에 의심하라.
12. 계약에 따른 설계를 하라.
예를 들어 특정 함수가 무엇을 요구하며 요구 사항을 만족 했을 때 최소한 무엇을 보장하는지를 “계약” 한 후 설계를 하라.
1
2
3
4
5
/*
* @require f != NULL
* @ensure getFont() == f
*/
void setFont(Font* f) { … }
함수에 잘못된 파라미터를 넘겨 주는 것을 걸르는 것은 호출자의 책임인가 피호출자의 책임인가? 필자는 호출자의 책임이라 한다. 난 아직 여기에 대해서는 잘 모르겠다. 트랜잭션을 처리하는 중에 에러가 있다면 그 트랙잭션은 롤백되어 실행되기 이전 상태로 돌아가야 한다. 중복 처리 가능성이 있기 때문이다.
13. 에러가 있다면 일찍 작동을 멈추게 하라.
에러는 무조건 빨리 잡을 수록 좋다. 안그러면 묻혀가다가 사용자에게까지 간다.
14. 어썰션(Assertion)은 불가능한 것들을 확인 하는데에 사용하라.
15. 메타 프로그래밍 하라.
”시스템”과 “세부사항”을 잘 구분하여 세부사항은 언제든 설정 가능하도록 하라. 세부 내용은 Configurable하도록 프로그래밍하라.
16. 시간적 결합(Temporal coupling)을 막아라.
동시에 할 수 있는 일은 동시에 하라. 언제나 동시성을 고려한 설계를 하라. 전역 변수나 정적 변수들이 왜 필요한지 묻고 필요하다면 동시 접근으로부터 보호하라.
17. 프로그래밍을 우연에 맡기지 말아라.
병사는 땅에 총검을 푹 찌르고 폭발을 예상하며 몸을 움찔한다. 폭발은 없다. 그래서 계속 찌르고 쑤시는 작업을 반복하면서 고통스러울 정도로 천천히 조금씩 앞으로 전진한다. 마침내, 지뢰가 없다는 것을 확신한 병사는 몸을 펴서 큰 걸음으로 성큼 걷기 시작한다. 그 순간 지뢰를 밟아 몸이 산산조각 난다. 우연에 맡기는 프로그래밍을 하다가는 이 병사 꼴이 날 수도 있다. 대신 의도적인 프로그래밍을 해야 한다. 내가 무엇을 하는지 그 결과가 어떠한지 분명히 그림을 그리며 하라.
요구사항을 만들어 내는 것부터 테스트에 이르기까지 어느 차원에서건 암묵적인 가정을 해서는 안된다. 가정하지 말라. 증명하라. 자신이 한 가정은 문서화를 하여 왜 그렇게 했는지를 기록하도록 한다.
노력을 기울일 대상의 우선순위를 정하고 계획적으로 하라.
기존의 코드가 앞으로 짤 코드를 지배하도록 놓아두지 말라. 언제나 리펙토링할 자세가 되어 있어야 한다.
18. 성급한 최적화를 조심하라.
어떤 알고리즘을 개선한다고 소중한 시간을 쏟기 전에, 그 알고리즘이 정말 병목현상인지를 먼저 확실히 해 두는 것이 좋다.
19. 리펙토링을 할 최적기는 바로 지금이다.
일찍 리펙토링 하고 자주 리펙토링하라. 리펙토링과 새로운 기능 추가를 동시에 하지 말자. 단계를 작게 나누어서 신중하게 작업하자. 고통을 관리하라. 지금 고통스럽더라도, 앞으로 더욱 고통스러워 질 것 같으면 지금 고치는 편이 낫다.
20. 테스트하라.
계약을 잘 지키는지 테스트하라. 모든 테스트가 통과하기 전엔 코딩이 다 된 게 아니다. 현존하는 테스트의 그물을 빠져 나가는 버그가 있으면 다시 그 버그가 생기는 일이 없도록 그물을 단단히 조여라. 그 케이스를 테스트에 추가하라. 버그는 한 번만 잡는다.
21. 사용자의 기대를 부드럽게 넘어서라.
그러기 위해서 기대를 상호 소통하라. 무엇을 기대하는 것이 합리적인지를 지속적으로 소통함으로써 산타클로스의 상상속 선물을 바라는 아이처럼 고객이 허황된 기대에 빠지는 일이 없도록 한다. 하지만 그들이 기대하는 것보다 조금만 더 해주자.
22. 자신의 작품에 서명하라.
다시 한번 나오지만 자신의 책임을 회피하지 말고, 도전을 수용하며 스스로 품질을 보증하라. 이것이 뼈있는 실용주의 프로그래머의 자긍심이다.