실용주의 프로그래머
"개발자를 위한 정석적인 자기계발서"
여전히- 현실세계에서 개발자같은 개발자를 찾기란 어려운 듯하다. 내가 말하는 개발자같은 개발자는 비속어로 "뼈발자" 이런 뜻으로 말하고 싶지는 않지만 어느정도 비중을 차지한다고 생각한다.
이 책이 개발자처럼 행동하는데 큰 도움을 줄 수 있다고 믿는다.
이 책에서는 많은 팁을 'tips: nn'
으로 개발자는 이런생각을 하는게 좋다 라는 내용을 알려준다. 관련 내용을 살펴보자.
1. 자신의 기술(craft)에 관심과 애정을 가져라
아무리 소프트웨어 개발을 잘 하려는 관심과 애정이 없다면, 그 일을 하는 것에 아무 의미가 없다고 생각한다.
2. 자신의 일에 대해 생각하면서 일하라!
어떤 일을 하든지 자기가 무엇을 하고 있는지 생각하면서 일해라- 모든 개발 과정에서, 매일, 모든 결정 과정에 지속적이고 비판적으로 평가해보는 것! 동시에 분석하기!
3. 어설픈 변명을 만들지 말고 대안을 제시하라.
책임져라! 너가 잘못했던 잘했든 네가 했던 일에 대해서 책임지고 받아들이는 연습을 하라. 어설픈 변명을 만들생각이라면 그만둬!
4. 깨진 창문을 내버려두지 말라.
깨진 창문을 발견했다고 가만히 놔두면 구린내가 진동하는 환경으로 변할 것이다. 너는 깨진창문(나쁜 설계, 잘못된 결정, 혹은 형편없는 코드)을 언제나 가만히 놔두면 말자. 발견하자마자 바로 고쳐라. 적절히 고칠 시간이 충분치 않다면 판자로 덮는 것만으로도 하라.
5. 변화의 촉매가 되라.
''돌멩이 수프와 삶은 개구리'' 를 예를 잘 기억하자. 너는 사람을 움직이게 하는 지혜를 배웠다. 잊지말자.
6. 큰 그림을 기억하라.
삶은 개구리가 되지 않기 위해 늘 큰 그림에 주위를 기울여라. 개인적으로 무엇을 하고 있는가에만 정신을 쏟지 말고, 주변에서 무슨 일이 벌어지는지 지속적으로 살펴보라.
7. 품질을 요구사항으로 만들어라.
나는 이 말을 품질도 요구사항으로 만들어라. 라고 정의하고 싶다. 내가 개발한 건 언제나 최종 endpoint는 사용자이다. 사용자에게 맞출 수 없다면 서비스는 죽은 것.
8. 지식 포트폴리오에 주기적으로 투자하라.
- 매년 새로운 언어를 최소 하나를 배워라
- 기술 서적을 분기마다 한 권씩 읽어라.
- 비 기술 서적도 읽어라.
- 수업을 들어라.
- 지역사용자 모임에 참여하라.
- 다른 환경에서 실험해보라.
- 요즘 흐름을 놓치지 마라.
- 인터넷을 이용하라.
학습의 기회
구루 다루기
전 세계에 걸친 인터넷의 전파로, 어느 순간 구루가 엔터키만큼이나 가까워졌다. 그럼 어떻게 구루를 찾고, 또 여러분과 대화할 구루를 어떻게 구할까?
여기엔 몃 가지 비결
- 여러분이 뭘 묻고 싶어 하는지 정확히 알고, 가능하면 구체적이 되도록 하라.
- 질문은 조심스럽고 예절바르게 써라. 여러분이 뭔가 부탁하는 입장이라는 사실을 기억하라. 답을 요구하고 있는 것이 아니다.
- 질문을 썼으면 일단 답이 있는지 다시 한번 찾아보라. 키워드를 몇 개 뽑아서 웹을 검색해 보라. 관련 FAQ를 찾아보라.
- 공개적으로 물을지 개인적으로 물을지 정하라. 유즈넷 뉴스그룹은 어떤 주제에 관해서건 전문가들을 만날 수 있는 훌룡한 장소이긴 하지만, 어떤 사람들은 이런 그룹들의 공개성에 대해 경계를 한다. 대신 구루와 직접 이메일로 소통할 수 있다. 어느 쪽을 선택하건 의미 있는 제목을 달아라.
- 물러서서 인내를 갖고 기다려라. 사람들은 바쁘기 때문에 구체적인 답을 얻을 때까지 며칠을 걸리기도 한다.
마지막으로 답해주는 사람들 모두에게 고맙다는 말을 꼭 전하라. 그리고 사람들의 질문 중에 여러분이 답할 수 있는 게 있다면 참여해서 자신의 몫을 하라.
9. 읽고 듣는 것을 비판적으로 분석하라.
나는 항상 이말을 무의식적으로 알고 있다고 생각했다. 근데 어느날 다시 살펴보면 너무 내가 모든 것을 삐딱하게 세상을 바라보는건 아닌가 라는 생각을 하게 됐다.
개발자이기 때문에 이런 생각을 할 수 있는 것이라 생각하자.
비판적으로 분석한다는 것은 차고 넘쳐나는 기술 출판물에 적용함으로써 복잡한 해답을 이해할 수 있을 것이다.
'나는 무시당하느니 차라리 샅샅이 흝어보는 시선이 낫다고 봐요.' - 메이 웨스트
10. 무엇을 말하는가와 어떻게 말하는가 모두 중요하다.
- 말하고 싶은 게 무엇인지 알아라.
- 청충을 알아라.
- 무엇(What)을 배우길 원하는가?
- 말하려는 것에서 그들의 관심(Interest)있어 하는 건 무엇인가?
- 얼마나 소양(Sophisticated)이 있는가?
- 어느정도의 구체적인(detail)내용을 원하는가?
- 누가 정보를 소유(owe)하길 원하는가?
- 그들이 경청하도록 동기(motive)를 주려면 어떻게 해야 될까?
- WISDOM - 청중이해하기
- 때를 골라라.
- 스타일을 골라라.
- 멋져 보이게 하라.
- 청중을 참여시켜라.
- 청자가 되어라.
- 응답하라.
11. DRY - 반복하지 마라 (Don't Repeat Yourself)
- 강요된(impose) 중복 - 개발자들은 다른 선택이 없다고 느낀다. 환경이 중복을 요구하는 것처럼 보인다.
- 부주의한 중복. - 개발자들은 자신들이 정보를 중복하고 있다는 것을 깨닫지 못한다.
- 참을성 없는 중복. - 중복이 쉬워 보이기 때문에 개발자들이 게을러져서 중복을 하게된다.
- 개발자간의 중복. - 한 팀에 있는(혹은 다른 팀에 있는) 여러 사람들이 동일한 정보를 중복한다.
12. 재사용하기 쉽게 만들어라.
13. 관련 없는 것들 간에 서로 영향이 없도록 하라.
직교적인 시스템을 기억하자. 개발에서 직교적이다
라는 의미는 일종의 독립성이다.
직교적인 시스템을 개발하기 위한 노력을 계속하라.
14.최종 결정이란 없다.
우리는 흔히 '오류'라는 것을 겪는다. 여기서 말하는 오류가 무엇을 의미하는지 생각해볼 필요가 있지만, 지면상 생략하고 흔히 DRY, 유연한 아키텍쳐 등 겪어보지 못한 미래에 대비해 코드를 작성하라고 하지만, 생각은 해볼 수 있지만 정답은 없다.
15. 목표물을 찾기 위해 예광탄을 써라
예광탄이란? 목표물을 맞추기 위해 일단 총에서 중간에 넣는 탄으로 탄로가 빛으로 보여줌으로써 타켓점을 맞출 수 있는 탄을 말한다. 개발에서도 예광탄이 중요하다고 생각할 수 있다. 모든 프로젝트가 0부터 10까지 모든 상황을 알고 그에 맞쳐서 대응하기란 불가능하다. 그럴 수 없다. 때문에 '어둠 속에서 빛을 내는 코드'를 만들기 위해서는 중간중간 예광탄을 만들어야한다.
프로토타입과는 조금 다른 내용이다.
16. 프로토타입을 통해 학습하라.
프로토타입을 개발하면 고려해볼 수 있는 부분으로
- 아키텍쳐
- 기존 시스템에 추가할 새로운 기능
- 외부 데이터의 구조 혹은 내용
- 성능 문제
- 사용자 인터페이스 설계
프로토타이핑은 학습 경험이며, 프로토타입의 가치는 생성된 코드에 있는 것이 아니라 이를 통해 배우게 되는 교훈에 있다. 이것이 프로토타이핑의 진정한 핵심이다.
17. 문제 도메인에 가깝게 프로그래밍하라.
18. 추정을 통해 놀람을 피하라.
19. 코드와 함께 일정도 반복하며 조정하라.
어떤 어플이든 프로그램을 제어하거나 환경설정하기 위한 단순한 언어든, 규칙이나, 절차를 명시하기 위한 더 복잡한 언어든, 우리는 여러분의 프로젝트를 문제 도메인에 가까운 곳으로 옮길 방법을 궁리해야 한다.
사실 개발일정을 추정하는건 정말 어려운 일이다. 겪어보니 그런것 같다. 아무리 몃일이라고 이야기해도 문제인것 같다.
그럼 어떻게 추정을 할 것인가?
정확한 날짜를 이야기는 지양하고 오차가 생길수 있는 단위로 이야기하라.
똑같은 문제를 겪었던 사람에게 질문해보기
무엇을 묻고 있는지를 이해하라 => 시스템의 모델을 만들어보라 => 모델을 컴포넌트로 나누어라 => 각 매개 변수에 값을 주어라 => 답을 계산하라 => 추정치를 기록하는 용기
만약 누군가 추정에 대해 물으면 무엇이라 대답해야 할까?
"나중에 전화드릴께요."
20. 지식을 일반 텍스트로 저장하라.
TIL와 같이 자명한 데이터를 저장하라!!
21. 명령어 쉘의 힘을 사용하라.
GUI 인터페이스의 장점은 WYSIW-YG(What You See is What you Get), 즉, 여러분이 보는 것이 여러분이 얻는 것이라는 것이다. 그러나 단점은 WYSUAYG(What You see Is All You Get) 즉, 여러분이 보는 것이 여러분이 보는 전부라는 것
GUI환경은 일반적으로 설계자의 의도에 따른 제약을 받는다.
때문에 명령어 쉘의 힘을 활용하는 것은 너의 사고를 넓히는 첫번째 발자국.
//TODO Git-Command 와 VIM-Command 마스터 하기.
22. 하나의 에디터를 잘 사용하라.
에디터 하나를 골라서 완전히 마스터하고, 모든 편집 작업에 그 에디터를 사용하라.
//TODO IntelliJ + ideaVIM 활용하기
23. 언제나 소스코드 관리 시스템을 사용하라.
GIT으로 관리하는 부분 : )
24. 비난 대신 문제를 해결하라.
버그가 여러분의 잘못인지 다른 사람의 잘못인지는 그리 중요한 게 아니다. 어쨌거나 그 버그는 여러분의 문제로 남는다.
25. 디버깅을 할 때 당황하지 마라.
버그를 목격하거나 혹은 버그 보고서를 보는 순간 첫 반응이 "그건 불가능해"라면 여러분은 두말할 필요 없이 틀렸다. "하지만 정랄 그럴 리가 없는데"로 시작하는 일련의 사고에 신경세포 하나라도 소모하지 마라. 왜냐하면 분명히 그런 일이 일어날 수 있으며, 실제로도 일어났기 때문이다.
디버깅을 할 때 근시를 조심하라. 표면에 보이는 증상만 고치려는 욕구에 저항하라. 실제 문제는 여러분이 관찰하고 있는 것에서 몇 단계 떨어져 있고, 또 다른 여러가지와 연관되어 있을 확률이 다분하다. 항상 문제의 근본적인 원인을 발견하려고 노력하고, 그 문제의 특정한 증상만 고치려고 하지 말자.
26. 'select'는 망가지지 않는다.
자신의 실수일 수 있는 일을 시스템의 문제라고 비난하기 시작하는 사람이 있기만 하면, 우리는 그 사건을 회고하게끔 'select가 망가졌어'라는 문구를 사용하자.
발굽 모양을 보면 말부터 생각해야지. 얼룩말부터 생각하지는 말자. OS는 아마 망가지지 않았을 것이다.
27. 가정하지 마라. 증명하라
놀라운 버그를 마주치면, 단순히 그걸 고치는 것을 넘어서, 왜 이 실패가 더 일찍 발견되지 않았을 까 생각해 볼 필요가 있다. 버그를 미리 잡을 수 있도록 단위 테스트나 다른 테스트를 수정할 필요가 있는지 고려하라.
버그를 고치는 데 긴 시간이 걸렸다면 왜 그런지 자문하라. 다음번에는 이 버그를 좀 더 쉽게 고칠 수 있도록 할 수 있는 뭔가가 있을까? 더 나은 테스팅 훅을 만들어 넣거나, 로그파일 분석기를 작성할 수도 있다.
마지막으로, 만약 버그가 누군가가 내린 잘못된 가정의 결과라면, 이 문제를 전체 팀과 함께 토론하라. 한 사람이 오해했다는 것은 여러 사람이 그럴 수 있다는 이야기다.
28. 텍스트 처리 언어를 하나 익혀라.
파이썬의 Jinja2와 같이 텍스트 처리 언어를 익히면 생산성이 올라갈 것이다!
- 데이터베이스 스키마 관리
- 자바 속성 액세스
- 테스트 데이터 생성
- 서적 집필
29. 코드를 작성하는 코드를 작성하라.
위에서 말한 데이터베이스 스키마와 같이 중복적으로 해야만 하는것을 만들어주는 코드를 위한 코드를 작성하라.
30. 완벽한 소프트웨어는 만들 수 없다.
삶의 공리로 받아들여야 하는 지론이다!!!
만약 모든 사람이 실제로 당신을 잡으려고 한다면, 편집증도 좋은 생각이다. - 우디 앨런(Woody Allen)
cf) 편집증 - 인격의 붕괴를 보이지는 않으나 피해망상·추적 망상과 같은 논리적·체계적인 망상을 나타내는 병적인 상태
31. 계약에 따른 설계를 하라.
32. 일찍 작동을 멈추게 하라.
자바에 왜 RunTimeReception 이 있는지 알게 된 대목.
만약 이 예외가 잡히지 않으면 프로그램의 최상위 수준까지 나올 것이고, 결국 스택트레이스를 출력하여 프로그램을 멈춰버릴 것.
33. 단정문을 사용해서 불가능한 상황을 예방하라.
"하지만 물론 그건 절대 일어나지 않을 거야!"라는 생각이 든다면, 그걸 확인하는 코드를 추가하라. 즉 테스트 코드를 만들어라
34. 예외는 예외적인 문제에 사용하라.
왜 우리는 이런 식으로 예외에 접근할 것을 제안하는가? 예외가 있다는 것은 즉 컨트롤의 이동이 즉각적이고 로컬하지 않다는 것을 말한다. 일종의 연쇄 같은 것이다. 예외를 정상적인 처리 과정의 일부로 사용하는 프로그램은 고전적인 스파게티 코드와 가독성 문제와 관리성 문제를 전부 떠안게 된다. 이런 프로그램은 캡슐화를 깨트린다. 예외 처리를 통해 루틴과 그 호출자들 사이의 결합도가 높아져 버린다.
예외처리기는 또 다른 대안이다. 즉, 예외처리기는 에러를 감지되었을 때 호출되는 루틴이므로, 특정 부류의 에러를 처리하기 위해 어떤 루틴을 등록하게 된다.
35. 시작한 것을 끝내라.
이건 사실 어떤 상황에서 다 적용되는 말이라고 생각된다. 단순히 리소스를 할당하는 루틴이나 객체가 리소스를 해제하는 책임 역시 져야한다는 것 의미할 뿐 아니라, 나에게는 시작한 일에 대해서 OutCome을 내라는 의미로 들린다! 명심하자!
36. 모듈간의 결합도를 최소화하라.
디미터 함수의 법칙이란 프로그램에서 모듈간 결합도를 최소화하여 시도한다. 이 법칙은 한 객체가 제공하는 메서드에 접근하기 위한 또 다른 객체를을 통하는 것을 허용하지 않는다. 디미터 법칙은 다음과 같다. '부끄럼 타는' 코드를 작성해서 디미터 법칙을 가능한 마족시킨다면 우리의 모적을 이룰 수 있다.
class Demeter {
privat:
A *a;
Int func();
public:
//...
void example(B& b);
}
void Demeter::example(B& b){
C c;
Int f = func(); <- 자신
b.invert(); <= 메서드로 넘어온 인자
a = new A();
a->setActive(); <= 자신이 생성한 객체
c.print() <= 직접 포함하고 있는 객체
}
}
cf) 디미터 법칙은 객체의 모든 메서드는 다음에 해당하는 메서드만을 호출해야 한다고 말한다.
디미터 법칙을 따르면 함수를 호출하는 클래스의 응답집합 크기를 줄일 수 있기 때문에 좀 더 에러가 적은 클래스들을 만들 수 있다.
https://www.slideshare.net/SangminLim/ss-63457159
아무리 뛰어난 천재라도 세부사항에 집착하면 그 재능이 발취되지 않는 법이다. - 레비의 8번째 법칙
37. 통합하지 말고 설정하라
우선 시스템을 되도록 설정가능하게 만들기 바람. 통합하거나 엔지니어링하지 말고 설정 옵션으로 구현해야 한다!
38. 코드에는 추상화를, 메다데이터에는 세부 내용을
- 설계의 결합도를 줄여 좀 더 유연하고 적응성 있는 프로그램을 만들 수 있다.
- 세부사항을 코드 밖으로 몰아냄으로써 보다 강하고 추상적인 디자인을 만들 수있다.
- 애플리케이션을 커스터마이징하기 위해 다시 컴파일할 필요가 없다. 이런 방식의 커스터마이징을 통해 실제 제작 공정 시스템에서 일어날 수 있는 치명적인 버그에서 벗어나는 우회로를 쉽게 만들 수 있다.
- 메타데이터는 범용 프로그래밍 언어보다 문제 도메인에 가까운 방식으로 표현될 수 있다
- 동일한 애플리케이션 엔진과 상이한 메타데이터를 이용해 여러 다른 프로젝트를 진행 할 수 있다.
가능한 마지막 순간까지 세부 정의를 피하고, 세부사항을 소프트하게, 변화하기 쉽게 남겨 두라. 빠르게 변화할 수 있는 해결안을 강구함으로써 많은 프로젝트에 범람하는 방향 전환이란 홍수에 보다 유연하게 대처할 수 있게 될 것이다.
39. 작업흐름 분석을 통해 동시성을 개선하라.
우리는 프로그래밍을 하나의 흐름안에서 모두 해결하려는 경향이 있다고 생각한다. 이런 생각은 절차지향의 Flowable할 수 있는 것이라고 판단한다.
근데 이는 잘못된 판단이라고 생각한다. 동시에 실행될 수 있는 부분을 작업흐름에서 파악하고 언제나 동시성을 개선하자.
40. 서비스를 사용해서 설계하라.
컴포넌트 대신 서비스를, 즉 잘 정의되고 일관성 있는 인터페이스 뒤에서 일하는 독립적이고 동시적인 객체들을 만들 것!
41. 언제나 동시성을 고려해 설계하라.
42. 모델에서 뷰를 분리하라.
43. 칠판을 사용해 작업흐름을 조율하라.
여기서 칠판의 의미란, 형사가 범인을 잡기위해 사용하는 칠판처럼 범인을 잡기위해서 여러 조건들이나 문제들을 나열하고 이 상황에서 작업흐름을 잡아가는 것을 의미한다.
44. 우연에 맡기는 프로그래밍을 하지 말라.
우리는 어떤 정답을 도출하기 위해 여러가지 시도를 한다. 그리고 그 시도에서 답이 나오길 우연히 바라는 마음이 존재한다. 그러나 그러하면 안된다는 것을 프로그래밍하면서 여러번 겪는다.
즉, 의도적으로 프로그래밍해야한다.
- 언제나 자기가 지금 무엇을 하고 있는지 알아야 한다. 프레드는 일을 서서히 자기 손 밖으로 벗어나도록 내버려 두었고, 결국 개구리처럼 삶아져 버렸다.
- 맹목적으로 코딩하지 말라. 완전하게 이해하지 못한 애플리케이션을 빌드하려 하거나 익숙하지 않은 기술을 사용하려고 시도하는 행동은 우연에게 자기를 미혹해도 좋다는 초청장을 보내는 것과 다름없다.
- 계획을 세우고 그것을 바탕으로 진행하라. 머리 속에 있는 계획이든, 냅킨 뒤에 적어놓은 계획이든, CASE 도구로 만든 한쪽 벽면에 가득할 정도 계획이든 상관없다.
- 신회할 수 있는 것에만 기대라. 우연한 일이나 가정에 의존하지 말라. 어떤 상황에서 신뢰할 만한 것과 아닌 것을 판단하지 못하겠거든, 일단 가장 최악의 상황을 가정하라.
- 여러분의 가정을 문서로 넘겨라. 다른 사람과 가정에 대해 소통하는 데 도움이 될 뿐더러, 자신의 마음속에서 가정을 명확하게 하는 데에도 도움이 된다.
- 코드만 테스트할 것이 아니라 여분이 세운 가정도 테스트해보야 한다. 어떤 일이든 단지 추측만 하지 말고 실제로 시험해 보도록 하자. 즉 테스크코드를 짜라!!!!
- 노력을 기울일 대상의 우선순위를 정하라. 중요한 것들에 먼저 시간을 투자하라.
- 과거의 노예가 되지 말자. 기존 코드가 앞으로 짤 코드를 지배하도록 놓아두지 말자. 더 이상 적절한 코드가 아니라고 생각되면, 어떤 코드라도 교체할 수 있다. 한 프로그램 안에서도 예정에 한 일이 앞으로 할 일을 제약하지 못하도록 하라.
45. 여러분 알고리즘의 차수를 추정하라.
알고리즘 속도 생각하기.
46. 여러분의 추정을 테스트하라.
최고라고 언제나 최고는 아니다 라는 마음가짐으로 임하라.
47. 일찍 리펙토링하고, 자주 리팩토링 하라.
리펙터링해야 할 것들의 명단을 만들고 유지하라. 어떤 것을 지금 당장 리팩터링하기 힘들다면, 일정에 그것을 리팩터링할 시간을 확실히 포함시켜 두도록한다. 그 코드를 사용하는 사람들이 코드가 조만간 리팩터링될 것이라는 사실과 그 사실이 그들의 코드에 어떤 영향을 주게 될지 인지하도록 만들어야 한다.
48. 테스트를 염두에 두고 설계하라.
모듈을 설계할 때도, 심지어 루틴 하나를 설계할 때도, 그것이 지켜야 할 계약과 계약을 지키는지 테스트하는 코드도 함께 설계해야 한다. 테스트를 통과하고 계약을 지키는 코드를 설계하다 보면 자연스럽게 그렇게 설계하지 않았으면 생각나지 않았을 경계 조건이나 다른 문제들을 고려하게 된다. 애초에 에러가 나지 않게 하는 것보다 에러를 고치는데 더 좋은 방법은 없다. 사실 코드를 구현하기 전에 테스트를 먼저 만들어보면, 그 코드의 인터페이스가 고정되기 전에 미리 시험해 볼 수 있게 된다.
49. 소프트웨어를 테스트하라. 그렇지 않으면 사용자가 테스트하게 될 것이다.
테스트 코드의 중요성!!!
50. 자신이 이해하지 못하는, 마법사가 만들어준 코드를 사용하지 말라.
우리는 무수한 인터넷 시대에 살고 있다. 그 안에는 많은 코드들이 있고 이를 이해하지 못한 상황에서 단순히 가져다가 쓰는 행위는 하지말자! 자신이 완벽하게 이해하지 못하는 것에 의존하며 지내지 않아야 할것 !!
51. 요구사항을 수집하지 말고 채굴하라.
52. 사용자처럼 생각하기 위해 사용자와 함께 일하라.
사용자 또는 클라이언트에게 요구사항을 수집하지 말고, 직접 사용자가 되어 요구사항을 채굴하라! 대개의 요구사항은 분명하게 주어지지 않기 때문에, 더욱 복잡해질 것이다.
53. 구체적인 것보다 추상적인 것이 더 오래간다.
'더 멀리 보기'란 미래 예측을 말하는가? 아니다. 그것은 다음을 의미한다.
시스템은 Date의 추상화를 적극적으로 사용한다. 시스템에는 포메팅, 저장, 수학 연산등을 일관되고, 보편적으로 제공하는 DATE서비스가 구현될 것이다.
54. 프로젝트 용어사전을 사용하라.
사용자와 개발자가 동일한 것을 다른 이름으로 가리키는 프로젝트가 성공하기는 매우 힘들며, 같은 이름으로 다른 것을 지칭하는 상황에서는 더더욱 어렵다. 때문에 프로젝트를 시작하기 전 프로젝트 용어사전을 사용하자.
여기서 우리는 다시한번 결국은 모두 글쓰기
라는 것을 인지할 수 있다.
55. 생각의 틀을 벗어나지 말고, 틀을 찾아라.
풀리지 않는 문제와 마주쳤다면, 생각해 볼 수 있는 모든 가능한 해결 경로를 눈앞에 나열해보라. 아무리 쓸모없고 바보같이 보이는 경로라도 절대 버리지 말라. 이제 목록을 하나씩 점검하면서 왜 그 경로르 따라갈 수 없는지 설명해보라. 정말 확신하는가? 증명할 수 있는가?
플리지 않는 문제에 대한 신선한 해결책의 좋은 예로 트로이의 목마를 생각해보자. 어떻게 해야 들키지 않고 성벽에 둘러싸인 도시에 병사들을 들여보낼 수 있을 까? '성문을 통해서' 라는 생각은 처음부터 자살 행위나 마찬가지라고 생각해서 버려졌음이 뻔하다.
제약들을 범주별로 나누고 우선순위를 매겨라. 목공은 어떤 일을 시작할 때 그 일에서 필요한 가장 긴 조각을 먼저 자르고, 남은 나무에서 작은 조각들을 잘라낸다. 비슷한 방식으로, 우리도 제일 구속이 심한 제약들로부터 파악해 내고 나머지 제약들을 그 안에서 맞춰 보아야 한다.
분명히 더 쉬운 방법이 있을 거야!
불가능하다고 느낄땐 한 걸음 뒤로 물러서서 다음 질문을 스스로에게 해 보아야 할 시점.
- 더 쉬운 방법이 존재하는가?
- 진짜 문제를 풀려고 노력하고 있나. 그렇지 않다면 중요하지 않는 기술적 문제에 정신이 팔려 있는 것인가?
- 왜 이것이 문제인가?
- 문제를 이렇게 풀기 어렵게 만드는 것이 무엇인가?
- 반드시 이 방법으로 해야 하는가?
- 반드시 해야 하는 일이긴 한가?
생각하라. 고르디우스의 매듭을!
우리에게 필요한 것은 진짜 제약과 우리를 오도하는 제약 그리고 그 차이를 구별하기 위한 지혜.
제랄드 와인버그의 [Are you Lights On?] / 인지 심리학[Cognitive Psychology] / 에드워드 드 보노
56. 준비가 되었을 때 시작하라.
'내면의 테니스' 라고 불리는 테니스 지도 방식을 떠올리자. 몃 시간이나 공을 쳐서 그물을 넘기는 연습을 하고, 이때 정확성에는 특별히 신경을 쓰지 않는 대신, 어떤 목표(의자인 경우가 많다.)에서 얼마나 떨어진 곳에 공이 떨어졌는지 소리 내에서 말해야 한다. 말로 하는 반응이 잠재의식과 반사 신경을 훈련시켜서, 의식적으로는 어떻게 그리고 왜 실력이 느는지 모르면서 실력이 는다는 것이 이 훈련 방식의 핵심.
57. 어떤 일이든 설명하기보다 실제로 하는 것이 쉽다.
여러분은 요구사항의 수집, 설계, 구현을 훌륭한 시스템을 전달한다는 동일한 과정의 서로 다른 측면으로서 보아야 한다. 요구 사항을 수집하고, 그 후 명세를 쓰고, 그런 다음 코딩을 시작하는 등의 모든 것이 고립되어 진행되는 환경을 믿지마라. 대신, 이음새 없는 접근방법을 채택하도록 하라. 명세와 구현은 단지 동일한 과정, 즉 요구사항을 포착해서 명문화하는 노력의 다른 측면일 뿐이다.
58. 형식적 방법의 노예가 되지 마라.
우리는 형식적 기법과 방법들을 활용하고 이를 유연하게 대처하는 법을 익혀야 한다. 애자일기법이라 하여 그것의 명확한 스펙을 따르는 것이 아닌, 팀의 분위기, 팀의 성향, 사람들의 성향에 맞춰 형식적 방법의 노예가 되지 말아야 한다!
59. 비싼 도구가 더 좋은 설계를 낳지는 않는다.
형식적 방법은 단지 도구 상자 속의 또 다른 도구일 뿐이라는 사실을 늘 기억하라. 만약, 주의 깊게 분석한 후에 어떤 형식적 방법을 사용할 필요가 있다고 생각한다면, 기꺼이 그렇게 하라. 하지만 누가 주인인지 분명히 기억하라. 절대로 방법론의 노예가 되지 말자.
어떤 방법의 거짓된 권위에도 넘어가지 말라. 사람들이 펼치면 몃백 평이넘을 클래스 다이어그램 종이 뭉치와 유스 케이스 150개를 들고 회의에 들어오더라도, 그 모든 것 역시 틀릴 가능성이 있는 요구사항과 설계에 대한 그들의 해석일 뿐이다. 어떤 도구의 결과물을 볼 때 비요이 얼마나 들었을지 생각하지 않도록 노력하라.
실용주의 프로젝트
실용주의 팀이란 무엇일까?
- 깨진 창문을 없애라
- 삶은 개구리
- 소통하라!
- 반복하지 마라
- 직교성
60. 팀을 기능 중심으로 조직하라.
- 자동화
- 덧칠을 언제 멈출지 알아라.
61. 수작업 절차를 사용하지 마라.
어떤 WIKI에 수작업을 통해서 어떤 버튼을 누르고 어떤 이동을 누르고 하는 상세한 설명이 있는 내용들이 있을 것이다. 우리는 이러한 것을 최대한 막아야 할 것이다.
다양한 개발자들이 똑같은 설명을 보고도 조금씩 다르게 세팅한다. 각 개발자들이 동일한 코드를 실행하는 데에도 애플리케이션의 움직은 미묘한 차이를 보였다. 그렇기 때문에 수작업 절차를 사용하지 않고, Cron
과 같이 자동화 할 수 있는 것을 항상 염두하자.
62. 일찍 테스트하고, 자주 테스트하라. 자동으로 테스트하라.
테스트 코드의 중요성을 나타내면서 테스트는 처음 시작할 때부터 전체의 일부로 봐야할 만큼 중요한 요소이다. 코드를 작성하자마자 테스트해야 한다. 그 작은 잔챙이들은 꽤나 빨리 자라나 사람을 잡아먹는 거대한 상어가 되는 고약한 성질이 있다. 상어를 잡는 일은 상당히 힘들다. 하지만 그렇다고 그 모든 테스트를 손으로 할 수는 없다.
버그를 빨리 발견될수록 고치는 비용이 적어진다. '코드 조금, 테스트 조금'은 스몰토크 세계에서는 유명한 격언이다. 우리는 제품 코드를 만드는 것과 동시에(혹은 이전에) 테스트 코드를 만듦으로써 그 주문을 우리것으로 할 수 있다.
63. 모든 테스트가 통과하리 전엔 코딩이 다 된 게 아니다.
어떤 코드를 만들었다는 이유만으로 여러분의 보스나 클라이언트에게 완료 되었다고 말할 수 있는 게 아니다. 그렇지 않다. 무엇보다도 코드는 결코 완료될 수가 없다.
무엇을 테스트할지
- 단위 테스트
- 통합 테스트
- 유효성 평가와 검증
- 자원 고갈, 에러 그리고 복구
- 성능테스트
- 사용편의성테스트
64. 파괴자를 써서 테스트를 테스트하라.
팀원중 한명을 파괴자로 임명해, 소스 트리의 카피를 별도로 만들어 취한 다음, 고의로 버그를 심고 테스트가 잡아낼지 검증하는 것.
65. 코드 커버리지보다 상태 커버리지를 테스트하라.
66. 버그는 한 번만 잡아라.
결국은 모두 글쓰기.
cf books) Writer's Workshops and Work of Making Things - Perason Edu, The Element of Style
67. 한국어도 하나의 프로그래밍 언어인 것처럼 다뤄라.
68. 문서(document)가 애초부터 전체의 일부가 되게 하고, 나중에 집어넣으려고 하지 말라.
먼저 내부 분서부터 시작하라.
위대한 유산
69. 사용자의 기대를 부드럽게 넘어서라
현실적으로 프로젝트의 성공여부는 사용자들의 기대를 얼마나 잘 충족하는가에 따른다. 그렇기 때문에 기대의 높낮이를 고려하여, 실행하도록 하자.
여기서 말하는 부드럽게 넘기기란?
- 기대를 상호 소통하기.
- 푸성 혹은 툴 팁 도움말
- 키보드 단축키
- 사용자 메뉴얼의 부록으로 만든 빠른 참조
- 색깔 입히기
- 로그 분석기
- 자동 설치
- 시스템의 상태를 체크하는 도구
- 훈련 목적으로 여러 버전의 시스템을 실행시킬 수 있는 기능
- 각 회사나 조직을 위해 만든 스플래시 스크린
오만과 편견
70. 자신의 작품에 서명하라.
실용주의 프로그래머는 책임을 회피하지 않는다. 그 대신 도전을 수용하고 자신의 전문적 지식을 널리 알리는 것을 기뻐한다. 만약 설계 혹은 코드에 대한 책임을 맡는다면, 스스로 자랑스러워할 만한 일을 해낼 것이다.
이 책의 내용은 여기서 끝난다.
그 뒤 부록A에 내용에서 언급했던 책들과 관련 자료에 대해 설명해주고 정말 인생깊었던 부분은 가장 맨 뒤에 나오는
실용주의의 확산과 미래 에 나오는 앤드류 헌트와 데이비스 토머스가 인터뷰 한 부분이 굉장히 흥미롭다.
아마도(?) 당시에는 루비가 핫한 언어로 떠올랐나보다. 그와 관련된 인터뷰가 쭉 나열되어있는데 굉장히 흥미롭고 마지막에 나온 이 한마디가 내 마음을 웅클하게 만들었다.
... 중략
앤디: 원스턴 처칠의 말을 이용하겠습니다.
*"절대로 포기하지 말고, 절대로 포기하지 말고, 절대로 포기하자 말라."*
'행위 돌아보기' 카테고리의 다른 글
함수형 사고 - [4] 열심히보다는 현명하게 (0) | 2019.07.26 |
---|---|
함수형 사고 - [3] 양도하라. (0) | 2019.07.21 |
함수형 사고 - [2] 전환 (0) | 2019.07.21 |
함수형 사고 - [1] 왜 (0) | 2019.07.18 |
[북리뷰] 손에 잡히는 VIM (0) | 2019.07.18 |
댓글