2016년에 "아는 것, 할 수 있는 것, 하는 것"에서도 말했던 것처럼 배우기 어려운 기술들이 있다. 특히 TDD는 우리가 개발을 하던 순서를 바꿔야 하는 비직관적인 것이어서 익히기 매우 어렵다. 우리는 대개 기능을 구현하고 그 기능이 잘 동작하는지를 확인하기 위해 테스트를 추가한다. 또 AAA(Arrange, Act, Assert) 스타일(Given When Then과 동일)로 테스트를 추가할 때도 순서가 Assert, Act, Arrange가 아니고 Arrange, Act, Assert 순서로 테스트를 추가한다. 우리의 의식을 흐름 순서와 반대되어서 몸에 익히기 참 어렵다. 이 2가지 순서 때문에라도 TDD를 익히기는 어렵다.
그럼 TDD와 같은 익히기 어려운 기술을 어떻게 익힐 수 있을까?
내가 생각하는 어려운 기술을 배우는 방법은 쉬운 문제로 배우려는 기술을 익히라는 것이다.
위 그림은 Kent Beck이 TDD를 익히는 방법에 대해서 트윗한 내용이다.
1. 평소와 같이 코드를 작성
2. 코드를 작성한 후에 성공하는 테스트를 작성
3. 그리고는 지금까지 작성한 것을 revert(git reset --hard HEAD)
4. 이번에는 테스트부터 작성
5. 코드를 작성하여 컴파일되도록 함
6. 테스트가 실패하는 것을 확인
7. 코드를 변경하여 통과하도록 함
매우 공감 가는 글이다. 1,2번의 과정을 통해 이미 구현을 해 봐서 어떻게 구현하면 되는지 알기 때문에 TDD가 익숙하지 않더라도 4번 이후의 과정을 통해 TDD로 기능을 구현할 수 있을 것이다.
이런 방식을 바쁜 업무 시간에 하긴 어렵다. 내 결과물을 누군가는 기다릴 수도 있고, 한 번에 할 수 있는 일을 두 번 할 수 있는 만큼 여유가 대개는 없다. 업무 외 시간에 연습을 해 봐야 한다. 그래서 몸에 익혀서 바쁜 업무 시간에도 저절로 내 몸에서 나오도록 해야 한다.
코드리뷰, TDD 등을 강연하면 "어떻게 하면 빨리 배울 수 있나, 적용할 수 있나?"는 질문이 많다. 한 번에 잘할 수 없다. 아마 한 번에 잘할 수 있는 것이라면 이런 질문을 하지도 않았을 것이다. 이런 질문은 존재할 수 없는 답을 찾는 것으로 보인다.
Kent Beck의 글처럼 쉬운 문제로 배워야 한다.
"Continuous Delivery: Reliable Software Releases through Build, Test, and Deployment Automation"에서 나오는 말이다. 이 말을 설명할 때 나는 연말정산이 생각난다. 오랜 직장 생활을 했음에도 나는 연말정산 때마다 방법이 잘 생각이 나지 않아 고생을 한다. 하고 나면 별것 아닌데 할 때는 참 어렵게 느껴진다. 왜 그럴까? 연말정산이 정말 어려워서일까? 아니다 빈도 때문이다.
위 그림은 Martin Fowler가 FrequencyReducesDifficulty라는 글에서 보여준 그림이다. 어떤 행위를 하는 간격이 길면 길수록 고통은 심해진다는 것이다. 즉, 빈도가 어려움을 만든다는 말이다. Continuous Delivery에서 말한 것과 일맥상통한다.
드물게 하면 고통스럽다.
그러니 고통스러우면 더 자주 해야 한다.
변화를 추구하다가 자신들에겐 안 맞는 것 같다고 포기하는 경우를 많이 봤다.
위 그림은 "마이그레이션을 도중에 멈추면 안 되는 이유"라는 글에서 알게 된 그림이다. 온프레미스에서 클라우드나, 모노리딕에서 MSA로 마이그레이션을 할 때 어려움이 있다고 포기하면 안 된다는 내용의 글로 기억한다.
변화를 추구하면 처음에는 성과가 나빠질 수 있다. 새로운 기술을 배워야 하기에 이전에 익숙한 기술을 사용할 때보다 성과가 떨어질 수 있다. 이때
이 기술은 우리의 환경에는 맞지 않아.
책에서나 가능한 것이지 현실적이지 않아.
라고 하면서 포기하면 안 된다. 이 즈음 고통의 계곡(valley of pain)에 빠져 있는 것이다. 고통의 계곡에 빠졌을 때 우리가 선택한 변화에 대해 믿음을 가지고 노력을 해서 고통의 계곡을 빠져나와야 한다. 고통의 계곡을 빠져나오면 기하급수적인 성장을 할 수 있다.
이 과정은 사람이 성장하는 것과도 닮아 있다. 흔히 우리는 사람이 사선으로 성장한다고 생각을 하지만, 실제로는 계단 성장을 한다고 한다. 계단 성장 바로 앞에서는 웅덩이에 빠져서 허덕이게 되는데, 이를 극복하고 웅덩이에서 빠져나온 사람이 수직 성장을 한다고 한다. 이런 반복적인 계단 성장을 멀리서 관찰하면 사선 성장을 하는 것처럼 보인다고 한다.
새로운 기술, 특히 어려운 기술을 배울 때 "고통의 계곡" 즉 웅덩이에 빠지는 일이 일어나기 마련이다. 이를 당연시 여기고 올바른 노력에 대한 신념을 가지고 극복해야 어려운 기술을 터득할 수 있다.
야구선수인 아들을 따라서 아들이 연습하는 것을 많이 따라다녀 봤다. 코치님들은 선수에게 매우 세밀한 것까지 신경을 쓰며 연습을 시킨다. 특히 포수가 투수가 던진 공을 잡아서 2루에 송구하는 과정은 많은 연습이 필요한데 이때 다음과 같은 방식으로 훈련을 한다.
공을 받아서 왼손 글러브와 오른손이 중간에서 만나기만 하기
오늘손으로 공을 빼서 원을 그리며 오른쪽 귀 근처로 오른손이 가기
2루로 던지기
던지고 나서 하체 자세를 잡기
각 과정을 반복적으로 연습해서 몸에서 저절로 나올 때까지 각개동작으로 연습을 한다. 그리고 충분히 연습이 되면 연속 동작을 연습하다(유튜브에서 비슷한 영상을 찾아보니 "도루 싹-다잡게 해드립니다! 포수 2루송구 레슨!!" 이런 영상이 있었다).
하지만 시합에서는
공 잡고 던지기
만 신경 쓰라고 한다. 연습 때 신경을 쓰던 세밀한 동작, 과정, 자세 등은 잊으라고 한다.
연습장에서 충분히 연습을 하고 나면 시합장에서는 그냥 몸에서 나오는 대로 경기를 하는 것이다. 타격도 마찬가지다. 시합에서는
공보고 공치기
를 하라고 한다.
우리도 배우고 싶은 기술을 연습장(업무 외 시간)에서 충분히 배워서, 실전에서 내가 의식하지 않아도 몸에도 나오도록 해야 하는 것이다.
다들 어렸을 적에 처음 자전거를 배운 경험이 있을 것이다.
이 영상에서 처럼 누군가(대개 아버지)가 뒤에서 잡아주면서 배우게 된다. 아이는 아버지에게 "절대 놓으면 안 돼"라고 말하면서 긴장을 하고 자전거에서 넘어지지 않기 위해 집중을 한다. 시간이 좀 흐르고 뒤를 보면 아버지가 잡아주지 않고 있는 것을 발견하고는 넘어진다. 하지만 이후에는 아버지가 잡아주지 않아도 혼자서 자전거를 탈 수 있게 된다. 대부분의 아이들은 자전가 타는 법에 대한 책을 공부하지 않고 이런 방식으로 자전거를 배운다. 물론 자전거 선수가 되기 위해서는 책을 보고 공부를 해야겠지만...
우리도 대개 새로운 코딩 관련 기술을 배울 때 책을 섭렵하고 코드를 작성해보지는 않는다. 대개는 튜토리얼을 살짝보고 이리저리 코딩을 해 보면서 사용법을 익히고, 후에 깊은 지식이 필요하면 책을 보고 공부를 하게 된다.
어려운 기술을 배울 때도 그랬으면 한다. 완전히 이해하고 해 보기보다, 가볍게 해 보면서 익히는 것으로 시작했으면 한다. 이런 접근법을 취하면 "어떻게 하면 빨리 배울 수 있나, 적용할 수 있나?"라는 질문을 덜하게 될 것 같다. 한 번에 잘하기 어렵다. 대개 혁신적인 새로운 시도는 90%가 실패한다고 한다. 그러니 가볍게 빠르게 시도해 보는 것이 좋은 전략이 될 수 있다고 생각한다(희생적 아키텍처도 참고하면 좋을 것 같다).
변화를 추구하여 새로운 기술이나 적합한 기술을 도입해서 개선해야 한다. 지금 내가 익숙한 방법으로는 달성할 수 있는 결과는 제한적이다(한계가 있다). 실패를 하지 않기 위해서 내게 익숙한 어제와 같은 방법으로 정말 열심히 한다면 조금은 나아질지 몰라도 큰 차이를 만들 수는 없다. 하지만 적합한 기술을 도입한다면 실패할 가능성은 높지만 큰 개선을 이룰 수 있을 것이다.
구글에서 "no thanks we are too busy"라고 이미지 검색을 하면 다음 그림이 나온다.
지금 나도 네모난 바퀴를 굴리는데 너무 바빠서 동그란 바퀴로 교체할 시간이 없다고 말하고 있는지 돌아볼 필요가 있다.