SlideShare a Scribd company logo
2017/10/11 10:13 http://blog.naver.com/knix008/221114494392
[ 소프트웨어 산업의 본질 - 03 ][ 소프트웨어 산업의 본질 - 03 ]
낙서장(2017)낙서장(2017)
실패는 어쩔 수 없이 발생한다. 모든 개발이 성공적으로 마무리 된다는 말은 거짓이다. 100% 일정내 개발이라는 것도 사
실일 수 없다. 실패의 정의를 “변경된 일정, 비용, 범위”라고 한다면 그럴수도 있겠지만, 사실상 계획은 계획일 뿐이다. 만
들기도 전에 잡아놓은 계획은 만들면서 구체적으로 변경될 뿐이다. 따라서, 실패를 받아들이는 태도를 바꾸지 않는한, 소
프트웨어 개발의 본질을 제대로 반영하지 못한다. 물론, 다른 개발도 마찬가지다. 대부분의 개발은 실패를 가정하고 있으
며, 그 중에서 몇가지만 성공해도 충분한 가치가 있는 것이다. 대기업은 100개의 제품을 개발해서 1개 정도의 대박 제품
을 만들면 이익을 남길 수 있지만, 중소기업은 10개의 제품을 만들어 5개 이상을 성공시키지 못하면 살아남기 힘들다. 여
기서 실패의 방법이 차이가 난다. 즉, 대기업은 큰 실패를 할 수 있는 여력이 있지만, 중소기업은 작은 실패도 심각한 상황
이 될 수 있다는 점이다. 그렇다고 실패하지 않을 일만 할 수 있는 것은 아니다. 중소기업이 취할 수 있는 현명한 실패는,
빠른(혹은, 이른) 실패를 결험하는 것이다. 짧은 반복주기를 거치면서 실패를 경험한다면, 다음 주기에 실패를 만회할 수
있다. 긴 반복주기에서 실패를 경험하게 되면, 그 동안 투자되었던 노력이 물거픔이 되지만, 짧고 빠른 실패는 복구 비용도
크지 않다. 현실이 이와같다면, 계획은 빠른 실패를 할 수 있는 방법을 실행하는데 초점을 맞춰야 한다. 실패는 배움의 과
정에서 항상 발생하는 일이며, 경험의 축적이 생기면 성공으로 가는 방법을 찾아내게 된다. 실패를 받아들이는 태도의 변
화가 없다면, 실패는 누군가의 탓만하는 것으로 끝나고 만다. 개발자의 실패가 허락되지 않는 조직은 경쟁력 없는 누구나
다 만들 수 있는 제품만 개발할 뿐이다. 그런 제품을 가지고 시장에 나서는 행위는 자살밖에 되지 않는다. 많이 팔아봐야
남는 것이 없는 장사일 뿐이다.
실패가 인정되지 않으면 도전도 하지 않는다. 당연한 말이다. 누가 과제 실패에 인생을 걸 수 있겠는가? 차라리 도전하지
않고 주는 월급만 챙길 수 있는 안정적인 일을 찾을 것이 분명하다. 공무원이 제일 안정적이라고 생각한다면, 그쪽으로 사
람들이 몰릴 수 밖에 없다. 실패했을 때 일어설 수 있도록 만들어야 도전이 가능하다. 한번에 실패로 모든 것이 돌이킬 수
없는 상황에 처한다면, 누구도 쉽게 나서지 못한다. 실패는 과정이며 성공은 결과다. 따라서, 과정 없이는 성공이라는 결과
도 없다. 성공을 원하면서 실패를 회피 하려는 것도 올바른 태도는 아니다. 물론, 그렇다고 실패를 꼭 하라는 말은 아니다.
과정에서 발생하는 실패를 “학습”으로 만들기 위해서는 계획된 실패가 필요하다. 축구의 신이라고 해서 모든 경기에 골을
넣는 것은 아니며, 골을 넣지 못했다고 다른 경기에 출장하지 않는 것도 아니다. 필요한 것은 과감하게 도전할 수 있도록
용기를 주는 것이지, 이겨내지 못하는 좌절을 안기는 것이 아니다. 개발은 상시 실패를 경험할 수 밖에 없다. 누구도 해보
지 않은 것을 만드는 것은(혹은, 남들은 해봤지만 우리는 경험이 없는 것을 만드는 것) 실패조차 경험으로 받아들일 수 있
는 자세가 필요하다. 책임을 회피하고자 하는 사람들은 실패하지 않을 일만 찾아다닌다. 안정 위주의 성장 전략을 짜고 작
은 이익을 추구하며 절대 새로운 일은 시작하지 않는다. 이런 상황에서 만들어지는 소프트웨어는 당연히 지난 성공을 다시
재탕 삼탕하는 것 밖에 되지 않는다. 소프트웨어 개발은(특히, 잘 모르는 것을 만들 때는) 빨리 무엇 인가를 만들어 사용자
의 피드백을 얻는 것이 중요하다. 실패하더라도 그것이 경험으로 남기 위해서는 피드백을 얻는데 주저할 필요가 없는 것이
1 · [ 프로페셔널 프로그래머 ]
다. 계획은 그런 경험을 축적하는 과정에서 더 정교하게 바뀔 것이고, 성공하기 위한 로드맵은 지속적으로 업데이트 될 것
이다.
우리는 실패를 인정하는 것을 두려워한다. 실패 자체가 자신의 오점으로 남고, 나중에도 성장의 걸림돌로 작용할 가능성이
있기 때문이다. 자신의 실수를 겸허하게 받아들이지 않는 이유도 동일하다. 일단은 살아남아야 다음을 기약할 수 있기 때
문이다. 또한, 본능적으로 위협이 있다고 판단될 경우 방어적인 태도를 취할 수 밖에 없다. 외부의 위협이란 결국 책임 추
궁이나 비난이 될 수 있으며, 그것을 모면할 수 있다면 어떤 핑게라도 만들어낼 수 있을 것이다. 개발자들이 만든 실수로
인해서 큰 비용이 들었다고 하더라도, 결국 실패 비용은 어쩔 수 없이 발생한 상황이다. 그것을 수습하는 것이 먼저다. 만
약, 그 책임을 개발자에게 묻는다면 실패 비용을 고스란히 개발자가 떠 안게 될 것이고, 당연히 과제는 투자한 비용만 남기
고 없어지게 될 것이다. 사람이 없으면 과제도 없는 것이다. 이미 마음이 떠난 과제를 책임지고 완수할 사람도 없으며, 만
약에라도 발생할 수 있는 실패에 대해서 책임지고 싶은 생각도 없을 것이다. 이런 상황을 개선할 수 있는 방법은 회사가 개
발자의 실패에 대해서 너그러움을 가지는 것 밖에 없다. 100% 만족을 원한다면 99%도 불만족 상태 겠지만, 80%만으
로도 충분하다면 이미 넘칠 정도로 만족한 상태가 된다. 회사는 개발자들이 실패했을 때, 어떤 상황이 만족스러운 상태인
지 확인시켜 주어야 한다. 원하는 기능이나 성능의 100%구현이 목표가 아니라, 얼마나 만족스러운지 긍정적으로 반응해
주어야 한다. 실패에서 배우지 못하는 것은 안되는 방법을 한가지 더 찾았다는 뜻이 아니라, 지금까지의 노력이 무의미 하
다는 것만 강조할 뿐이다. 실패의 복구는 책임 추궁이 아니라, 더 나은 결과를 만들기 위한 노력을 결집하는 것이다.
2 · [ 프로페셔널 프로그래머 ]
책임은 개발자가 지는 것이 아니라 계획하는 사람에게 돌아가야 맞다. 조직의 실패는 시스템의 실패이며, 개발자는 개인일
뿐이다. 따라서, 계획에 관련된 사람들이 제대로 일을 수행하지 않아서 시스템의 운영이 미숙 했던 것일 뿐이다. 하지만,
현실은 항상 계획한 사람과 책임지는 사람이 분리되어 있다. 누군가의 명령(혹은, 좋은 의도)으로 계획된 과제가 “일정, 비
용, 기능”을 만족시키지 못한체 실패했다면, “일정이나, 비용, 기능”의 선택에 문제가 있었다는 뜻으로 해석해야 한다. 개
발자의 능력이 부족해서 실패를 해도 마찬가지다. 적절한 자원을 투입하지 않았기 때문이다. 일정을 만족시키지 못하는 대
부분의 과제는 지나치게 “도전적인” 일정이 차지하고 있으며, 비용 계획을 만족하지 못한 과제는 사전에 필요한 자원을 제
대로 파악하지 못했기 때문이다. 모든 과제에서 요구되는 기능은 언제나 100%다 사용 되지 않는다. 따라서, 이 모든 실패
의 원인은 시스템적인 결함으로 발생하는 결과일 뿐이다. 제대로 된 기획을하고 걸맞는 일정 계획을 만들어 적절한 자원을
투입해 우선순위가 높은 기능을 위주로 구현 했다면, 실패가 발생하더라도 빨리 복구할 시스템을 구축 했을 것이다. 그렇
지 않다는 말은 결국 누군가의 실패(혹은, 오만이나 지나친 강압)로 인해서, 결과만 고스란히 개발자들이 뒤집어 쓰고 있
다는 뜻이 된다. 책임은 과제에 이해를 가지고 있는 모든 사람들이 함께 져야하며, 그래야만 시스템의 실패를 복구 할 수
있는 가능성이 생긴다. 책임을 묻는 자리에서 과제에 영향력을 행사한 사람들이 침묵하는 것은 실패를 자신의 책임으로 인
정하지 않고 남의 탓으로 돌리고 싶어하는 방어 본능일 뿐이다. 성숙한 인간이라면 적어도 자신의 미흡 했음을 남에게 전
가하지는 않을 것이다. 스스로 부족함을 알 때, 진정한 개선을 이룰 수 있다.
- 실패는 병가지 상사라고 했던가? 책임 추궁만하는 분위기로는 도전 정신을 발휘하지 못한다.-
3 · [ 프로페셔널 프로그래머 ]
2017/10/12 12:59 http://blog.naver.com/knix008/221115410342
[ 소프트웨어 산업의 본질 - 04 ][ 소프트웨어 산업의 본질 - 04 ]
낙서장(2017)낙서장(2017)
소프트웨어 개발은 비용을 줄이는 전략으로 추진해야 한다. 단순히 빨리 개발하는 것이 아니라, 전체 라이프 사이클을 놓
고 보았을 때, 비용이 적게 들어가는 방향을 선택해야 하는 것이다. 일반적으로 경쟁하고 있는 상황에서 가장 쉽게 선택할
수 있는 것은 “무조건 빨리”가 될 것이다. 하지만, 무조건 빨리에 “무엇을 개발할 것인가”를 명확하게 제한 해야한다. 모든
기능을 무조건 빨리 개발할 것이 아니라, 최소의 필요한 기능을 빠르게 개발하는 것이 필요하다. 즉, 이것이면 충분하다고
생각되는 범위를 정하고, 얼마 정도 기간이 소요되는지 대략적인 목표를 정하는 것이다. 물론, 그렇게 정한 목표라고 해서
반드시 정의된 기간내에 완료된다고 100%보장하지는 않는다. 하지만, 필요하다고 생각되는 모든 기능을 다 구현하는데
필요한 일정 계획을 세우는 것보다는 정확도가 높을 것이다. 따라서, “반드시 가져야할 기능(Must have), 가지면 좋은 기
능(Good to have)”을 잘 정의해야 한다. 비용을 줄이는 전략을 세우기 위해서 입력으로 사용되기 때문이다. 계획을 세웠
다고 끝나는 것이 아니다. 계획을 실행할 때도 마찬가지로 비용을 생각해야 한다.
소프트웨어는 구현하는데 필요한 노력보다 “유지보수”가 비용의 대부분을 차지한다(60%이상). 따라서, 유지보수 노력을
줄이는 구현이 필요하다는 말이 된다. 이를 위해서는 당연히 “모듈화와 계층화”를 따르는 것이 구현 전략이 될 것이다. 모
든 것을 한꺼번에 구현하려고 노력 해서도 안되지만, 그렇다고 아무런 원칙 없이 구현하는 것도 위험하다. 비용이란 결국
무엇을 하는데 얼마나 노력이 드는지를 결정하는 것이다. 초반에 비용을 줄이는 전략의 채택이 만들어진 결과물의 “유지보
수 노력”에 지대한 영향을 주기에, 항상 무엇이 최선인지(무엇이 최대로 비용을 줄이는지) 확인하면서 나아가야 한다. 비
용을 줄이기 위해서는 문제를 빨리 발견할 수 있는 방법을 사용해야 한다. 문제를 나중에 발견하면 비용도 더 들기 마련이
다. 예를 들어, 자동차를 만든다고 할 때(대략 20,000개의 부품으로 조립한다고 하니 충분한 복잡도를 가질 것으로 본다),
조립하는 과정에서 불량을 발견하는 것이 조립이 완료된 후에 불량을 발견하는 것보다 비용이 싸다. 물론, 문제를 찾아내
고 해결하는 동안에 생산이 지연 되기는 하겠지만, 불량품을 생산하는 것은 이익이 아니라 비용만 늘릴 뿐이다.
4 · [ 프로페셔널 프로그래머 ]
비용은 낭비이며, 낭비는 추가적인 시간을 요구한다. 과제가 지연되는 이유를 무엇이라고 보는가? 대부분의 경우 버그 발
생과 밀접하게 관련이 있을 것이다. 그렇다면, 만드는 과정에서 버그를 줄이도록 하는 방법을 연구하는 것이 옳다. 소프트
웨어에서 버그를 줄이는 방법은 이미 많이 연구되어 왔다. 요구사항의 누락이나 잘못된 해석, 아키텍처나 설계 문제의 늦
은 발견, 코딩 단계에서 코드 리뷰와 단위/통합 테스트 누락, 요구사항에 대한 테스트 미비 등등 다양한 것들이 버그의 발
생과 관련이 있다. 따라서, 이런 부분들을 어떻게 해결할 수 있을 것인지 미리 계획해야 한다. 당연히 계획을 실행하는 것
역시 중요하다. 하지만, 계획조차 하지 않거나, 그런 활동들을 할 시간을 계획에 집어 넣지않는 것이 더 큰 문제다. 경험이
많은 사람들은 남들이 이야기하는 방법을 믿지 않는다. 그리고, 자신의 경험이 이야기하는 것이 절대적으로 옳다고 믿는
다. 물론, 그 경험이 잘못된 것은 아니다. 하지만, 스스로 제대로 경험하지 못한 부분까지 생각자체를 거부하는 것은 옳지
않다. 마치 오래동안 인정되어온 방법들이 교과서나 있는 것이고, 학교때 숙제하는 정도에서만 유용한 것으로 생각하는 것
은 잘못이다. 안다고 이야기는 하지만, 실행하지 못하는 지식은 아는 것이 아니라 추측하는 것일 뿐이다.
낭비는 가치를 생산하지 않는 일을 하는 것이다. 따라서, 코드 리뷰나 정적 분석, 단위 테스트를 이용한 모듈 테스트 자동
화, 통합 테스트 자동화 등은 낭비가 아니다. 오히려 그런 활동들을 활성화 시키는 것이 낭비를 줄이는 길이다. 버그를 사
전에 제거할 수 있으며, 변경에 대한 강건성을 지속적으로 유지할 수 있는 방법을 낭비로 취급해서는 안된다. 오히려, 느린
통합, 자동화 되지 않는 테스트와 배포(수동 테스트 및 그 배포), 무의미한 회의 및 보고서 등이 낭비다. 아키텍처를 만들고
디자인 하는 것은 우리가 만들고 있는 소프트웨어가 그만큼 복잡하기 때문이다. 개집을 만드는 사람이 설계도를 필요로 하
지 않을 뿐, 높은 빌딩을 짓기 위해서는 상세한 도면이 필요한 것이 당연한 이치다. 시간이 부족해서 어쩔 수 없다고 이야
기하는 것 자체가 낭비를 부채질하는 것이다. 마치, 문제를 많이 만들어서 나중에 그것을 고치겠다는 것과 다름없기 때문
5 · [ 프로페셔널 프로그래머 ]
이다. 나중에 문제를 고치는 시간을 줄이기 위해서라도 앞 단계에서 낭비를 줄여야 한다. 소프트웨어 개발은 비용을 줄이
기 위해서 투자를 해야하지만, 투자하는 것이 아까워 낭비를 하겠다는 말이 된다. 그리고, 그 낭비는 투자비 보다 더 비쌀
것이 분명하다. 지속적으로 개량해 나가는데 필요한 비용이 끝없이 추가될 것이기 때문이다. 당연히 유지보수 비용도 덩달
아 커질 것이 분명하다.
- 소프트웨어 개발의 지름길은 막대한 비용을 지불하도록 요구한다. 생산성을 획기적으로 높이는 도구는 없다.-
6 · [ 프로페셔널 프로그래머 ]
2017/10/13 08:33 http://blog.naver.com/knix008/221116006636
[ 소프트웨어 산업의 본질 - 05 ][ 소프트웨어 산업의 본질 - 05 ]
낙서장(2017)낙서장(2017)
소프트웨어 개발은 기술이 집약된 산업이다. 사람을 많이 투입하는 것이 일정을 단축할 수 있다고 믿는다면, 만드는 품질
보다 만들어내는 양을 중요하게 생각한다는 뜻이된다. 하지만, 코딩양이 많다고해서 그것이 고객이 요구하는 것을 만족 시
킨다고 할 수 없으며, 품질이 높다고도 이야기 할 수 없다. 전통적인 관점에서 생산성은 투입된 자원에 비례해서 생산량이
늘지만, 소프트웨어는 생산된 자원(사람)이 많아지면 오히려 생산성이 줄어드는 효과가 생긴다. 하나의 제품에 대한 생산
은 라인을 늘리고 숙련된 사람을 늘리면 되지만, 하나의 소프트웨어 제품을 만들기 위해서 여러 생산 라인을 만들 수는 없
다. 가능한 경우는 구현할 내용을 분리해서 모듈화 시키는 방법이지만, 이를 위해서는 먼저 역할과 책임을 나누는 활동이
선행되어야 한다. 또한, 전체 구조를 정의한 후에 각각의 세부 사항들을 나누어진 역할과 책임하에 구현되어야 한다. 구현
과정에서 다양한 협업이 발생하며, 어떤 한 부분이 빠르게 개발된다고 해서 전체 시스템의 개발 생산성이 그것에 맞춰지는
것도 아니다. 우수한 팀과 그렇지 못한 팀 간의 생산성도 크게 차이가 나며, 우수한 인력과 그렇지 못한 인력의 생산성도
마찬가지다. 어떤 자원(사람은 자원이 아니지만)을 사용하느냐에 따라 과제의 품질과 개발의 속도가 크게 달라지기에, 기
술이 탁월한 인력을 꾸준히 유지할 수 있는 방법을 찾는 것이 소프트웨어 개발에서 경쟁력을 가지는 방법이다. 그렇지 못
한 조직은 지속적인 저 품질 비용의 증가로 인해 시장에서 얻을 수 있는 이익이 줄어들 수 밖에 없다.
소프트웨어는 결국 사람이 만든다. 사람이 늘어나면 대화해야할 대상이 늘어나게 되며, 소통 오버헤드 및 사람 사이의 동
기화 비용도 커진다. “책임의 분산”도 문제가 될 수 있다. 즉, 모두의 책임이 되면 누군가의 책임을 묻지 못하게 되며, 그것
으로 인해 개인이 가진 최고의 역량을 발휘하지 않는 상황이 된다. 멀티 코어를 사용할 때, 코어의 수 만큼 성능이 개선되
지 않는다는 사실은 다 알것이다. 제대로 코어를 활용한 코드를 만들지 않는 경우와 코어 간에 동기화된 접근으로 인해 오
버헤다가 코어의 수가 증가함에 따라 급속도로 늘어나기 때문이다. 기계가 이런 상황이라면 사람 사이의 일은 더 크게 숫
자에 민감할 수 밖에 없다. 한 사람 한 사람의 역량이 100이라고 했을 때(물론, 역량은 측정하기도 힘들고 같을수도 없지
만), 그 사람들의 역량을 다 더한 후 사람의 수로 나누면 100이 되지 않는 것이 “책임의 분산” 때문이다. 대화에 대한 오버
헤드와 책임의 분산으로 인해 발생하는 비용은 개발 시간의 상당 부분을 차지하게 되며, 미리 대비하고 잘 설계된 역할과
책임의 분산이 없다면 오히려 개발 기간은 인력의 수에 비례해서 조금씩 늘어나게 된다. 심지어 개발 기간의 중간에 투입
된 인력이 있다면, 기존의 결정과 코드 및 문서들을 읽기 위한 시간도 추가되며(학습을 위한 시간), 기존 인력들이 신규 인
력을 도와주는 시간도 오버헤드에 포함되어야 한다. 따라서, 지연되고 있는 과제에 사람을 더 투입하는 것이 역효과를 내
는 것이다. 물론, 전통적인 관점에서는 사람을 더 투입하면 더 많은 생산량을 만들 수 있다고 보겠지만, 소프트웨어는 복잡
한 지식을 효과적으로 다루는 방법에 대한 것이기 때문에, 사람의 수와 생산성이 비례 관계를 이루지 못하는 것이다.
7 · [ 프로페셔널 프로그래머 ]
사람을 중요하게 생각하지 않는 회사는 경쟁력을 상실한다. 모든 회사는 “인재가 자산”이라는 말을 하지만, 그 말을 지키
는 회사는 드물다. 인재는 자산이지만 오버헤드로 취급하는 것이 일반적이다. 가능한 이익을 크게 하기 위해서는 갑 싼 인
력을 많이 채용해서 빨리 물건을 만들라고 요구하는 것이 일반적이다. 소프트웨어 개발비의 대부분은 사람에 대한 인건비
이기에, 비싼 인력이 놀고 있는 꼴을 결코 좌시하지 않는다. 하지만, 일은 자신이 가진 최대 역량을 100%발휘해야 탁월한
품질을 가지는 것이 아니다. 그리고, 100% 노력이라는 것도 측정할 수 없는 수치다. 사람은 한계를 정하면 그 만큼만 노
력하거나, 혹은 한계 자체가 자신이 생각하는 도달 가능한 목표 수준으로 설정한다. 따라서, 사람이 가지는 내재된 역량을
완전히 발휘하는 것은 불가능한 목표일 수 밖에 없다. 바쁘게 일하는 것이 그 사람의 모든 역량을 뽑아쓰는 것이라고 생각
하는 관리자들은 될 수 있으면 많은 일을 시키려고 애쓴다. 야근과 특근 시간 통계를 내서 관리하는 것이 가장 손쉬운 “노
력을 측정하는 도구”로 생각하고 있으며, 일정 준수만이 모든 과제의 목표로 지정하고 있기 때문이다. 살아남는 것이 목표
인 상황에서는 그럴수도 있을 것이다. 제대로 알지 못하는 것을 측정하려고 애쓰기 보다 눈에 보이는 것만 측정하면 되기
때문이다. 하지만, 그것이 경쟁력을 강화시켜주거나 시장에서 제품의 성공을 보장해주지는 못한다. 결국 지식 집약적인 기
술의 회사가 되지 못하면, 차별화는 없어지고 잡다한 기능의 합집합만 있을 뿐이다. 기능이 많다고 팔리는 제품보다 필요
한 기능의 품질이 우수한 제품이 성공하는 이유가 거기에 있다. 사람이 중요하다면 시간이 아닌 품질을 강조해야 한다. 양
을 강조하면 품질은 낮아질 것이고, 품질을 강조하면 자연스럽게 속도도 빨라지게 될 것이다.
소프트웨어 개발은 품질이 속도를 대변한다. 저품질이 비용을 발생시키며, 재작업이 대부분의 비용이다. 따라서, 재작업이
없는 제품을 만들기 위해서 과정에서 만들어지는 산출물의 품질을 높여야 한다. 품질이 나쁜 상태로 최종 단계에 이르게
되면, 당연히 재작업 양은 늘어나게 된다. 이미 조립된 상태에서 품질 수준을 높이는 일은 “현상만 완화시키는” 단기적인
대책을 만들 뿐이다. 문제는 상황이 조금만 바뀌어도 재발할 것이며, 문제를 다루는 사람의 역량에 따라 비용도 추가될 것
이다. 이런 식의 개발이 지속되면 신제품을 개발하는 속도에도 영향을 주게된다. 대부분의 소프트웨어 개발 회사는 신제품
개발 인력과 기존 제품 지원 인력에 구분을 두지 않고 있다. 따라서, 기존 제품의 문제는 신제품을 개발하면서 같이 처리
해야 하는 상황이다. 문제점이 많은 제품을 지원하기 위해 신제품 개발이 지연되는 현상이 지속해서 발생하게 된다. 고객
8 · [ 프로페셔널 프로그래머 ]
은 점차 약속한 일정에 대해서 의미를 두지 않게되며, 언제든 대체할 수 있는 다른 제품을 찾아 나서게 된다. 이런 상황에
서 유일한 해결책은 사람을 추가하는 것이지만, 값싼 인력은 많지만 제대로 된 인력은 찾아보기 힘든게 소프트웨어 업계의
현실이다. 또한, 제품의 수가 늘어나면 지원해야 할 제품도 많아지게 되며, 비례해서 인력의 수도 같이 늘어나는 빈익빈
현상이 되고만다. 매출이 늘어나더라도 이익이 늘어나지 않는 구조가 되고마는 것이다. 만약, 시장에 탁월한 경쟁자가 나
타난다면, 쉽게 경쟁력을 상실할 우려가 생긴다는 말이다. 품질을 높이는 것이 결국 시장에서 성공하는 길임과 동시에 속
도면에서도 경쟁력을 가지는 것이다. 소프트웨어 개발은 고품질을 만들기 위해서 속도를 희생해야 하는 것이 아니라, 품질
을 높이는 것이 속도를 보장해주는 분야라는 것을 이해해야 할 것이다.
- 소프트웨어 개발은 사람에 의존한다. 하지만, 그것을 이겨내는 것이 상향 평준화를 이루는 길이다.-
9 · [ 프로페셔널 프로그래머 ]
2017/10/13 13:06 http://blog.naver.com/knix008/221116186429
[ 소프트웨어 산업의 본질 - 06 ][ 소프트웨어 산업의 본질 - 06 ]
낙서장(2017)낙서장(2017)
소프트웨어 개발은 고품질이 저비용이다. 여기서 말하는 비용이란 결국 일정의 지연을 의미한다. 즉, 저품질로 인해서 발
생하는 비용의 대부분은 과제의 지연이나 버그 수정 혹은 기능 추가의 지연을 의미한다. 일정이 지연되는 동안 사람에 대
한 인건비는 지출되어야 하며, 만회하기 위해서 추가되는 인력이나 근무시간의 연장 역시 비용의 추가로 이어지기 때문이
다. 교통비 몇 푼이면 충분하다고 생각할지도 모르지만, 근무시간의 연장은 결과적으로 근무 시간중에 만들어지는 제품의
품질이나 생산성에 영향을 주게된다. 결과적으로 절대 성공적으로 제품의 품질 수준을 정해진 일정 내에(혹은, 요구된 일
정에 따라) 만족시킬 수 없는 상태가 지속될 뿐이다. 소프트웨어 개발에서 말하는 고품질은 완벽하게 버그가 없다는 것을
증명하는 것이 아니라, 알려진 버그가 없다는 것을 의미한다. 따라서, 최대한 검증력을 확보해 가면서 검증 주기를 자주 가
져야하며, 검증의 범위도 높여야 한다는 의미다. 100% 완벽한 소프트웨어가 없더라도 대부분의 버그는 사전에 제거할
수 있으며, 그 비용도 비싸지 않다는 것을 이해해야 한다. 예를 들어, 자동화된 테스트를 만들 수 있는 시간이 없다고해서
수동 테스트만 고집한다면, 사람의 인건비에 대한 낭비만 초래할 뿐이다. 테스트 자체를 쉽게 하기 위한 방법도 설계와 구
현에서 필요한 요구사항 이기에, 코딩 업무에 “해야할 일”로 취급 되어야 한다. 과정의 품질을 높이면 최종 품질 수준도 높
아지며, 더 적은 노력으로 더 많은 일을 할 수 있는 상황이 될 것이다.
소프트웨어는 한번 만들 때 제대로 만들어야 한다. 나중에 고치면 된다는 생각은 버리는 것이 좋다. 그렇다고 완벽한 소프
트웨어를 만들겠다고 지나치게 기준을 높여도 안된다. 적당한 수준의 비용은 감수를 할 수 있지만, 그 비용이 지나치게 높
아지는 것을 경계해야 한다는 뜻이다. 코드가 많아지면 버그는 자연스럽게 늘어나기 마련이고, 버그는 코드의 복잡도와 밀
접한 관련을 가진다. 따라서, 복잡도가 지나치게 높아지는 것을 관리할 수 있는 방법을 체계적으로 실행해야 한다. 복잡도
는 논리적인 것이 있지만, 물리적인 것이 관리하기 쉽다. 물리적인 의존 관계를 모아서 관리해야 하며 될 수 있으면 낮은
수준으로 유지해야 한다. 논리적인 분기도 가능한 줄이는 것이 좋다. 내구 구조에 대한 의존은 낮추고 인터페이스에 의존
하게 만들어야 한다. 이해하는데 어려운 부분을 개선하는 것도 복잡도를 낮추는 것이다. 각종 소스 코드에 등장하는 객체
(Object : 변수, 함수, 상수, 파일, 디렉토리 등등)들은 적절한 이름을 가질 필요가 있는 것이다. 이 모든 것이 사람의 이해
를 돕는 방법을 구현되어야 한다. 이미 구현된 코드를 개선하는 것은 어렵기 때문에, 코드가 만들어지는 순간부터 개선 작
업도 함께 시작해야 한다. 모든 코드는 생성되는 순간부터 유지보수에 들어간다고 보는 것이 옳다. 통합과 테스트는 자주
할수록 비용이 적게 든다는 것도 알아야 한다. 고품질을 유지하기 위해서는 일정 비용이 들어가는 것을 감수할 수 밖에 없
다. 지나치게 들어가는 비용은 경계해야 하지만, 적절한 투자는 항상 미래에 위해서 필요한 부분이다.
10 · [ 프로페셔널 프로그래머 ]
고품질로 만들어진 소프트웨어는 유지보수 비용이 낮을 수 밖에 없다. 새로운 기능을 추가하거나 기존 버그를 수정하는데
필요한 시간도 단축된다. 당장 비용을 줄이고 싶다고 하더라도 가치를 만들어 낼 수 있는 투자는 해야하는 것이다. 간혹,
비용과 투자를 혼동하는 사람들이 있으며, 투자가 필요 없다고 믿는 사람들도 있다. 그들이 보는 시각은 항상 "바쁜일과 현
재"만 초점을 두고 있기에, 미래에 어떤 일이 생길지는 예상하지 못한다. 투자가 없으면 개선도 없다. 그리고, 그렇게 만들
어진 코드는 지속적인 유지보수 비용 발생의 원인이 된다. 저품질로 인해서 발생하는 비용은 문제를 찾아내는 단계가 늦어
질수록 더 비싸진다. 고객에게 배포된 이후에 발견되는 버그는 수정을 위해서 막대한 비용을 지불해야 할수도 있다. 개발
팀의 목표는 과제를 완료하는 것이 아니라, 제품이 시장에서 오래동안 살아남는 것 이어야 한다. 소프트웨어는 하드웨어와
달리 지속적인 변경을 요구하며, 그 변경을 통해서 꾸준히 생명력을 유지한다. 따라서, 변경을 쉽게 받아들일 수 있는 구조
를 만들지 않는다면, 변경 자체가 추가적인 비용으로 지출 요인이 되는 것이다. 고품질은 그런 비용을 줄일 수 있는 방법이
며, 빨리 만드는 것으로는 고품질을 달성하지 못한다. 빨리 만들면서 고품질을 달성하기 위해서는 반드시 "자동화된 테스
트"를 가져야만 한다. 자주 통합하고 테스트 하기 위해서는, 그 때마다 추가되는 기능과 모듈 들에 대한 검증력을 높여야
하기 때문이다. 자동화된 테스트를 만들기 위해서 필요한 것은 상품화에 들어가는 코드만이 전부가 아니다. 물론, 이런 부
분들을 오버헤드라고 생각한다면, 다른 고품질을 달성하기 위한 활동들은 사람에 의한 노력에 전적으로 의존하게 된다.
모든 투자가 가치를 만드는 것은 아니다. 하지만, 투자해야 할 시기를 놓치면 다시하기 힘든 것이 있다. 소프트웨어 개발은
초기부터 일정 부분 투자해야 할 항목을 정하고 시작해야 한다. 100이라는 노력을 투자할 수 있다면, 적어도 30이상의
노력은 산출물의 품질을 높이는데 투자되어야 한다. 모든 노력이 코딩에만 쏠리게 되면, 다른 투자해야할 부분들이 빚으로
남게된다. 빚이 쌓이면 지불능력을 상실하는 때가 오게되며, 그때는 새로 개발하는 것보다 못한 상태가 된다. 과거의 유산
에서 자유롭지 못한 상태가 되면, 앞에서 투자 했어야 할 노력보다 더 많은 노력이 개선에 투자해야 하는 상황이 되고 만
다. 물론, 좋다는 것은 안다고 이야기를 하지만, 아는 것에서 끝나고 마는 것이 현실이다. 투자를 생략한다면 처음에는 빠
른 것 처럼 보일지도 모른다. 하지만, 목표에 다가갈수록 점점더 생산성은 낮아질 것이며, 해결해야 할 문제들은 더 빠르게
늘어난다. 이를 극복하기 위해서 단기 처방전을 사용하는 것이 그 때로서는 최선이지만, 말 그대로 단기적인 대안일 뿐이
다. 개발자들은 개발이 한참 힘든 순간이 되어서야 후회하게 되고, 다음 프로젝트에서는 반드시 개선하겠다고 마음 먹는
11 · [ 프로페셔널 프로그래머 ]
다. 하지만, 그런 기회는 절대 다시 오지 않는다. 그때 못했던 것은 나중에도 하지 못한다. 소프트웨어 개발이란 한번 만들
어진 제품은 계속 유지 보수를 해야하며, 완전히 다른 제품으로 변경하지 않는한 문제는 끊임없이 해결해 주어야 한다. 다
시 말하면, 문제를 해결하느라 새로운 과제를 하더라도 시간이 부족하게 될 것이 분명하기 때문이다. 관리자는 개발자가
절대 노는 꼴을 보지 못하며, 유지보수나 구조 개선 작업, 테스트 자동화 등은 코드를 개발하는 것보다 우선 순위가 낮다고
보는 것이 일반적이다.
- 저품질이 지연의 주된 이유다. 나머지는 관리자의 “도전적인 계획”에서 원인을 찾아야 한다.-
12 · [ 프로페셔널 프로그래머 ]
2017/10/16 08:56 http://blog.naver.com/knix008/221117895666
[ 완벽보다 최선을 선택하라. ][ 완벽보다 최선을 선택하라. ]
낙서장(2017)낙서장(2017)
어느 회사를 가더라도 소위 말하는 “꼴통”은 항상 있다. 높은 역량을 가진 사람들로만 채워진 조직에서 일하더라도, 수준이
낮은 사람은 존재하며 열심히 노력하지 않는 사람들도 항상 있기 마련이다. 사람은 완벽한 존재가 아니며 완벽하려고 노
력은 할 수 있지만 목표에 도달한 사람은 아직 없다. 우리가 할 수 있는 최선이란 것 자체가 정의할 수 있는 성격의 것이 아
니며, 매일 매일 조금씩 더 나아지려고 노력할 뿐이다. 소프트웨어 개발도 마찬가지다. 완벽한 소프트웨어는 존재하지 않
으며, 완벽에 가깝도록 만들려는 의지만 있을 뿐이다. 누군가 100% 무결한 소프트웨어를 만들었다면, 이미 거짓말을 하
고 있다는 것을 쉽게 알 수 있다. 사람이 완벽하지 않은데 만들어진 제품이 완벽할리가 없다. 따라서, 적당한 취약점은 인
정할 필요가 있다. 물론, 그 약한 부분이 유난히 다른 것에 비해서 드러나 보인다면 문제가 될 수 있지만, 그렇지 않다면 어
느정도 감수하고 나아갈 수 밖에 없다. 완벽하려고 더 많은 시간과 노력을 투자하기 보다, 완벽하지는 않지만 쓸만한 소프
트웨어를 만드는 것을 목표로 삼아야 한다. 노력이나 투자 자체가 없다면 문제가 있다고 볼 수 있으며, 30%이상의 노력이
소모되고 있는 것도 경계해야 한다. 자신이 해야할 일을 70%정도 하고 있다면, 한 일을 정리하는데 필요한 노력도 투자
하는 것이 옳다. 100%의 노력이 어느 정도 인지 모른다면, 하루 2시간을 넘지 않는 선에서 기존의 노력에 대한 정리 작업
을 하는 것이 좋을 것이다. 하지만, 직급이 낮거나 혹은 권한이 없는 경우에는 이 정도의 시간을 투자하는 것도 무리가 있
다. 따라서, 이때는 드러나지 않게 개선 활동에 투자하는 시간을 만들어야 한다. 실제로 높으신 분들은 구체적인 일은 잘
모른다. 뭔가 열심히 하고 있는듯이 보이기만 한다면, 특별한 간섭은 피할 수 있을 것이다. 이런 것들이 귀찮다고 생각한다
면, 자신을 위한 투자라고 생각해 볼 수도 있다. 그리고, 그 투자의 결실은 결국 돌아오기 마련이다.
완벽에 가까운 소프트웨어를 만드는 것은 가능하다. 예를 들어, 모든 제어 경로를 실행해 볼 수 있다. 하지만, 그것 자체가
너무 많은 시간과 노력을 필요로 하기에, 적절한 수준에서 제어 경로를 실행해 볼 수 있어야 한다. 작은 단위에서 전체 경
로를 실행하는 것은 가능하지만, 통합된 코드에서 모든 경로를 실행해보는 것은 예외까지 포함하기에 투자 대비 성과가 나
오지 않는다. 해볼 수 있는 방법은 작은 단위의 실행 경로에 대한 검증을 높이는 동시에, 통합된 수준에서는 주요 시나리오
및 예외 상황에 대한 검증을 해보는 것이다. 물론, 이를 위해서 미리 정의된 아키텍처와 디자인을 가지고 있는 것이 유리
하다. 즉, 검증 자체를 편하게 만들기 위한 구조를 미리 통합된 코드 내에 포함하고 있어야 한다. 그렇지 않다면, 자동화된
실행 자체가 어려울 수 있다. 만드는 것보다 검증이 힘들어지는 이유는 초기 투자의 부족을 나중에 복구 하려고 하기 때문
이다. 따라서, 초기에 조금만 신경써서 필요한 요소들을 미리 반영할 수 있다면, 생각보다 쉽게 자동화된 검증을 진행할 수
있다. 예를 들어, 버스(Bus)구조와 같은 것을 통해서 서로 통신하는 시스템의 객체들을 정의했다면, 테스트를 위한 에이
전트(Agent)를 이용해서 각각의 시스템 객체들을 나누어서 검증할 수도 있을 것이다. 물론, 이와 같은 노력이 의미를 가
지기 위해서는 상당 시간의 노력이 필요하다. 팀원들과 리더를 설득하려는 대화도 필요할 것이다. 거부감을 가지는 팀원들
도 있을 것이고, 과제 일정 지연에 대한 우려를 표하는 과제 담당자도 있을 것이다. 그런 모든 것들을 다 극복하는 것이 어
려울 수 있기에, 가능한 같이 할 수 있는 사람을 먼저 만드는 일이 필요하다. 이도 저도 안된다면, 혼자서라도 자신의 코드
13 · [ 프로페셔널 프로그래머 ]
만큼은 자동화된 검증을 할 수 있도록 만들어야 할 수도 있다. 어쨌든 그런 경험을 통해서 남보다 한 발짝 더 나아갈 수 있
다는 것은 분명하다.
대체로 경험이 많은 사람일수록 새로운 것을 받아들이는 속도나 늦다. 이것은 어쩔 수 없는 일이다. 새로운 경험이 기존의
경험과 반대되는 성향이 짙을수록 거부감은 더 커진다. 따라서, 이 떄는 먼저 보여주기를 선택하는 편이 좋을 수도 있다.
보지 않으면 믿지 않는 것이 대부분의 사람들이 가지는 태도다. 특히, 기존 경험이 있는 사람의 경우에는 직접적인 증거를
제시 하더라도 믿지 않을 가능성이 높다. 이유는 단순하다. 자신의 생각과 다르다고 느끼기 때문이다. 생각이 다르면 자신
의 권한이 축소될 위험이 있으며, 지금까지의 경험이 옳지 않다고 판단되는 결과를 만들고 싶지 않을 것이다. 일종의 불안
감이 뒤섞인 인생 경험의 부정을 취하기 때문에, 거부할 수 있는 모든 이유를 가져다 붙일 수도 있다. 이런 상황이라면 굳
이 부딪혀서 해결할 필요가 없다. 시간이 흘러 변화를 시도할 수 있는 때를 기다리며, 개인의 역량을 키우는 것을 차선으로
선택할 수 있다. 물론, 그렇다고 그 시간이 마냥 즐거울 수 만은 없을 것이다. 그렇다고 “아니오”라고 말하는 것도 조직에
서 “왕따”가 될 가능성이 있기에 바람직하지는 않다. 먼저 살아남는 것이 목표이며, 그 후에 자존심을 챙겨야 할 수도 있
다. 이런 저런 것들을 따지고 싶지 않다면, 자신의 의견이 받아들여지는 팀을 찾아보는 것도 좋을 것이다. 모든 일이 경험
보다 중요한 것은 방향이다. 잘못된 방향으로 아무리 많은 지식이나 경험을 쌓아봐야, 잘못된 결과만 반복해서 만들어낼
뿐이다. 경험이 많다는 것은 선택할 수 있는 폭을 줄이는 효과도 가지기 때문에, 주의해서 새로운 것들을 검토해야 한다.
만약, 자신이 잘못된 생각을 가지고 있다고 판단될 때는 겸허히 사실을 받아들이는 자세도 필요하다. 물론, 가장 힘든 일이
그런 것을 인정하는 것이지만, 그래도 더 잘못되기 전에 바로 잡는 것이 조금이라도 좋은 결과를 만들어 낼 수 있다. “아니
다”라고 생각될 때는 미련을 두지 말아야 하며, 무엇이 올바른 것인지 알기 위해서 일단은 모든 선입견을 내려놓아야 할 것
이다.
혼자서 일을 할 때도 기준은 정해야 한다. 이때 위안으로 생각해 볼 수 있을 정도의 수준을 만족시키기 위해서는 다음과 같
은 것들을 잣대로 삼아야 할 것이다. 하드웨어 성능으로 도달할 수 있는 목표의 80%이상, 독립적으로 실행될 수 있는 부
분이 최대 길이를 100라인 수준으로 정하기, 객체 지향 언어를 사용할 경우 클래스의 크기를 1,000라인 이하로 유지하
기, 단위 테스트 커버리지를 함수에 대해서 95%, 라인에 대해서 85%, 분기에 대해서 75%이상 가져가기, 복제된 코드
14 · [ 프로페셔널 프로그래머 ]
의 비율은 1%미만으로 하기, 함수의 파라미터 수가 5개 이상인 비율을 1%미만으로 만들기, 조건문의 중첩 수준이 3단
계 이상인 코드를 5%이하로 유지하기 등등, 다양한 100%가 아닌 것들을 만들어서 적용하는 것이다. 기준이 없으면 일
하는 것은 힘들다. 성과를 높이기 위해서는 측정해야 하며, 그것을 기준으로 얼마나 더 나아갈지 결정해야 하기 때문이다.
단순히 “잘, 많이, 더, 열심히, 꾸준히, 성과”아 같은 단어를 사용하는 것으로는 객관적인 잣대를 만들 수 없다. 대부분의 목
표가 형용사나 부사같은 말의 연속이라면, 결과는 이미 정해진 것이나 다름 없다. 즉, 할 수 있는 시간적인 여유가 있을 때
해보겠다는 말이 된다. 당연히 시간이 없으면 대충 마무리 할 것이 분명하다. 이런 식의 일이 반복되는 이유는 “기준”을 명
확히 제시하지 않기 때문이다. 개인이 어떤 일을 혼자서 하더라도 피드백(Feedback)을 적절히 얻어야 동기유발이 될 수
있다. 목표가 되는 기준을 만들었다면, 무슨 일이 있더라도 반드시 하겠다는 의지가 있어야 한다. 의지는 가지고만 있어선
안되고, 실행에 투입되어야 한다. 따라서, 하루 일과의 일부를 반드시 그 일을 하는데 집중할 필요가 있다. 그것이 반복되
면 결국 의지 자체가 노력과 자동으로 연결되며, 노력 자체가 습관화 될 것이다. 변화는 작은 것이라도 꾸준히 실천하지 않
으면 결과로 드러나지 않는다. 혼자만이라고 느낀다면 그 결과의 변화를 통해서 옆의 동료들과 대화를 나눌 수 있는 근거
자료를 만들 수 있을 것이다. 비록 완벽하지는 않을지라도 그 노력의 결과 만큼은 부정하지 못할 것이다.
- 완벽하려고 노력은 하되, 완벽 자체에 집착하지 말라.-
15 · [ 프로페셔널 프로그래머 ]
2017/10/17 11:35 http://blog.naver.com/knix008/221118823020
[ 설계 품질이 결과를 좌우한다. ][ 설계 품질이 결과를 좌우한다. ]
낙서장(2017)낙서장(2017)
소프트웨어 아키텍처는 시스템을 구성하는 요소와 그들간의 관계 및 구성 요소 및 관계의 속성을 정의한다. 따라서, 요구
사항을 만족시키기 위한 구성 요소 및 관계의 정의를 포함하고 있어야 아키텍처라고 부를 수 있다. 대부분의 개발자들이
만드는 설계는 요구사항의 일부분에 한정해서 관련이 있으며, 기술적인 부분에 지나치게 치중하는 경향이 있다. 이는 아키
텍처 설계의 대부분의 과정이 고객과 동떨어져서 진행되며, 고객이 이해하는 언어로 작성되지 않기 때문이다. 이런 부분들
을 극복하기 위해서는 고객의 설명을 자세히 들어야하며, 될 수 있으면 고객의 언어를 이용해서 비지니스의 핵심이 되는
부분에 대한 설계를 진행해야만 한다. 개념의 차이가 발생하는 이유는 다른 언어의 사용과 같은 언어를 사용하더라도 상황
(Context)에 따른 의미 차이를 이해하지 못하기 때문이다. 따라서, 이런 부분을 해결하지 않는다면, 아키텍처 설계는 고객
의 진정한 요구(Needs)를 만족시키지 못할 가능성이 높다. 고객에는 외부의 사용자만 포함하는 것도 아니며, 가장 가까운
관계는 동료 개발자도 될 수 있다. 또한, 과제에 이해 관계를 가지고 있는 모든 사람을 대상으로 해야하는 것이 옳다. 이런
사람들의 요구가 서로 상충하는 부분이 있기에, 대화와 타협을 통해서 적절한 트레이드 오프(Trade-Off)를 취해야 하는
것은 당연한 일이다. 또한, 요구사항에는 성능만 포함되는 것이 아니라, 이식성, 테스트 용이성, 사용성, 보안성, 변경 용이
성 등과 같은 추가적인 것들도 같은 중요도로 다루어야 한다. 대체로 대부분의 개발자는 “성능”에 몰입하는 경향이 있지
만, 성능을 갖추기 위해서 희생되는 다양한 “비기능 요구사항”들은 시스템을 운영 유지 보수하는데 필요한 비용 발생의 원
인이 되기도 한다. 따라서, 아키텍처 설계는 이런 부분들도 고려해서 적절한 결정을 내려야 하며, 결정에 대한 근거를 명확
히 하는 근거가 될 수 있다. 단순히 설계만 하고 구현이 설계를 따라가지 않는다면, 이것 역시 대화의 단절과 요구사항 구
현의 부정확성만 키우게 될 것이다. 문서화는 복잡하고 어려운 일 일수록 더 필요하게 되며, 재활용이 많거나 단순한 과제
라면 간단한 설계만으로도 충분하다. 적절한 선택에 대한 가이드라인은 없지만, 그렇다고 아키텍처의 품질을 평가하지 못
할 이유도 없다. 설계의 품질이 결국 산출물의 품질과 연결되기 때문에, 검토 및 검증은 설계에 대해서도 유효하다는 것이
다.
설계가 복잡하면 구현도 복잡해 지고, 당연히 버그도 많이 발생한다. 실수를 할 가능성이 높다는 뜻이다. 처음부터 복잡한
것은 없지만 간단한 생각이라고 하더라도 추가되고 변경되면 복잡한 일이 되고 만다. 사실 복잡한 문제를 복잡하게 해결하
려고 노력하는 것은 어리석은 생각이다. 처음부터 모든 상황을 고려해서 만드는 것은 불가능한 일이며, 가능한 간단한 해
결책을 먼저 생각한 후에 조금씩 일반적인 상황에 맞춰나가야 한다. 물론, 일을 통해서 얻게되는 지식이 늘어나면, 특별한
상황에서 어떻게 처리해야 될지 결정해야 하는 부분들이 있다. 하지만, 일단은 가장 간단한 해결책 부터 고민하는 것이 일
의 시작이다. 설계를 위해서는 시스템을 구성하는 요소들을 판별해내야하며, 이는 대부분 명사의 형태로 존재하는 것들이
다. 모든 명사가 해당되는 것이 아니라, 핵심에 해당하는 부분부터 골라내는 것이 필요하다. 그외의 것들은 나중에 생각하
도록 한다. 이때 조심해야 할 것은 미리 구현을 생각해서 용어를 복잡하게 만드는 것이다. 단순히 하나의 시나리오에 기반
해서 그것에만 집중하는 것이 일을 간략하게 만드는 방법이다. 모든 것을 고려해서 좋은 것을 만들기는 어렵지만, 하나의
16 · [ 프로페셔널 프로그래머 ]
상황과 사용 시나리오만을 고려해서 설계하는 것은 어렵지 않을 것이다. 문제는 그 하나의 시나리오가 무엇이냐에 달려있
다. 핵심이 되는 시나리오를 선택하기 위해서는 사용자가 가장 많이 사용하는 기능에 초점을 맞출 필요가 있으며, 시간의
흐름에 따라 어떤 결정과 동작(혹은 이벤트)이 발생하는지 보도록 한다. 그것에 맞춰 고객이 원하는 기능을 만족시키기 위
해서 비지니스 로직에 필요한 구성요소를 판별하면 될 것이다. 기술적인 부분은 세부 설계나 시스템의 인프라 측면을 고려
할 때 하도록 하고, 일단은 고객이 사용하는 언어와 업무 프로세스(혹은, 동작 방식)를 이해하고, 필요한 구성요소들 간의
관계를 정의하는 것을 선행해야 할 것이다. 대표 시나리오 몇 개만 잘 구성할 수 있다면, 나머지 추가되는 시나리오는 연결
고리의 형태로 수평적인 확장을 통해서, 혹은 하위 시나리오의 형태로 설계해 나갈 수 있을 것이다.
설계 품질을 높이기 위해서는 요구사항의 수집과 분석이 선행되어야 한다. 어떤 일을 해야하는지 모르는 상황에서 내리는
결정은 오류가 있을 수 밖에 없다. 결정할 수 없는 것들은 결정을 미루는 것이 최선일 수 있다. 혹은, 알고 있는 부분에 한
정해서 결정하는 것이 좋다. 나중에 더 많은 정보를 얻게 된다면 그 떄 결정하는 것이 효과적일 것이다. 일단은 아는 내용
부터 명확히 결정해 나가는 방식을 취해야 할 것이다. 요구사항을 수집하는 과정이 없거나, 혹은 요구사항이 늦게 주어지
는 경우도 있다. 즉, 아키텍처를 설계하는 과정에서 요구사항의 수집이 제대로 되지 않을 가능성이 크며, 고객의 변심이나
추가적인 기능으로 인해서 아키텍처 자체를 변경해야 할 경우도 생긴다. 이를 위해서는 가능한 자세한 설계나 구현은 나중
으로 남겨두어야 할 것이다. 물론, 이것 조차도 불가능한 경우도 있다. 예정된 날짜에 결과물 제출을 요구받을 때이다. 이
떄는 설계된 부분에 대해서 명시적으로 결정되지 않았다고 기록을 남겨야 할 것이다. 부족한 설계의 결과물이 구현으로 연
결되지 않도록 만들기 위해서는 반드시 설계를 평가해야 한다. 따라서, 아직 정의되지 않은 기능이나 비기능 요구사항들에
대해서 미리 구현하는 것은 변경을 각오해야 할 것이다. 사실 이런 부분도 개발에서는 어쩔 수 없는 부분으로 받아들이는
경우가 많다. 과제 일정이 한정된 경우에는 어떤 식으로든 구현 단계로 진행할 수 밖에 없는 상황이 발생하는 것이다. 하지
만, 구현에서 변경이 가능하도록 만들기 위해서는 설계에서 불변인 부분과 그렇지 않은 부분을 명확하게 구분해 주어야 한
다. 그렇지 않다면 변경은 제어할 수 없는 수준에서 발생하게 되며, 결과적으로 과제 지연이 어쩔 수 없이 발생하기 때문이
17 · [ 프로페셔널 프로그래머 ]
다. 요구사항을 수집하는 다양한 방법들이 있지만, 실제로 고객(실 사용자)을 만나서 이야기하는 경우는 드물다. 가능하면
고객이 참여하는 것이 좋지만, 참여했을 때도 고객의 언어를 개발자가 이해하지 못하거나, 혹은 개발자의 언어를 고객이
이해하지 못하는 상황이 생긴다. 따라서, 요구사항 수집 활동은 고객의 언어를 사용하는 것을 우선해야 할 것이다. 분석도
마찬가지로 가능한 고객의 언어와 가깝게 하거나, 혹은 언어 사용에 대한 용어집을 만들어두는 것이 좋을 것이다. 이떄도
마찬가지로 구현에 필요한 언어는 상세 설계로 미루는 것이 좋을 것이다.
설계는 경험과 지식의 산물이지만, 지속적인 학습과 개선으로 수준을 높일 수 있다. 설계는 뛰어난 몇 사람에 의해서 주도
되는 활동이지만, 그렇다고 그 몇 사람에게만 한정하는 것은 좋지않다. 구현을 할 사람들이 이해하지 못하는 설계란 읽혀
지지 않는 문서와 다름없다. 그냥 한번 만들고 다시 뒤돌아 볼 일이 없기 떄문이다. 지속적인 학습과 개선이 가능하기 위해
서는 구현과 설계가 완전히 분리된 과정이 되어서는 안된다. 구현도 경험과 지식의 축적이 필요한 부분이며, 그것을 통해
설계가 제대로 되었는지 확인할 수도 있다. 따라서, 경험과 지식이 늘어나면 설계도 그것을 반영하기 위해서 더 정교하게
변화해야 한다. 제대로 알게되는 지식을 반영하는지 보기 위해서는 설계 문서의 갱신 날짜를 보면 된다. 즉, 계획된 산출물
로 등록된 이후에 변경이 없다면, 설계는 이미 “죽은 문서”밖에 되지 않는다는 말이다. 지속적인 개선이란 “살아있는 피드
백 루푸(Feedback Loop)”를 통해서만 가능하며, 변화가 없다는 말은 관리하지 않는 말과 동일하다. 따라서, 잘못된 설계
가 있다고 하더라도 구현에는 반영되었을지 몰라도, 설계에는 반영되지 않았을 가능성이 높다. 상세 설계를 하는 과정도
마찬가지다. 아키텍처 수준에서 설계한 내용이 옳지 못하다고 판단될 때는 그것을 개정할 수 있어야 한다. 상세 설계의 수
준은 아키텍처 설계에서 찾아내는 “구성요소와 관계” 및 “속성”의 세부 사항들을 정의하는 것이다. 따라서, 구체적인 수준
에서 올바르지 못한 결정을 찾아냈다면, 상위 수준의 설계에 대해서 피드백을 주어야 한다. 일을 시작할 때는 모르던 지식
들도 일을 마칠 때가 되면 더 이상 남아있지 않게된다. 즉, 개선할 점이 드러나는 순간은 과제의 완료 시점까지 지속 된다
는 것이다. 심지어 과제가 완료되어 실제 사용에 들어가더라도 이는 마찬가지다. 물론, 그 전까지 최대한 많은 부분을 찾아
내 수정하는 것이 좋다. 하지만, “복잡한” 일의 특성상 직접 사용해 보지 않으면, 그런 부분들을 찾아내기 힘든 경우가 많
다. 따라서, 조금이라도 수정을 줄이기 위해서는 가능한 빨리 사용할 수 있는 형태로 만들어야 한다. 핵심만 설계를 하고
결정되지 않은 것들을 뒤로 미루는 이유도 그것 때문이다. 가능한 완전하게 사용할 수 있는 “핵심”기능을 먼저 소위 말하는
풀 스택(Full Stack)으로 구현해 보는 것이 수정 노력을 최소로 만들어 줄 것이다. 계획에 이런 부분들을 적절히 배치할 수
있다면, 성공할 가능성도 조금씩 커질 것이 분명하다.
- 복잡할수록 실행 전에 어떻게 할 것인지 계획해야 한다.-
18 · [ 프로페셔널 프로그래머 ]
2017/10/18 11:56 http://blog.naver.com/knix008/221119636806
[ 테스트하기 쉬운 코드 ][ 테스트하기 쉬운 코드 ]
낙서장(2017)낙서장(2017)
제품을 만드는 기술의 발전은 “구현”만 있는 것이 아니다. 만든 제품을 테스트 하는 것도 제품을 만드는 것 만큼 중요하다.
실제로 제품을 개발하면 검증을 어떻게 하느냐에 따라, 일정 지연 여부가 결정되기도 한다. 잘 만들기 위해서는 잘 만들 수
있는 방법을 미리 고안해야 하며, 테스트도 마찬가지로 과제 초기부터 고려해서 코드에 반영될 수 있어야 한다. 이미 대부
분의 코드가 만들어진 이후에 테스트를 하는 것은 낭비가 발생할 가능성이 높으며, 제대로 테스트 하기도 힘들어 검증과정
이 길어질 염려도 있다. 소프트웨어 제품을 만드는 대부분의 시간은 검증과 디버깅에 달려있기에, 이를 줄일 수 있는 방법
을 생각하는 것을 과제 개발에서 중요한 “요구사항”으로 간주해야 한다. 그렇지 않다면, 만들었다고 생각하는 순간부터 길
고 지루한 “디버깅” 시간을 가질 것이 분명하기 때문이다. 다른 것들도 마찬가지겠지만, 초기부터 조금씩 테스트를 위한 고
려를 구현에 포함 시킨다면, 투자에 대한 이익은 확실히 보장될 것이다. 사실 테스트 자동화 만큼 “남는 장사”는 없다고 보
는 것이 옳다.
01.01. 시스템의시스템의 상태를상태를 외부에서외부에서 파악할파악할 수수 있는있는 방법을방법을 고려한다.고려한다.
; 외부에서 시스템의 상태를 얻기 위해서는, 시스템에 상태를 모니터링 할 수 있는 에이전트를 만들어야 할 수도 있다. 혹
은, 특정한 저장공간이나 원격 시스템에 시스템의 로그를 저장할 수도 있을 것이다. 구현하는 시스템에 따라 다양한 방법
이 고려될 수 있지만, 시스템의 상태를 실시간으로 알 수 있는 방법을 제공하는 것은 디버깅을 위해서 중요한 고려사항이
다.
02.02. 입력의입력의 종류와종류와 가지수를가지수를 한정한다.한정한다.
; 입력의 종류와 가지수를 한정하는 것은 구현을 돕는 동시에 테스트도 쉽게 만든다. 예를 들어, 함수를 구현할 때 파라미
터의 수를 늘리면 입력으로 주어야 할 가지수가 늘어나게 된다. 당연히 테스트해야 할 케이스도 늘어난다. 또한, 값의 범위
를 제한하지 않으면 어떤 값이 유효한 값인지 알지 못한다. 이떄는 생각할 수 있는 모든 값을 넣어야 제대로 테스트 할 수
있을 것이다.
03.03. 단일단일 출력을출력을 가지도록가지도록 만든다.만든다.
; 단일 출력을 가진다면 실행의 결과를 출력을 통해서 확인하는 방법을 이용할 수 있다. 물론, 내부 데이터의 변경이 동반
되는 경우에는 외부에서 의존성을 삽입하는 방식으로 데이터를 인위적으로 검사할 수 있을 것이다. 예를 들어, 함수와 같
은 것을 검증할 때, 출력을 이용해서 정확히 실행 되었는지 확인할 수 있을 것이다.
04.04. 변경과변경과 질의를질의를 구분한다.구분한다.
19 · [ 프로페셔널 프로그래머 ]
; 변경과 질의를 같이하면 두가지 역할을 하나에 할당하는 것과 같다. 따라서, 둘 다를 검사해야 한다. 이 두가지를 분리한
다면 각각을 나누어서 검증할 수 있을 것이다. 당연히 둘을 분리하는 것은 역할과 책임 범위를 명확히 할 수 있으며, 각각
은 더 짧은 코드로 나누어지게 될 것이다. 의존성도 각각에 나누어서 관리될 수 있을 것이다.
05.05. 외부에외부에 의존하는의존하는 부분을부분을 가능한가능한 줄인다.줄인다.
; 외부에 의존하는 것이 많아지면 테스트를 위해서 만족시켜야 할 조건들이 늘어나게 된다. 따라서, 이런 경우 테스트 자체
보다 선행 조건을 만들어주는 일이 더 커지게 된다. 당연히 테스트 작성의 효율은 낮아질 것이고, 의존성을 해결하기 위해
서 코드를 이해하는 시간은 길어질 것이다. 테스트 케이스 작성 자체가 불가능한 상황이 될 지도 모른다.
06.06. 짧은짧은 코드를코드를 작성한다.작성한다.
; 짧은 코드는 단일 역할만 하는 실행 단위를 기초로 한다. 예를 들어, C언어라면 함수가 최소 실행단위가 되며, 하나의 함
수는 하나의 역할만 수행하는 것이 맞다. 즉, 단일 역할을 실행하는 짧은 코드를 작성해야 하며, 길이가 길어질 경우에는
여러 개의 작은 부분들로 나누어서 작성해야 할 것이다. 물론, 각각의 나누어진 부분들을 하나씩 검사하지 않고도 충분히
검증을 할 수 있다. 하지만, 중요한 부분이라고 생각되는 것들은 따로 검사할 수 있어야 한다.
07.07. 조건문의조건문의 수를수를 가능한가능한 줄인다.줄인다.
20 · [ 프로페셔널 프로그래머 ]
; 조건문의 수가 늘어나면 테스트를 위한 입력 조건을 만드는 가지수도 늘어나게 된다. 또한, 복잡한 조건문일 경우에는 실
행되지 않는 코드가 있을 수도 있다. 물론, 그런 코드를 발견하면 제거하는 것이 기본이지만, 특별한 예외 상황을 처리하기
위해서 그대로 두는 경우가 있다. 하지만, 그런 예외 상황을 만들어내는 것이 힘들어, 테스트 없이 그냥 두게되는 것이 일
반적이다. 조건문의 수는 성능에도 영향을 주기 때문에, 가능한 줄이는 것이 좋다.
08.08. 조건문조건문 자체를자체를 간략하게간략하게 만든다.만든다.
; 조건문 자체도 복잡하지 않아야 한다. 조건문이 복잡해지면 각각의 실행을 위해서 조건을 만들어낼 수 있는 조합 자체가
늘어나게 된다. 이해가 어려운 것은 당연한 결과다. 따라서, 조건문을 될 수 있으면 간단히 유지하려고 노력해야 하고, 이
해하기 어려운 조건문은 따로 분리해서 인라인 함수화 시키는 것도 좋다. 부정보다 긍정적인 조건문을 사용하는 것이 코드
를 읽는 사람이 더 이해하기 쉽도록 도울 것이다.
09.09. 외부에외부에 노출되는노출되는 부분을부분을 가능한가능한 줄인다.줄인다.
; 외부에 노출되는 것이 많으면 많을수록 코드는 스파게티처럼 꼬이는 것이 일반적인 현상이다. 사람은 알고 있는 사실을
이용해서 가능한 직접적인 조작을 시도하는 경향이 있다. 따라서, 정보를 감추는 일은 의존성을 약화시키는 첫 번째 방법
이다. 노출되는 정보다 적으면 테스트를 위한 선행 조건을 만들기도 쉬울 것이다.
10.10. 자원에자원에 대한대한 의존을의존을 외부에서외부에서 삽입할삽입할 수수 있도록있도록 만든다.만든다.
; 자원을 내부에서 생성하면 외부에서 알 방법이 없다. 그리고, 생성된 자원이 하드웨어나 혹은 테스트 하는 환경에 밀접한
관련이 있다면, 그것을 제공할 수 있는 방법도 없다. 예를 들어, 특정 레지스터나 타이머에 대한 의존성이 생긴다면, 테스
트 케이스에서 삽입할 수 있는 방법을 제공해 주어야 한다. 그렇지 않다면, 원활하게 테스트를 실행하기 어려울 가능성이
높으며, 테스트 대상이 되는 코드가 제대로 동작 하는지 확인하기도 어렵게 된다.
제품은 만드는 것보다 항상 어떻게 테스트 할 것인지를 먼저 고려해야 한다. 그러한 고려가 없다면 대부분의 중요한 시간
을 낭비할 가능성이 높다. 물론, 그런 대비에 너무 많은 시간을 사용하는 것도 옳지 않지만, 그렇다고 전혀 투자를 하지 않
는 것도 올바른 선택은 아니다. 적당한 비율을 찾는다면 7:3 정도로 하기 바란다. 특별한 이유가 있는 숫자는 아니며, 일의
효율과 투자의 적정성을 고려해서 코드 개발에 70%, 테스트를 위해서 30%의 노력을 사용하면 된다. 자신이 하고 있는
일에 대해서 검증할 수 있는 방법을 다른 사람에게서 찾는다면 프로패셔널이 아니다. 진정한 전문가라면 자신이 하는 일의
성격이 무엇인지 파악하고 그것에 맞는 방법을 찾아서 익히는 것이 기본 자세다.
- 테스트 하기 쉬운 코드가 설계를 개선한다.-
21 · [ 프로페셔널 프로그래머 ]
2017/10/19 08:39 http://blog.naver.com/knix008/221120293450
[ 여유는 올바른 결정을 만든다. ][ 여유는 올바른 결정을 만든다. ]
낙서장(2017)낙서장(2017)
바쁜 사람은 문제에 대한 다양한 분석이 어렵다. 바둑이나 장기를 둘 때, 옆에서 훈수하는 사람이 더 상황을 잘 파악하는
이유도 그 때문이다. 객관적인 입장이 되지 않으면, 보여야 하는 것들이 제대로 보이지 않게된다. 시속 100km로 달리는
차를 운전할 때는 주위의 사물이 눈에 들어오지만, 200km로 달리는 차를 운전하는 사람은 자신의 바로 앞에 있는 상황만
인지할 수 있을 뿐이다. 물론, 심리적인 것과 시각적인 것이 다르다고 이야기 할 수 있을지도 모르지만, 어쨌든 바쁜면 나
쁜 선택을 하게되는 것은 어쩔 수 없다. 1시간짜리 회의라면 마지막 5분에 대부분 중요한 결정이 나기마련이다. 그 떄 올
바른 선택을 하기 위해서는 최대한 객관적인 입장에서 한발 물러나 생각해야 한다. 문제를 벗어나서 생각하면 해결책이 떠
오르지만, 문제 속으로 들어가면 풀어야 할 문제의 전체적인 모습이 보이지 않게 된다. 시간이 부족해서 급하게 내리는 결
정들의 대부분은 잘못될 가능성이 있기에, 가능하면 급한 결정은 뒤로 미루는 것이 현명하다. 위험하다고 생각되는 순간에
우리가 선택할 수 있는 최선의 것은 “우리 자신을 보호하는 것”밖에 없다. 이것은 문제에 대한 진정한 해결책이 아니라, 문
제를 회피하고 벗어나려는 방법이 될 것이다. 우리 자신을 위험에서 지켜내는 것이 “급한 결정이 할 수 있는 최선의 것”이
다. 개발자들이 시간이 부족할 떄 내리게 되는 대부분의 결정도 마찬가지다. 근본적인 해결책이 아닌 증상의 완화이거나,
미래의 가치를 낮추는 오류를 만들게 된다. 이런 결정들을 내리지 않기 위해서는 미리 마주할 수 있는 위험 상황에 대한
“행동 지침”을 만들고, 그것에 맞게 차분하게 대처하는 것이 현명한 방법이다. 개발자가 가장 자주 마주하는 위협 중에 하
나는 “일정 단축이나 부족”이며, 그런 상황에 대처하기 위한 방법은 “가능한 일을 하지 않는 방법을 생각하는 것”이 될 것이
다. 구현하지 않으면 문제도 발생하지 않는다. 따라서, 일하지 않으면 문제도 없는 것이다. 역설적이지만 일하지 않는 것이
가장 완벽한 처방일 수 있는 것이다. 따라서, 과제 계획에는 반드시 “응급 상황에 대한 대처 방안”을 미리 갖추는 것이 필
요하며, 그것에 맞게 행동하도록 훈련되어 있어야 할 것이다.
규칙은 사람을 편하게 만든다. 생각할 것이 없이 그대로 따르면 되기 때문이다. 물론, 규칙을 만드는 과정은 여러 사람의
참여와 동의가 필요하다. 그냥 무턱대고 만들면 아무도 안지키게 되기 때문이다. 일반적으로 규칙에는 두가지 점이 반영되
어야 한다. 첫 번째는 이미 효과가 있다고 증명된 것들이 포함될 수 있으며, 두 번째는 과제에 적합한 것들이 있을 수 있
다. 둘 간에 우선 순위는 항상 특수한 상황을 가정한 것이 높다. 일반적인 상황에서 적용할 수 있는 것들이 있는 반면에 특
정 과제에만 적용할 수 있는 것들이 있기 때문이다. 하지만, 문제가 되는 것은 두가지 규칙이 서로 상충하는 경우가 있다는
점이다. 예를 들어, 전역 변수를 쓰는 것이 일반적으로 좋지 못하다고 이야기하지만, 특정 과제에서 편의를 위해서(혹은,
성능이나 기타 다른 요인에 의해서), 전역 변수를 한정해서 사용할 수도 있기 때문이다. 상충하는 경우 어떻게 해결할 것인
가를 정하지 않으면 둘 중에 하나는 무시될 것이 분명하다. 따라서, 서로 충돌이 발생하는 경우를 위해서 협의 할 수 있는
창구나 방법을 마련해 두는 것도 필요하다. 대부분의 경우 일반적으로 “적절하다”고 생각되는 것은 사실은 특정 과제에만
적용되지는 않는다. 적용 정도가 차이가 나거나, 혹은 변형되어 사용될 뿐, 전체적으로 그르다고 보는 것은 옳지 않다. 상
충되는 부분이 있다면, 미리 규칙을 이야기 할 떄 정리하는 것이 가장 효과적일 것이다. 규칙을 정할 떄는 상식이나 경험적
22 · [ 프로페셔널 프로그래머 ]
인 부분을 배제할 필요가 있을 수도 있다. 예를 들어, 과거에는 이렇게 해왔다거나 혹은 이렇게 하는 것이 더 좋아보인다와
같은 의견은 엉뚱한 결과를 가져올 수도 있다. 상식이라고 생각되던 것이 거짓으로 판별되는 경우도 있으며, 잘못된 경험
이 편견을 만들어 낼 수도 있기 때문이다. 가능한 검증된 결과를 가지고 이야기하는 것이 많은 사람의 동의를 이끌어내고,
더 좋은 결과를 유도할 것이라는 점은 분명하다. 간혹, 성급한 결정이 돌이킬 수 없는 결과를 만들어 낼 수 있기에, 가능한
여유가 있는 상황에서 논리적으로 합당한 규정을 만들도록 노력해야 할 것이다.
사람은 여유가 없다고 느끼면 일 처리를 빨리 하려고 노력한다. 과정을 생략하고 결과에만 집중하도록 요구 받는다. 결정
은 신속하게 내려지지만 정확하거나 논리적이지 않을 수 있으며, 행위의 결과에 대한 검토는 건너뛰게 된다. 당연히 오류
가 스며들 가능성이 높아지는 것이다. 여유가 필요한 순간이 바로 이 떄다. 급하게 가고 있다는 생각이 들 때면, 다시 한번
지금까지 제대로 해 왔는지를 검토해야 한다. 더 나아가면 다시 돌아가야 할 길만 길어질 뿐이다. 지금 문제가 보이지 않는
다고 해서 문제가 없는 것이 아니며, 검토를 생략하면 당연히 문제는 숨어서 자라게 된다. 커진 문제를 해결하기 보다, 문
제가 작을 때 해결하는 것이 비용이 싸다. 이것은 누구나 아는 사실이지만 가벼운 증상을 키워서 중병으로 만드는 것과 같
다. 이쯤은 괜찮겠지라는 생각이 결국 치명적인 결과를 만드는 것이다. 완벽 하라고 이야기하는 것이 아니라, 최소한 뒤돌
아 볼 수 있는 시간이 필요하다는 것이다. 계속 앞으로만 달려가는 사람은 폭이 좁은 시야를 고수하게 되고, 결국 자신이
가고 있는 방향이 잘못되었다는 사실을 시간이 지나서야 알게된다. 그 때가 되면 이미 돌아가기에는 너무 먼 길을 왔기에,
관성을 그대로 갈 수 밖에 없다. 물론, 그 때라도 조금 여유를 가지는 것이 중요하기는 하지만, 이미 상황이 발생한 상태에
서는 이전에 가지고 있던 여유 마저도 없을 것이 분명하다. 복잡한 일을 하는 사람은 모든 상황을 다 보지 못한다. 모든 상
황을 다 고려한 판단도 불가능하다. 하지만, 만약 그 상황에 대응할 수 있는 “행동 강령”이나 “업무 규칙”이 있다면, 훨씬 더
효과적인 결과를 만들어 낼 수 있다. 앞만보고 가더라도 장애물이 나타날 경우 어떻게 해결할 것인지 미리 계획한다면, 회
피하거나 정면으로 극복하려고 노력할 것이다. 오히려 사태를 악화시키는 것은 임시적인 방편으로 지속적인 대응을 하겠
23 · [ 프로페셔널 프로그래머 ]
다는 생각이다. 상황이 바뀌면 대응 방법도 달리하는 것이 옳지만, 그렇다고 모든 것을 임시적인 해결책으로 완화 시키려
고 노력하는 것은 해답이 아니다. 예를 들어, 제품의 라인업을 다양화 하기 위해서 지속적으로 분기하는 코드를 삽입하는
것은 옳지 않다. 빠르게 고칠수는 있지만, 근본적인 해결책이 아닌 것이다. 그럴 경우에는 미리 제품 분기에 대한 정책을
만들어서 규격화 시킬 필요가 있다. 여유가 있을 때 생각을 정리하지 않으면 임시 방편만 만들다가 아까운 시간을 낭비하
게 되는 것이다.
노력이 결과를 만들기 위해서는 노력의 방향과 질적인 수준을 정해야 한다. 단순히 노력한다고 모든 일이 완성되는 것은
아니다. 누군가는 “1만 시간”을 사용해서 최고의 전문가가 되지만, 또 다른 누군가는 “1만 시간”을 사용해도 평범한 수준
에서 크게 차이가 나지 않을 수 있다. 따라서, 노력이 결과를 만들기 위해서 무엇을 어떻게 해야할지 세부적인 목표와 더불
어 행동 규정도 만들어야 한다. 물론, 그렇게 만들어진 것들이 지속적으로 사용되기도 해야하지만, 계속 더 효과적으로 만
들기 위해서 개선도 해야한다. 지금 부족하다면 근본이 되는 이유를 찾아야하고, 그것을 해결할 수 있는 방법을 축적해야
한다. 임시 방편으로 대응하는 것은 잘모르는 상황에 대해서 좁아진 시야로 할 수 있는 최선의 선택이다. 하지만, 그 때는
최선이었는지 모르지만, 시간이 흐르면 최악의 잘못된 선택이 될 수도 있다. 자신의 분야에 경험과 지식이 충분히 있다고
믿는 사람이라면, 적어도 장기적인 시각에서 올바른 선택이 무엇인지 확고하게 알고 있어야 한다. 단순히 “좋아보이거나
그래야 할 것 처럼 보이는” 결정들은 실패를 부르는 지름길이 될 수도 있다. 빨리 간다고 목표에 도달할 수 있는 것이 아니
라, 제대로 방향을 잡고 가야 좋은 결과를 만들 수 있다. 기초가 부족하다면 기초를 익혀야 할 시간도 필요하며, 경험이 부
족하다면 작고 빠르게 실패할 수 있는 방법도 찾아야 한다. 규칙은 신중하게 선택되어야 하며, 여러 사람의 동의가 필요한
부분이기에 시간을 투자할 충분한 가치가 있다. 또한, 한번 정해진 규칙은 꾸준히 지키는 것이 무엇보다 중요하다. 복잡함
을 정복하는 길은 작은 규칙적인 활동을 반복하는 것이며, 규칙 자체도 꾸준히 다듬어 나가는 것이 필요하다. 너무 많은 규
칙을 만들기 보다, 핵심이 되는 적은 수의 규칙을 만드는 것이 시작이다. 각각의 상황에 맞게 해석을 달리하는 것이 아니
라, 각각의 상황에 적합하도록 다듬는 것이다. 여유는 투자할 수 있는 노력이 있다는 것을 말하며, 놀고 있다는 뜻이 아니
다. 어떻게 여유를 사용해야 할지 모르는 것이 문제이며, 여유 자체가 없는 것이 더 큰 문제다. 여유가 주어지면 사람들은
자신의 행위에 대한 검토와 개선 방법을 만들지만, 여유 없는 삶이란 실수는 하지만 배우지 않는 반복적인 따분함의 연속
일 뿐이다.
- 더 적게 일할 수 있는 방법을 고안 하라. 게으름은 효과적인 방법을 찾도록 만든다.-
24 · [ 프로페셔널 프로그래머 ]
2017/10/24 22:32 http://blog.naver.com/knix008/221124500807
[ 불안감의 정체 ][ 불안감의 정체 ]
낙서장(2017)낙서장(2017)
불안감을 느끼고 있는 상황에서는 좋은 판단을 내리기 어렵다. 가장 중요한 것은 불안감에 대응하는 방어적인 자세를 취하
게 되는 것이 최고 우선순위다. 따라서, 좋은 판단보다는 안정을 추구하는 것이 당연한 행동이며, 변화나 도전은 남의 이야
기로 치부해 버리고 만다. 회사는 변화를 추구하고 도전해야 한다고 이야기 하지만, 실무자 들이 느끼는 것은 가능한 자신
이 할 수 있는 일만 하는 것이 최선이고 최고의 가치다. 실패는 용납되지 않고 실패가 곧 낙인처럼 인식되는 회사에서는 도
전이나 혁신은 구글이나 페이스 북에서만 가능하다고 생각될 뿐이다. 불안감이 없어지지 않는한, 우리가 할 수 있는 일이
라고는 최대한 모험을 하지 않고 안정을 추구하는 것이 최선의 선택이다. 그렇다면 불안감이 생기는 원인은 뭘까? 불안감
은 크게 두가지 측면에서 온다. 첫 번째는 자신의 능력보다 큰 일을 맡았다고 생각 될 때이며, 두 번째는 무슨 일인지 모르
는 경우다. 자신의 능력보다 큰 일은 자신감을 감퇴 시키며, 모르는 일은 무엇을 해야할 지 막연하게 만든다. 확실한 것이
없는 상황에서는 가장 확실한 방법을 선택하기 마련이며, 대부분의 경우 새로운 것보다는 이미 해보았던 것을 선택하는 것
이 가장 안정적인 것이다.
불안감은 미지에서 나온다. 이미 경험한 것은 두려움이 아니다. 이미 알고 있는 것은 힘들지는 모르지만, 어느정도 감을 가
지고 대응할 수 있다. 불안감을 느끼는 것은 무엇인지 모르는 상황에서 나오는 행동이다. 따라서, 파악할 수 있는 절차와
방법이 필요하다. 신입 사원이 가지는 불안감도 마찬가지다. 새로운 일을 맡게 되면 불안감을 느낄 수 밖에 없으며, 불안감
은 곧바로 불편함과 거부감이 들도록 만든다. 불편한 것은 변화를 동반해야 해결이 되지만, 새로운 것들 받아들이는 것 자
체도 불안감을 키울 수 있기 때문에 상황이 악화될 가능성도 있다. 이것을 해결할 수 있는 유일한 방법은 그냥 "모르는 것
을 인정하는 것" 뿐이다. 모르는 것을 모른다고 표현할 수 있다면 누군가의 도움이나 해결할 수 있는 방법을 찾아야 한다는
것을 깨닫게 된다. 불안감을 가지고 아닌 척 해봐야 문제는 해결되지 않기 때문이다. 새로운 것을 받아들일 수 있는 마음이
드는 것도 "스스로 모르는 것을 인정"할 때 가능하다. 미지에서 나오는 불안감을 극복하기 위해서는 학습할 수 있는 시간
이 필요하며, 시험하고 실패할 수 있는 가능성이 열려있어야 한다. 마치 한번의 실패가 모든 실패로 결론나지 않도록 만들
기 위해서는 작은 시도에 대해서 즐겁게 실패할 수 있는 마음가짐이 필요하다.
25 · [ 프로페셔널 프로그래머 ]
바쁜 마음은 불안감을 증폭시키는 효과를 가진다. 잘 모르는 일을 주어진 시간내에 마무리를 지어야 한다는 압박감은 느껴
보지 않은 사람은 알 수 없다. 과제의 리더가 되지 않고서는 그런 감정을 쉽게 알 수 없을 것이다. 문제는 팀원이 느끼는 불
안감보다 리더가 느끼는 불안감이 과제를 엉뚱한 방향으로 몰고갈 수 있다는 점이다. 리더가 불안하면 팀원 들에 대해서
압박감을 줄 수 있으며, 압박받는 상황에서 일하는 팀원들은 될 수 있으면 간단한 해결방법(하지만, 잘못된) 선택을 하게
된다. 쉬운 선택이 올바른 것이 아닐 수도 있지만, 선택을 하는 순간에는 그것을 깨닫지 못한다. 특히, 복잡한 일일수록 잘
못된 선택의 결과는 후반으로 갈수록 효과가 커지게 되며, 그것을 깨닫는 순간 이미 너무 많이가서 다시 돌아가기 함든 상
황이 되고만다. 관성의 힘이 작용하는 것은 물리세계만이 아니라, 우리의 판단도 "이미 만들어 놓은" 것에서 자유로울 수
없다. 사실 바쁘다는 말이 가지는 의미는 일을 제대로 처리하는데 시간이 더 많이 필요하다는 것을 의미한다. 바쁘다는 말
로 단계를 생략해도 된다는 것이 아니다. 리더가 업무에 대한 기준이 명확하지 않다면, 팀원들은 일을 임의로 처리하게 된
다. 바쁘기 때문에 그렇게 해도 아무도 이의를 제기할 수 없는 것이다. 바쁜 마음이 든다면 어떻게 일을 하는 것이 제대로
하는 것인지 기준을 명확히 하는 것이 최선의 답이다.
당겨진 일정, 부족한 기술과 인력, 모자란 자금과 지원 등등 다양한 것들이 불안감을 제공한다. 이중 대부분을 해결해 줄
수 있는 것은 "더 높은 곳에 있는 분"이다. 따라서, 불안감을 조성하는 것도 대부분 그 분들의 일이며 해소하는 방법을 알
려주지도 않는다. 불안감을 조성해서 사람들의 동기를 자극하려는 "단순한" 욕구에서 그렇게 하는 경우와, 실제로 그런 일
정 밖에 만들지 못하는 것이 실력일지도 모른다. 과제가 지속적으로 지연되고 있다면, 다음 번 과제는 더 빨리 시작할 수
있는 방법을 생각해야 하는 것이 아닐까? "그럼에도 불구하고 목표 100%완료"라는 엉뚱한 목표를 제시하고 "도전의
식"과 "주인의식"을 강조하는 것도 그들이다. 문제는 그들 자신이 그런 과제를 하게 된다면 정말 그렇게 할까? 아마도 똑
똑 하셨던 분들이라 결코 그런 진흙 구덩이에 빠지는 과제에서는 일찌감치 발을 뺐을 지도 모른다. 도전적인 목표란 일을
할 수 있는 방법과 일정을 스스로 계획할 때 가능하다. 주인 의식은 권한이 주어졌을 때 생기는 감정이다. 그런 것들이 인
정 받지 못하는 상황에서 만들어지는 불안감은 극복할 수 있는 방법이 없는 것이다. 따라서, 극복하지 못하면 피할 수 밖에
없다. 스스로를 보호하지 못하면 당하는 수 밖에 없기 때문이다. 피할 수 있는 모든 방법을 강구해서 다양한 이유로 일정을
늦추거나, 노력이 많이 필요한 기능들을 제거하는 것도 그것 때문이다. 창의적인 노력이 필요한 복잡한 일을 하지만, 가능
한 다치지 않게 피하는 방법을 배우게 되는 것도 어쩔 수 없다.
- 공포로 해결할 수 있는 것은 일을 망치는 방법을 고안하는 것 뿐이다.-
26 · [ 프로페셔널 프로그래머 ]
2017/10/25 08:36 http://blog.naver.com/knix008/221124696798
[ 환경이 사람을 만든다. ][ 환경이 사람을 만든다. ]
낙서장(2017)낙서장(2017)
코딩은 정신 활동이다. 따라서, 코딩하는 사람의 정신 상태가 코드에 영향을 줄 가능성이 높다. 코딩이 원활하게 이루어지
기 위해서는 그 일을 하는 사람의 심리적인 상태가 안정적이어야 하며, 그렇지 못할 경우 좋은 코드가 나오지 않을 것이 분
명하다. 야근이나 특근은 미진한 부분에 대한 만회를 할 수 있는 시간이다. 바쁜 상황에서 처리하지 못했던 남은 업무를 마
감할 떄 활용할 수 있는 유일한 기회다. 상시 야근과 특근이 일상화가 되면 하루 동안 사용해야 할 한정된 정신력이 분산되
는 효과를 낳으며, 생산성이 떨어지는 것은 당연한 결과일 것이다. 선진국과 우리나라의 산업 생산성에 대한 비교를 하면
서, 우리나라는 일을 많이 하면서 생산성이 높지 않아서 고비용 저효율이라고 이야기 한다. 이는 선택의 문제이며 우리나
라의 대부분의 관리자들은 고비용이 들더라도 많은 일을 할 것 처럼 보이는 것을 선택했기 때문에 발생하는 결과일 뿐이
다. 마치 조직의 구성원이 효율이 낮아서 그런 것 처럼 보이는 말을 하지만, 실질적으로 높은 가치를 만드는 일보다 빨리
조금이라도 많이 만들어 싸게 파는 것을 전략적으로 추진했기 때문에 나오는 현상이다. 효율을 높이고자 한다면 주어진 시
간에 고부가 가치를 생산할 수 있는 일을 해야한다. 또한, 하나의 가치를 만들더라도 더 큰 시장에서 팔 수 있도록 표준화
된 제품을 만들어 주어야 한다. 서비스를 제공한다면 한정된 작은 시장보다는 큰 시장을 대상으로 해야하며, 물질적으로
손에 잡히는 것보다 생산과 동시에 소비가 이루어질 수 있는 것들을 만들어야 한다. 노동 집약적인 산업에서 지식 집약적
인 산업으로 이동하는 이유도 마찬가지다. 하지만, 그 모든 것을 가능하게 만들기 위해서 가장 필요한 것은 구성원의 “올바
른 정신 활동이 가능한 상태”를 만들어주는 것이 선행되어야 한다. 사람은 하루에 한정된 노력 만을 투자할 수 있으며, 투
자 효과가 극대화가 되기 위해서는 사소한 낭비를 줄이고 집중할 수 있는 분위기를 유도해야 한다. 그런 환경이 되지 못한
다면 시스템을 탓해야지 사람을 탓하고 있어서는 안된다. 누구나 좋은 환경에서 자라면 훌륭한 인재가 될 것이라는 것은
다 알면서도, 좋은 환경 만들기에 인색하게 굴면서 좋은 인재 타령만 해선 안될 것이다.
좋은 환경은 좋은 코드를 만든다. 정신 상태가 맑은 상황에서 코딩하는 것이 당연히 더 적은 버그를 만든다. 피곤하고 지친
상태에서 만드는 코드는 잠재적인 버그의 개수를 늘린다. 하지만, 우리가 일을 하는 방식은 “더 많이 더 빨리”에 가깝다.
따라서, 더 많은 코드를 더 빠르게 만들기 위해서 더 오랜 시간을 일하게 되는 것이 현실이다. 맑은 정신 상태를 유지하기
위해서는 적절한 휴식이 필요하지만, 휴식 시간을 길게 가지면 노는 것 처럼 보여서 관리자들은 싫어한다. 정신이 지치면
사람들이 하는 반응은 “더 느리게 집중하지 않고” 코딩하게 된다. 당연히 일하는 시간은 길어지지만 품질이 나쁜 코드가 만
들어진다. 사람의 정신력이란 무한정 뽑아서 쓸 수 있는 것이 아니라, 휴식을 취해야만 회복할 수 있다. 휴식 시간이 짧아
지면 당연히 뽑아낼 수 있는 정신력도 적을 수 밖에 없다. 적은 정신력을 길어진 시간에 맞추기 위해서는 집중의 밀도가 낮
아질 수 밖에 없는 것이다. 사람에 대한 평가를 내릴 때, 그 사람이 얼마나 오래동안 근무를 했는가를 따진다면, 일의 품질
보다는 자리에 앉아 있는 시간만 평가를 받게 된다. 대부분의 관리자들은 자리에 앉아서 일하고 있는 모습을 보기 좋아하
며, 자신이 쉽게 그런 상황을 파악할 수 있는 것을 바랜다. 잠시 일어나서 훑어보는 것으로 누가 아직 퇴근하지 않고 일하
는지 알고 싶어한다. 그리고, 그것이 그들이 할 수 있는 최선의 “빠른 납기 달성을 위한 방법”처럼 보이기도 한다. 하지만,
27 · [ 프로페셔널 프로그래머 ]
문제는 납기를 만족했다고 일이 끝나지 않는다는 점이다. 비용은 납기 이후에 발생하면 대처하기 위한 시간도 길어지며 큰
낭비를 가져오는 성향이 있다. 흐리멍텅한 정신으로 만든 문제들이 납기 이후에 발생하지 않을 것이라고 장담할 수 있을
까? 우리가 만드는 코드의 테스트 범위도 모르는 상황에서 단순히 테스트를 통과했다는 의미를 납기 이후까지 확장할 수
있을까? 그것은 근거없는 낙관일 뿐이다. 그리고, 그 낙관은 쉽게 손상되는 것이 일반적이다.
좋은 코드를 만들기 위해서는 “역량있는 인재”들이 필요하지만, 그런 인재들은 비싸고 움직이지도 않는다. 이미 회사에서
그런 인재들을 충분히 대우하고 있을 것이 분명하다. 또한, 역량있는 인재를 찾는 것도 쉽지 않다. 누가 역량이 있는지는
옆에서 일해본 사람만이 알 수 있기 때문이다. 대부분의 역량있는 인재들은 더 환경이 좋은 회사를 선호한다. 금전적인 부
분이 만족되면 그 다음은 회사의 분위기를 찾게 되는 것이다. 인재들은 환경이 좋지 않다면 아무리 많은 돈을 주더라도 쉽
게 회사를 떠난다. 남는 사람들은 “인재(인간 재앙)”에 가까운 사람들이 될 가능성이 높다. 물론, 이것도 사람을 길러내는
회사의 시스템적인 문제다. 동일한 출발선에서 시작하더라도 누군가는 역량있는 인재가 되고, 누군가는 재앙을 몰아오는
사람이 되는 것이다. 그런 차이를 만드는 것이 바로 회사의 체계(시스템)와 분위기다. 사람을 아끼는 회사라면 인재를 키
우는데 투자를 아끼지 않을 것이다. 적어도 스타트 업과 같은 벤처라고 하더라도 좋은 인재를 찾기 위한 여러가지 아이디
어는 가지고 있을 것이다. 그것들 대부분이 단순히 “연봉”만을 이야기 하지는 않는다. 좋은 환경이라고 해서 무조건적인
“여유”를 말하는 것은 아니다. 사람이 성장하는데는 적절한 도전 목표와 그것을 자율적으로 해결할 수 있도록 만들어주는
시스템이 있어야 한다. 단순히 좋은 분위기만 유지하고 편하다는 느낌으로는 만족되지 않는 “발전하고자 하는 욕구”가 있
기 때문이다. 좋은 인재들은 자신이 발전하고 있다는 느낌을 가지고 싶어한다. 마냥 반복되는 지루한 업무는 그들에게 따
분함만 줄 뿐이다. 자신이 결정하고 행동할 수 있는 것도 중요한 요구사항이다. 아무 것도 결정할 권한이 없고 누군가의 일
방적인 의견이나 명령만 들어야 하는 상황은 인내력이 아무리 강한 사람이라도 참아내기 힘들다. 아마도 그런 환경을 이겨
낸 사람은 이미 새로운 것에 대한 도전 정신이나 자발적인 동참과 같은 부분은 “뇌에서 제거”되었을지도 모른다.
28 · [ 프로페셔널 프로그래머 ]
사람이 무한한 능력을 가지고 있다고 이야가 하지만, 그것을 뽑아내서 쓰는 것은 시스템의 몫이다. 잘못된 시스템을 아무
리 활용해봐야 나올 수 있는 아웃풋은 쓰레기에 가까운 결과물일 뿐이다. 무한한 잠재력이라고 하지만 휴식이 없이는 서서
히 밑바닥을 드러내는 우물이 되고말 것이다. 많은 일을 빠른 시간내에 마칠 수는 있을지 모르지만, 그 각각의 처리한 일들
이 제대로 되었다는 보장은 할 수 없다. 한번에 많은 일을 하게 되면 정신적인 소모가 커지게 되며, 결국 더 오랜 시간을 보
충을 위해서 필요로 한다. 이것이 지켜지지 않으면 뽑아내 사용할 수 있는 역량도 줄어들기 마련이다. 관리자들은 인정하
기 힘들겠지만 이것이 현실이다. “더 열심히, 더 오래, 더 많이”하라고 이야기하는 것에도 한계가 있는 것이다. 일정을 아무
리 당긴다고 하더라도 한 사람이 열 달 할 일이 열 사람이 한 달내에 끝내지는 못한다. 커뮤니케이션과 동기화에 따르는 오
버헤드도 필요하며, 야근과 특근으로 지치게 만들수록 일은 더디게 진행될 것이 분명하기 때문이다. 무한한 능력을 발휘할
수 있도록 만들기 위해서 관리자들이 유일하게 할 수 있는 것은, 과제에 필요한 모든 것 중에서 자신의 능력으로 해결할
수 있는 것들을 제공하는 것 밖에 없다. 맑은 정신을 가질 수 있는 휴식과 적절한 도전적인 일정 및 자유로운 방법의 선택,
불필요한 숙제를 줄여주는 것등이 좋은 인재를 끓어들이고 효과적으로 능률을 높일 수 있는 유일한 방법이다. 아무리 다그
치고 야단친다고 하더라도 효과는 잠시 밖에 지속되지 않는다. 관리자의 목소리가 커지면 구성원의 목소리는 작아지고 불
만 수준은 커지는 것이 당연하다. 큰 목소리를 낸다고 일이 제대로 돌아간다면 목소리 큰 사람이 가장 높은 자리를 차지해
야 옳을 것이다. 좋은 코드는 좋은 환경에서 나오며, 그 환경을 만드는 것이 관리자의 몫인 것이다. 환경이 좋다면 역량있
는 인재가 회사를 마다할리가 없다. 사람이 회사를 떠나는 가장 큰 이유 중에 하나가 자신이 생존해야 할 공간에서 제공받
지 못하는 것(해결되지 않는 욕구)이 있기 때문이다.
- 인재는 인재를 알아보고, 좋은 환경은 좋은 인재를 끌어들인다.-
29 · [ 프로페셔널 프로그래머 ]
2017/11/14 21:10 http://blog.naver.com/knix008/221140028509
[ 과제 관리자 되기 ][ 과제 관리자 되기 ]
낙서장(2017)낙서장(2017)
과제 관리자의 대부분은 과제 관리를 모르는체로 과제 관리자가 된다. 그들은 개발 경험이 많거나, 연차가 오래되었다고,
혹은 성공한 프로젝트 경험을 가지고 있다는 이유로 과제 관리자의 위치로 간다. 물론, 그들이 할 수 있는 일은 기존의 과
제 관리자가 해오던 것을 최대한 위배하지 않는 것이다. 동일한 템플릿을 사용하고, 남들과 같은 방법으로 같은 내용을 기
술해서, 비슷하게 발표하고 보고한다. 전임 관리자들도 과제 관리에 대해서 배운 것은 없지만, 시간을 통해서 알게되는
"관례"에 익숙한 방법을 그보다 앞선 전임 관리자 처럼 했을 것이 분명하다. 따라서, 우리는 제대로 관리자가 될 준비가 되
지 않은 상태에서 관리자가 되는 것이다. 준비없는 관리자가 할 수 있는 것은 개발자 시절에 자신이 했던 일을 반복하는 것
뿐이다. 새로운 것을 배우지 못했다면, 지금까지 알고 있는 것이라도 잘할 수 밖에 없다. 개발자로서 잘하던 사람들도 관리
자가 되면 자신의 역할이 바뀌었음을 인식하지 못하고, 소위 말하는 "대리"처럼 행동하게 된다. 자세한 것은 잘 보지만 전
체 그림을 그리지 못하며, 자신이 관심있는 일은 주의 깊게 보지만, 전공했던 것과 관련이 없는 일은 시선에서 놓치게 된
다.
관리자가 된 후에 배우는 것도 과제 관리가 아닌 팀 빌딩이나 "좋은 관리자란 무엇인가"라는 이야기 밖에 없다. 사실 그런
교육은 크게 전문적인 지식을 요구하는 것은 아니기에, 강사들도 많고 교육 비용도 비싸지 않다(현재 관련된 일을 하고 있
는 사람들을 낮춰보는 것은 절대 아니기에 오해 없기를 바란다.). 그때 배우는 좋은 관리자가 되는 길이라고 해봐야 대부분
비슷한 이야기 뿐이다. "코치가 되려고 노력해야 하며, 보스가 아닌 리더가 되라"는 것이다. 팀원 들과 대화를 많이 해야하
고, 그들이 일을 즐길 수 있는 환경을 만들어야 한다는 이상적인 이야기 뿐이다. 그런 리더가 있으면 좋지만 그렇지 않은
리더가 많은 이유가 그 때문이다. 좋은 리더보다 더 드문 것은 "훌륭한 과제 관리자"다. 그들의 가치는 과제를 성공으로 이
끄는 핵심이며, 그들의 가지는 전문적인 기술은 교육을 통해서 전달할 수 있기에 중요하다. 투자를 하려면 좀 더 목적이 확
실한 곳에 하는 것이 옳은 방향이 아닐까?
30 · [ 프로페셔널 프로그래머 ]
관리자가 되기 위해서는 과제 관리 방법을 알아야 한다. 예를 들어, 과제의 일정을 산출하거나, 해야할 일을 정리하는
WBS(Work Breakdown Structure)를 만들어 낼 수 있어야 한다. 하지만, 대부분의 경우 일정 산출은 자신의 경험에 의
지하는 부분이 많으며, 과제의 기능이나 난이도, 인력 구성, 마일스톤에 따른 기능의 우선 순위 등등은 충분히 고려하지 않
는다. WBS도 대부분의 경우 간트 차트(Gantt Chart)정도만 생각하고 툴을 이용해서 그때 수정할 뿐, 거의 일정 관리 목
적으로만 사용하는 것이 현실이다. 우리는 실제로 과제에 대한 관리 방법에 대해서는 문외한 이면서도 나름 자신은 과제
관리에 대해서 철학이 있다고 생각하고 있는지도 모른다. 그렇다고 모든 사람이
PMP(Project Management Professional) 자격증을 따라는 것은 아니다. 적어도 “성공할 가능성이 높은 과제 관리 방
법”에 대해서 체계적인 교육이 필요하며, 그것을 통해서 상위 관리자들도 과제의 개발자 역할을 할 때와 다른 관점에서 과
제를 바라보아야 한다는 것을 익혀야 한다. 개발자가 진급해서 관리자가 되지만, 그렇게 성장한 관리자는 과제 관리에 대
한 좋은 경험과 지식은 가지지 못한체로 역할을 맡게 된다. 당연히 제대로 된 과제 관리자가 되지 못한다. 리더가 되건 보
스가 되건 상관없이 “과제 관리”는 항상 진행해야 하는 업무다.
소프트웨어 개발은 벌써 50년이 넘는 역사를 가지고 있다. 물론, 다른 분야에 비하면 터무니없이 짧은 것도 사실이다. 하
지만, 50년의 시간동안 과제 관리자들이 놀고만 있었던 것은 아니고, 수많은 실패 사례를 분석해서 나름의 성공적인 방법
론들을 만들어 왔다. 애자일(Agile)도 어떻게 보면 그런 실패의 산물인지도 모른다. 실패를 했기에 더 나은 방법이 있는지
찾아 보았을 것이고, 실패를 했기에 성공하는 방법에 대해서 아낌없이 투자를 했던 것이다. 애자일이 만병 통치약은 아니
지만, 그렇다고 자신의 과제에 적용하지 못할 이유도 없다. 예를 들어, 기능별 구현 전략이나 조기(Early) 테스트, 상호간의
대화를 통한 문제 발견 및 해결 노력, 지속적인 개선과 자기주도적인 팀원 들의 개발 참여 등은 모든 과제에서 유용한 방
법이다. 아쉬운 것은 경험하지 않은 것에 대한 막연한 실패의 두려움과 터무니 없는 일정을 주고도 “열심히”만 강조하는 관
리자들의 마인드다. 물론, 그들 나름의 고민도 있고 성과 지향이라는 어쩔 수 없는 부분도 있지만, 그렇다고 “우물에서 숭
늉을 찾는다”는 말이 되어서는 안될 것이다.
31 · [ 프로페셔널 프로그래머 ]
- 훌륭한 과제 관리자를 만나는 것은 그 자체가 축복이다.-
32 · [ 프로페셔널 프로그래머 ]
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3
소프트웨어개발자이야기 2017 p3

More Related Content

What's hot

사용자 스토리 기반의 스크럼
사용자 스토리 기반의 스크럼사용자 스토리 기반의 스크럼
사용자 스토리 기반의 스크럼Junyi Song
 
초간단스크럼
초간단스크럼초간단스크럼
초간단스크럼Hyun Chang Lee
 
제1부 전략과 분석 제5장 프로젝트 관리
제1부 전략과 분석 제5장 프로젝트 관리제1부 전략과 분석 제5장 프로젝트 관리
제1부 전략과 분석 제5장 프로젝트 관리Minsuk Chang
 
애자일에대한오해와진실
애자일에대한오해와진실애자일에대한오해와진실
애자일에대한오해와진실Sangcheol Hwang
 
잘하면고효율, 못하면가문의원수가되는 짝프로그래밍 (Effective Pair Programming with Lessons Learned)
잘하면고효율, 못하면가문의원수가되는 짝프로그래밍 (Effective Pair Programming with Lessons Learned)잘하면고효율, 못하면가문의원수가되는 짝프로그래밍 (Effective Pair Programming with Lessons Learned)
잘하면고효율, 못하면가문의원수가되는 짝프로그래밍 (Effective Pair Programming with Lessons Learned)Suwon Chae
 
소프트웨어 공학의 사실과 오해
소프트웨어 공학의 사실과 오해소프트웨어 공학의 사실과 오해
소프트웨어 공학의 사실과 오해한 경만
 
User Stories Applied
User Stories AppliedUser Stories Applied
User Stories AppliedJungHyuk Kwon
 
Getting Real Overview(한글)
Getting Real Overview(한글)Getting Real Overview(한글)
Getting Real Overview(한글)parkchanwook
 
애자일 프랙티스
애자일 프랙티스애자일 프랙티스
애자일 프랙티스한 경만
 
[AUG] 칸반을 활용한 업무 프로세스 혁신 실천법
[AUG] 칸반을 활용한 업무 프로세스 혁신 실천법[AUG] 칸반을 활용한 업무 프로세스 혁신 실천법
[AUG] 칸반을 활용한 업무 프로세스 혁신 실천법철민 신
 
0. review. 린과 애자일 개발
0. review. 린과 애자일 개발0. review. 린과 애자일 개발
0. review. 린과 애자일 개발Unyong (Sheldon) Choi
 
린 소프트웨어 개발(Lean software development)
린 소프트웨어 개발(Lean software development)린 소프트웨어 개발(Lean software development)
린 소프트웨어 개발(Lean software development)영기 김
 
스크럼 리뷰 이지원 발표용
스크럼 리뷰 이지원 발표용스크럼 리뷰 이지원 발표용
스크럼 리뷰 이지원 발표용지원 이
 
Agile의 의미와 Agile 계획 수립(Gdc2007)
Agile의 의미와 Agile 계획 수립(Gdc2007)Agile의 의미와 Agile 계획 수립(Gdc2007)
Agile의 의미와 Agile 계획 수립(Gdc2007)Kay Kim
 

What's hot (14)

사용자 스토리 기반의 스크럼
사용자 스토리 기반의 스크럼사용자 스토리 기반의 스크럼
사용자 스토리 기반의 스크럼
 
초간단스크럼
초간단스크럼초간단스크럼
초간단스크럼
 
제1부 전략과 분석 제5장 프로젝트 관리
제1부 전략과 분석 제5장 프로젝트 관리제1부 전략과 분석 제5장 프로젝트 관리
제1부 전략과 분석 제5장 프로젝트 관리
 
애자일에대한오해와진실
애자일에대한오해와진실애자일에대한오해와진실
애자일에대한오해와진실
 
잘하면고효율, 못하면가문의원수가되는 짝프로그래밍 (Effective Pair Programming with Lessons Learned)
잘하면고효율, 못하면가문의원수가되는 짝프로그래밍 (Effective Pair Programming with Lessons Learned)잘하면고효율, 못하면가문의원수가되는 짝프로그래밍 (Effective Pair Programming with Lessons Learned)
잘하면고효율, 못하면가문의원수가되는 짝프로그래밍 (Effective Pair Programming with Lessons Learned)
 
소프트웨어 공학의 사실과 오해
소프트웨어 공학의 사실과 오해소프트웨어 공학의 사실과 오해
소프트웨어 공학의 사실과 오해
 
User Stories Applied
User Stories AppliedUser Stories Applied
User Stories Applied
 
Getting Real Overview(한글)
Getting Real Overview(한글)Getting Real Overview(한글)
Getting Real Overview(한글)
 
애자일 프랙티스
애자일 프랙티스애자일 프랙티스
애자일 프랙티스
 
[AUG] 칸반을 활용한 업무 프로세스 혁신 실천법
[AUG] 칸반을 활용한 업무 프로세스 혁신 실천법[AUG] 칸반을 활용한 업무 프로세스 혁신 실천법
[AUG] 칸반을 활용한 업무 프로세스 혁신 실천법
 
0. review. 린과 애자일 개발
0. review. 린과 애자일 개발0. review. 린과 애자일 개발
0. review. 린과 애자일 개발
 
린 소프트웨어 개발(Lean software development)
린 소프트웨어 개발(Lean software development)린 소프트웨어 개발(Lean software development)
린 소프트웨어 개발(Lean software development)
 
스크럼 리뷰 이지원 발표용
스크럼 리뷰 이지원 발표용스크럼 리뷰 이지원 발표용
스크럼 리뷰 이지원 발표용
 
Agile의 의미와 Agile 계획 수립(Gdc2007)
Agile의 의미와 Agile 계획 수립(Gdc2007)Agile의 의미와 Agile 계획 수립(Gdc2007)
Agile의 의미와 Agile 계획 수립(Gdc2007)
 

Similar to 소프트웨어개발자이야기 2017 p3

SWDeveloperStory201501
SWDeveloperStory201501SWDeveloperStory201501
SWDeveloperStory201501Suho Kwon
 
프로젝트 Xxx에 적용하고 싶은 개발방법
프로젝트 Xxx에 적용하고 싶은 개발방법프로젝트 Xxx에 적용하고 싶은 개발방법
프로젝트 Xxx에 적용하고 싶은 개발방법도형 임
 
Agile sw development 101
Agile sw development 101Agile sw development 101
Agile sw development 101Kiwon Kyung
 
프로덕트 매니지먼트하기
프로덕트 매니지먼트하기프로덕트 매니지먼트하기
프로덕트 매니지먼트하기YOO SE KYUN
 
애자일 도입과 사례 공유
애자일 도입과 사례 공유애자일 도입과 사례 공유
애자일 도입과 사례 공유agilekorea
 
220806 UX/UI 해외 인기 아티클 6기 : 3주차 발표
220806 UX/UI 해외 인기 아티클 6기 : 3주차 발표220806 UX/UI 해외 인기 아티클 6기 : 3주차 발표
220806 UX/UI 해외 인기 아티클 6기 : 3주차 발표Minho Lee
 
Sk planet 이야기
Sk planet 이야기Sk planet 이야기
Sk planet 이야기종범 고
 
Itsm팀 내부세미나 익스트림프로그래밍_정희찬
Itsm팀 내부세미나 익스트림프로그래밍_정희찬Itsm팀 내부세미나 익스트림프로그래밍_정희찬
Itsm팀 내부세미나 익스트림프로그래밍_정희찬정 희찬
 
TDD - 테스트 주도로 개발하기
TDD - 테스트 주도로 개발하기TDD - 테스트 주도로 개발하기
TDD - 테스트 주도로 개발하기현승 배
 
Dev rookie codecomplete-1
Dev rookie codecomplete-1Dev rookie codecomplete-1
Dev rookie codecomplete-1대영 노
 
사용자 스토리 기반의 스크럼(Scrum)
사용자 스토리 기반의 스크럼(Scrum)사용자 스토리 기반의 스크럼(Scrum)
사용자 스토리 기반의 스크럼(Scrum)재능마켓 크몽
 
[오픈소스컨설팅] DevOps 체험교육 소개
[오픈소스컨설팅] DevOps 체험교육 소개[오픈소스컨설팅] DevOps 체험교육 소개
[오픈소스컨설팅] DevOps 체험교육 소개Brian HAN 한진규
 
Agile SW 개발
Agile SW 개발Agile SW 개발
Agile SW 개발혁 권
 
[디프만 6기] 디자인만 할 줄 아는 시대는 끝났다.
[디프만 6기] 디자인만 할 줄 아는 시대는 끝났다.[디프만 6기] 디자인만 할 줄 아는 시대는 끝났다.
[디프만 6기] 디자인만 할 줄 아는 시대는 끝났다.DongYoung Kim
 
팀장님 근데 Cmmi가 뭐에여
팀장님 근데 Cmmi가 뭐에여팀장님 근데 Cmmi가 뭐에여
팀장님 근데 Cmmi가 뭐에여도형 임
 

Similar to 소프트웨어개발자이야기 2017 p3 (20)

SWDeveloperStory201501
SWDeveloperStory201501SWDeveloperStory201501
SWDeveloperStory201501
 
프로젝트 Xxx에 적용하고 싶은 개발방법
프로젝트 Xxx에 적용하고 싶은 개발방법프로젝트 Xxx에 적용하고 싶은 개발방법
프로젝트 Xxx에 적용하고 싶은 개발방법
 
애자일프랙티스
애자일프랙티스애자일프랙티스
애자일프랙티스
 
AKC2020 인썸니아 이성훈
AKC2020 인썸니아 이성훈AKC2020 인썸니아 이성훈
AKC2020 인썸니아 이성훈
 
Agile sw development 101
Agile sw development 101Agile sw development 101
Agile sw development 101
 
프로덕트 매니지먼트하기
프로덕트 매니지먼트하기프로덕트 매니지먼트하기
프로덕트 매니지먼트하기
 
애자일 도입과 사례 공유
애자일 도입과 사례 공유애자일 도입과 사례 공유
애자일 도입과 사례 공유
 
220806 UX/UI 해외 인기 아티클 6기 : 3주차 발표
220806 UX/UI 해외 인기 아티클 6기 : 3주차 발표220806 UX/UI 해외 인기 아티클 6기 : 3주차 발표
220806 UX/UI 해외 인기 아티클 6기 : 3주차 발표
 
Sk planet 이야기
Sk planet 이야기Sk planet 이야기
Sk planet 이야기
 
개발 관리론
개발 관리론개발 관리론
개발 관리론
 
Itsm팀 내부세미나 익스트림프로그래밍_정희찬
Itsm팀 내부세미나 익스트림프로그래밍_정희찬Itsm팀 내부세미나 익스트림프로그래밍_정희찬
Itsm팀 내부세미나 익스트림프로그래밍_정희찬
 
TDD - 테스트 주도로 개발하기
TDD - 테스트 주도로 개발하기TDD - 테스트 주도로 개발하기
TDD - 테스트 주도로 개발하기
 
AKC2020 marimba 마주연
AKC2020 marimba 마주연AKC2020 marimba 마주연
AKC2020 marimba 마주연
 
Dev rookie codecomplete-1
Dev rookie codecomplete-1Dev rookie codecomplete-1
Dev rookie codecomplete-1
 
사용자 스토리 기반의 스크럼(Scrum)
사용자 스토리 기반의 스크럼(Scrum)사용자 스토리 기반의 스크럼(Scrum)
사용자 스토리 기반의 스크럼(Scrum)
 
[오픈소스컨설팅] DevOps 체험교육 소개
[오픈소스컨설팅] DevOps 체험교육 소개[오픈소스컨설팅] DevOps 체험교육 소개
[오픈소스컨설팅] DevOps 체험교육 소개
 
Agile SW 개발
Agile SW 개발Agile SW 개발
Agile SW 개발
 
[디프만 6기] 디자인만 할 줄 아는 시대는 끝났다.
[디프만 6기] 디자인만 할 줄 아는 시대는 끝났다.[디프만 6기] 디자인만 할 줄 아는 시대는 끝났다.
[디프만 6기] 디자인만 할 줄 아는 시대는 끝났다.
 
발표원고
발표원고발표원고
발표원고
 
팀장님 근데 Cmmi가 뭐에여
팀장님 근데 Cmmi가 뭐에여팀장님 근데 Cmmi가 뭐에여
팀장님 근데 Cmmi가 뭐에여
 

소프트웨어개발자이야기 2017 p3

  • 1. 2017/10/11 10:13 http://blog.naver.com/knix008/221114494392 [ 소프트웨어 산업의 본질 - 03 ][ 소프트웨어 산업의 본질 - 03 ] 낙서장(2017)낙서장(2017) 실패는 어쩔 수 없이 발생한다. 모든 개발이 성공적으로 마무리 된다는 말은 거짓이다. 100% 일정내 개발이라는 것도 사 실일 수 없다. 실패의 정의를 “변경된 일정, 비용, 범위”라고 한다면 그럴수도 있겠지만, 사실상 계획은 계획일 뿐이다. 만 들기도 전에 잡아놓은 계획은 만들면서 구체적으로 변경될 뿐이다. 따라서, 실패를 받아들이는 태도를 바꾸지 않는한, 소 프트웨어 개발의 본질을 제대로 반영하지 못한다. 물론, 다른 개발도 마찬가지다. 대부분의 개발은 실패를 가정하고 있으 며, 그 중에서 몇가지만 성공해도 충분한 가치가 있는 것이다. 대기업은 100개의 제품을 개발해서 1개 정도의 대박 제품 을 만들면 이익을 남길 수 있지만, 중소기업은 10개의 제품을 만들어 5개 이상을 성공시키지 못하면 살아남기 힘들다. 여 기서 실패의 방법이 차이가 난다. 즉, 대기업은 큰 실패를 할 수 있는 여력이 있지만, 중소기업은 작은 실패도 심각한 상황 이 될 수 있다는 점이다. 그렇다고 실패하지 않을 일만 할 수 있는 것은 아니다. 중소기업이 취할 수 있는 현명한 실패는, 빠른(혹은, 이른) 실패를 결험하는 것이다. 짧은 반복주기를 거치면서 실패를 경험한다면, 다음 주기에 실패를 만회할 수 있다. 긴 반복주기에서 실패를 경험하게 되면, 그 동안 투자되었던 노력이 물거픔이 되지만, 짧고 빠른 실패는 복구 비용도 크지 않다. 현실이 이와같다면, 계획은 빠른 실패를 할 수 있는 방법을 실행하는데 초점을 맞춰야 한다. 실패는 배움의 과 정에서 항상 발생하는 일이며, 경험의 축적이 생기면 성공으로 가는 방법을 찾아내게 된다. 실패를 받아들이는 태도의 변 화가 없다면, 실패는 누군가의 탓만하는 것으로 끝나고 만다. 개발자의 실패가 허락되지 않는 조직은 경쟁력 없는 누구나 다 만들 수 있는 제품만 개발할 뿐이다. 그런 제품을 가지고 시장에 나서는 행위는 자살밖에 되지 않는다. 많이 팔아봐야 남는 것이 없는 장사일 뿐이다. 실패가 인정되지 않으면 도전도 하지 않는다. 당연한 말이다. 누가 과제 실패에 인생을 걸 수 있겠는가? 차라리 도전하지 않고 주는 월급만 챙길 수 있는 안정적인 일을 찾을 것이 분명하다. 공무원이 제일 안정적이라고 생각한다면, 그쪽으로 사 람들이 몰릴 수 밖에 없다. 실패했을 때 일어설 수 있도록 만들어야 도전이 가능하다. 한번에 실패로 모든 것이 돌이킬 수 없는 상황에 처한다면, 누구도 쉽게 나서지 못한다. 실패는 과정이며 성공은 결과다. 따라서, 과정 없이는 성공이라는 결과 도 없다. 성공을 원하면서 실패를 회피 하려는 것도 올바른 태도는 아니다. 물론, 그렇다고 실패를 꼭 하라는 말은 아니다. 과정에서 발생하는 실패를 “학습”으로 만들기 위해서는 계획된 실패가 필요하다. 축구의 신이라고 해서 모든 경기에 골을 넣는 것은 아니며, 골을 넣지 못했다고 다른 경기에 출장하지 않는 것도 아니다. 필요한 것은 과감하게 도전할 수 있도록 용기를 주는 것이지, 이겨내지 못하는 좌절을 안기는 것이 아니다. 개발은 상시 실패를 경험할 수 밖에 없다. 누구도 해보 지 않은 것을 만드는 것은(혹은, 남들은 해봤지만 우리는 경험이 없는 것을 만드는 것) 실패조차 경험으로 받아들일 수 있 는 자세가 필요하다. 책임을 회피하고자 하는 사람들은 실패하지 않을 일만 찾아다닌다. 안정 위주의 성장 전략을 짜고 작 은 이익을 추구하며 절대 새로운 일은 시작하지 않는다. 이런 상황에서 만들어지는 소프트웨어는 당연히 지난 성공을 다시 재탕 삼탕하는 것 밖에 되지 않는다. 소프트웨어 개발은(특히, 잘 모르는 것을 만들 때는) 빨리 무엇 인가를 만들어 사용자 의 피드백을 얻는 것이 중요하다. 실패하더라도 그것이 경험으로 남기 위해서는 피드백을 얻는데 주저할 필요가 없는 것이 1 · [ 프로페셔널 프로그래머 ]
  • 2. 다. 계획은 그런 경험을 축적하는 과정에서 더 정교하게 바뀔 것이고, 성공하기 위한 로드맵은 지속적으로 업데이트 될 것 이다. 우리는 실패를 인정하는 것을 두려워한다. 실패 자체가 자신의 오점으로 남고, 나중에도 성장의 걸림돌로 작용할 가능성이 있기 때문이다. 자신의 실수를 겸허하게 받아들이지 않는 이유도 동일하다. 일단은 살아남아야 다음을 기약할 수 있기 때 문이다. 또한, 본능적으로 위협이 있다고 판단될 경우 방어적인 태도를 취할 수 밖에 없다. 외부의 위협이란 결국 책임 추 궁이나 비난이 될 수 있으며, 그것을 모면할 수 있다면 어떤 핑게라도 만들어낼 수 있을 것이다. 개발자들이 만든 실수로 인해서 큰 비용이 들었다고 하더라도, 결국 실패 비용은 어쩔 수 없이 발생한 상황이다. 그것을 수습하는 것이 먼저다. 만 약, 그 책임을 개발자에게 묻는다면 실패 비용을 고스란히 개발자가 떠 안게 될 것이고, 당연히 과제는 투자한 비용만 남기 고 없어지게 될 것이다. 사람이 없으면 과제도 없는 것이다. 이미 마음이 떠난 과제를 책임지고 완수할 사람도 없으며, 만 약에라도 발생할 수 있는 실패에 대해서 책임지고 싶은 생각도 없을 것이다. 이런 상황을 개선할 수 있는 방법은 회사가 개 발자의 실패에 대해서 너그러움을 가지는 것 밖에 없다. 100% 만족을 원한다면 99%도 불만족 상태 겠지만, 80%만으 로도 충분하다면 이미 넘칠 정도로 만족한 상태가 된다. 회사는 개발자들이 실패했을 때, 어떤 상황이 만족스러운 상태인 지 확인시켜 주어야 한다. 원하는 기능이나 성능의 100%구현이 목표가 아니라, 얼마나 만족스러운지 긍정적으로 반응해 주어야 한다. 실패에서 배우지 못하는 것은 안되는 방법을 한가지 더 찾았다는 뜻이 아니라, 지금까지의 노력이 무의미 하 다는 것만 강조할 뿐이다. 실패의 복구는 책임 추궁이 아니라, 더 나은 결과를 만들기 위한 노력을 결집하는 것이다. 2 · [ 프로페셔널 프로그래머 ]
  • 3. 책임은 개발자가 지는 것이 아니라 계획하는 사람에게 돌아가야 맞다. 조직의 실패는 시스템의 실패이며, 개발자는 개인일 뿐이다. 따라서, 계획에 관련된 사람들이 제대로 일을 수행하지 않아서 시스템의 운영이 미숙 했던 것일 뿐이다. 하지만, 현실은 항상 계획한 사람과 책임지는 사람이 분리되어 있다. 누군가의 명령(혹은, 좋은 의도)으로 계획된 과제가 “일정, 비 용, 기능”을 만족시키지 못한체 실패했다면, “일정이나, 비용, 기능”의 선택에 문제가 있었다는 뜻으로 해석해야 한다. 개 발자의 능력이 부족해서 실패를 해도 마찬가지다. 적절한 자원을 투입하지 않았기 때문이다. 일정을 만족시키지 못하는 대 부분의 과제는 지나치게 “도전적인” 일정이 차지하고 있으며, 비용 계획을 만족하지 못한 과제는 사전에 필요한 자원을 제 대로 파악하지 못했기 때문이다. 모든 과제에서 요구되는 기능은 언제나 100%다 사용 되지 않는다. 따라서, 이 모든 실패 의 원인은 시스템적인 결함으로 발생하는 결과일 뿐이다. 제대로 된 기획을하고 걸맞는 일정 계획을 만들어 적절한 자원을 투입해 우선순위가 높은 기능을 위주로 구현 했다면, 실패가 발생하더라도 빨리 복구할 시스템을 구축 했을 것이다. 그렇 지 않다는 말은 결국 누군가의 실패(혹은, 오만이나 지나친 강압)로 인해서, 결과만 고스란히 개발자들이 뒤집어 쓰고 있 다는 뜻이 된다. 책임은 과제에 이해를 가지고 있는 모든 사람들이 함께 져야하며, 그래야만 시스템의 실패를 복구 할 수 있는 가능성이 생긴다. 책임을 묻는 자리에서 과제에 영향력을 행사한 사람들이 침묵하는 것은 실패를 자신의 책임으로 인 정하지 않고 남의 탓으로 돌리고 싶어하는 방어 본능일 뿐이다. 성숙한 인간이라면 적어도 자신의 미흡 했음을 남에게 전 가하지는 않을 것이다. 스스로 부족함을 알 때, 진정한 개선을 이룰 수 있다. - 실패는 병가지 상사라고 했던가? 책임 추궁만하는 분위기로는 도전 정신을 발휘하지 못한다.- 3 · [ 프로페셔널 프로그래머 ]
  • 4. 2017/10/12 12:59 http://blog.naver.com/knix008/221115410342 [ 소프트웨어 산업의 본질 - 04 ][ 소프트웨어 산업의 본질 - 04 ] 낙서장(2017)낙서장(2017) 소프트웨어 개발은 비용을 줄이는 전략으로 추진해야 한다. 단순히 빨리 개발하는 것이 아니라, 전체 라이프 사이클을 놓 고 보았을 때, 비용이 적게 들어가는 방향을 선택해야 하는 것이다. 일반적으로 경쟁하고 있는 상황에서 가장 쉽게 선택할 수 있는 것은 “무조건 빨리”가 될 것이다. 하지만, 무조건 빨리에 “무엇을 개발할 것인가”를 명확하게 제한 해야한다. 모든 기능을 무조건 빨리 개발할 것이 아니라, 최소의 필요한 기능을 빠르게 개발하는 것이 필요하다. 즉, 이것이면 충분하다고 생각되는 범위를 정하고, 얼마 정도 기간이 소요되는지 대략적인 목표를 정하는 것이다. 물론, 그렇게 정한 목표라고 해서 반드시 정의된 기간내에 완료된다고 100%보장하지는 않는다. 하지만, 필요하다고 생각되는 모든 기능을 다 구현하는데 필요한 일정 계획을 세우는 것보다는 정확도가 높을 것이다. 따라서, “반드시 가져야할 기능(Must have), 가지면 좋은 기 능(Good to have)”을 잘 정의해야 한다. 비용을 줄이는 전략을 세우기 위해서 입력으로 사용되기 때문이다. 계획을 세웠 다고 끝나는 것이 아니다. 계획을 실행할 때도 마찬가지로 비용을 생각해야 한다. 소프트웨어는 구현하는데 필요한 노력보다 “유지보수”가 비용의 대부분을 차지한다(60%이상). 따라서, 유지보수 노력을 줄이는 구현이 필요하다는 말이 된다. 이를 위해서는 당연히 “모듈화와 계층화”를 따르는 것이 구현 전략이 될 것이다. 모 든 것을 한꺼번에 구현하려고 노력 해서도 안되지만, 그렇다고 아무런 원칙 없이 구현하는 것도 위험하다. 비용이란 결국 무엇을 하는데 얼마나 노력이 드는지를 결정하는 것이다. 초반에 비용을 줄이는 전략의 채택이 만들어진 결과물의 “유지보 수 노력”에 지대한 영향을 주기에, 항상 무엇이 최선인지(무엇이 최대로 비용을 줄이는지) 확인하면서 나아가야 한다. 비 용을 줄이기 위해서는 문제를 빨리 발견할 수 있는 방법을 사용해야 한다. 문제를 나중에 발견하면 비용도 더 들기 마련이 다. 예를 들어, 자동차를 만든다고 할 때(대략 20,000개의 부품으로 조립한다고 하니 충분한 복잡도를 가질 것으로 본다), 조립하는 과정에서 불량을 발견하는 것이 조립이 완료된 후에 불량을 발견하는 것보다 비용이 싸다. 물론, 문제를 찾아내 고 해결하는 동안에 생산이 지연 되기는 하겠지만, 불량품을 생산하는 것은 이익이 아니라 비용만 늘릴 뿐이다. 4 · [ 프로페셔널 프로그래머 ]
  • 5. 비용은 낭비이며, 낭비는 추가적인 시간을 요구한다. 과제가 지연되는 이유를 무엇이라고 보는가? 대부분의 경우 버그 발 생과 밀접하게 관련이 있을 것이다. 그렇다면, 만드는 과정에서 버그를 줄이도록 하는 방법을 연구하는 것이 옳다. 소프트 웨어에서 버그를 줄이는 방법은 이미 많이 연구되어 왔다. 요구사항의 누락이나 잘못된 해석, 아키텍처나 설계 문제의 늦 은 발견, 코딩 단계에서 코드 리뷰와 단위/통합 테스트 누락, 요구사항에 대한 테스트 미비 등등 다양한 것들이 버그의 발 생과 관련이 있다. 따라서, 이런 부분들을 어떻게 해결할 수 있을 것인지 미리 계획해야 한다. 당연히 계획을 실행하는 것 역시 중요하다. 하지만, 계획조차 하지 않거나, 그런 활동들을 할 시간을 계획에 집어 넣지않는 것이 더 큰 문제다. 경험이 많은 사람들은 남들이 이야기하는 방법을 믿지 않는다. 그리고, 자신의 경험이 이야기하는 것이 절대적으로 옳다고 믿는 다. 물론, 그 경험이 잘못된 것은 아니다. 하지만, 스스로 제대로 경험하지 못한 부분까지 생각자체를 거부하는 것은 옳지 않다. 마치 오래동안 인정되어온 방법들이 교과서나 있는 것이고, 학교때 숙제하는 정도에서만 유용한 것으로 생각하는 것 은 잘못이다. 안다고 이야기는 하지만, 실행하지 못하는 지식은 아는 것이 아니라 추측하는 것일 뿐이다. 낭비는 가치를 생산하지 않는 일을 하는 것이다. 따라서, 코드 리뷰나 정적 분석, 단위 테스트를 이용한 모듈 테스트 자동 화, 통합 테스트 자동화 등은 낭비가 아니다. 오히려 그런 활동들을 활성화 시키는 것이 낭비를 줄이는 길이다. 버그를 사 전에 제거할 수 있으며, 변경에 대한 강건성을 지속적으로 유지할 수 있는 방법을 낭비로 취급해서는 안된다. 오히려, 느린 통합, 자동화 되지 않는 테스트와 배포(수동 테스트 및 그 배포), 무의미한 회의 및 보고서 등이 낭비다. 아키텍처를 만들고 디자인 하는 것은 우리가 만들고 있는 소프트웨어가 그만큼 복잡하기 때문이다. 개집을 만드는 사람이 설계도를 필요로 하 지 않을 뿐, 높은 빌딩을 짓기 위해서는 상세한 도면이 필요한 것이 당연한 이치다. 시간이 부족해서 어쩔 수 없다고 이야 기하는 것 자체가 낭비를 부채질하는 것이다. 마치, 문제를 많이 만들어서 나중에 그것을 고치겠다는 것과 다름없기 때문 5 · [ 프로페셔널 프로그래머 ]
  • 6. 이다. 나중에 문제를 고치는 시간을 줄이기 위해서라도 앞 단계에서 낭비를 줄여야 한다. 소프트웨어 개발은 비용을 줄이 기 위해서 투자를 해야하지만, 투자하는 것이 아까워 낭비를 하겠다는 말이 된다. 그리고, 그 낭비는 투자비 보다 더 비쌀 것이 분명하다. 지속적으로 개량해 나가는데 필요한 비용이 끝없이 추가될 것이기 때문이다. 당연히 유지보수 비용도 덩달 아 커질 것이 분명하다. - 소프트웨어 개발의 지름길은 막대한 비용을 지불하도록 요구한다. 생산성을 획기적으로 높이는 도구는 없다.- 6 · [ 프로페셔널 프로그래머 ]
  • 7. 2017/10/13 08:33 http://blog.naver.com/knix008/221116006636 [ 소프트웨어 산업의 본질 - 05 ][ 소프트웨어 산업의 본질 - 05 ] 낙서장(2017)낙서장(2017) 소프트웨어 개발은 기술이 집약된 산업이다. 사람을 많이 투입하는 것이 일정을 단축할 수 있다고 믿는다면, 만드는 품질 보다 만들어내는 양을 중요하게 생각한다는 뜻이된다. 하지만, 코딩양이 많다고해서 그것이 고객이 요구하는 것을 만족 시 킨다고 할 수 없으며, 품질이 높다고도 이야기 할 수 없다. 전통적인 관점에서 생산성은 투입된 자원에 비례해서 생산량이 늘지만, 소프트웨어는 생산된 자원(사람)이 많아지면 오히려 생산성이 줄어드는 효과가 생긴다. 하나의 제품에 대한 생산 은 라인을 늘리고 숙련된 사람을 늘리면 되지만, 하나의 소프트웨어 제품을 만들기 위해서 여러 생산 라인을 만들 수는 없 다. 가능한 경우는 구현할 내용을 분리해서 모듈화 시키는 방법이지만, 이를 위해서는 먼저 역할과 책임을 나누는 활동이 선행되어야 한다. 또한, 전체 구조를 정의한 후에 각각의 세부 사항들을 나누어진 역할과 책임하에 구현되어야 한다. 구현 과정에서 다양한 협업이 발생하며, 어떤 한 부분이 빠르게 개발된다고 해서 전체 시스템의 개발 생산성이 그것에 맞춰지는 것도 아니다. 우수한 팀과 그렇지 못한 팀 간의 생산성도 크게 차이가 나며, 우수한 인력과 그렇지 못한 인력의 생산성도 마찬가지다. 어떤 자원(사람은 자원이 아니지만)을 사용하느냐에 따라 과제의 품질과 개발의 속도가 크게 달라지기에, 기 술이 탁월한 인력을 꾸준히 유지할 수 있는 방법을 찾는 것이 소프트웨어 개발에서 경쟁력을 가지는 방법이다. 그렇지 못 한 조직은 지속적인 저 품질 비용의 증가로 인해 시장에서 얻을 수 있는 이익이 줄어들 수 밖에 없다. 소프트웨어는 결국 사람이 만든다. 사람이 늘어나면 대화해야할 대상이 늘어나게 되며, 소통 오버헤드 및 사람 사이의 동 기화 비용도 커진다. “책임의 분산”도 문제가 될 수 있다. 즉, 모두의 책임이 되면 누군가의 책임을 묻지 못하게 되며, 그것 으로 인해 개인이 가진 최고의 역량을 발휘하지 않는 상황이 된다. 멀티 코어를 사용할 때, 코어의 수 만큼 성능이 개선되 지 않는다는 사실은 다 알것이다. 제대로 코어를 활용한 코드를 만들지 않는 경우와 코어 간에 동기화된 접근으로 인해 오 버헤다가 코어의 수가 증가함에 따라 급속도로 늘어나기 때문이다. 기계가 이런 상황이라면 사람 사이의 일은 더 크게 숫 자에 민감할 수 밖에 없다. 한 사람 한 사람의 역량이 100이라고 했을 때(물론, 역량은 측정하기도 힘들고 같을수도 없지 만), 그 사람들의 역량을 다 더한 후 사람의 수로 나누면 100이 되지 않는 것이 “책임의 분산” 때문이다. 대화에 대한 오버 헤드와 책임의 분산으로 인해 발생하는 비용은 개발 시간의 상당 부분을 차지하게 되며, 미리 대비하고 잘 설계된 역할과 책임의 분산이 없다면 오히려 개발 기간은 인력의 수에 비례해서 조금씩 늘어나게 된다. 심지어 개발 기간의 중간에 투입 된 인력이 있다면, 기존의 결정과 코드 및 문서들을 읽기 위한 시간도 추가되며(학습을 위한 시간), 기존 인력들이 신규 인 력을 도와주는 시간도 오버헤드에 포함되어야 한다. 따라서, 지연되고 있는 과제에 사람을 더 투입하는 것이 역효과를 내 는 것이다. 물론, 전통적인 관점에서는 사람을 더 투입하면 더 많은 생산량을 만들 수 있다고 보겠지만, 소프트웨어는 복잡 한 지식을 효과적으로 다루는 방법에 대한 것이기 때문에, 사람의 수와 생산성이 비례 관계를 이루지 못하는 것이다. 7 · [ 프로페셔널 프로그래머 ]
  • 8. 사람을 중요하게 생각하지 않는 회사는 경쟁력을 상실한다. 모든 회사는 “인재가 자산”이라는 말을 하지만, 그 말을 지키 는 회사는 드물다. 인재는 자산이지만 오버헤드로 취급하는 것이 일반적이다. 가능한 이익을 크게 하기 위해서는 갑 싼 인 력을 많이 채용해서 빨리 물건을 만들라고 요구하는 것이 일반적이다. 소프트웨어 개발비의 대부분은 사람에 대한 인건비 이기에, 비싼 인력이 놀고 있는 꼴을 결코 좌시하지 않는다. 하지만, 일은 자신이 가진 최대 역량을 100%발휘해야 탁월한 품질을 가지는 것이 아니다. 그리고, 100% 노력이라는 것도 측정할 수 없는 수치다. 사람은 한계를 정하면 그 만큼만 노 력하거나, 혹은 한계 자체가 자신이 생각하는 도달 가능한 목표 수준으로 설정한다. 따라서, 사람이 가지는 내재된 역량을 완전히 발휘하는 것은 불가능한 목표일 수 밖에 없다. 바쁘게 일하는 것이 그 사람의 모든 역량을 뽑아쓰는 것이라고 생각 하는 관리자들은 될 수 있으면 많은 일을 시키려고 애쓴다. 야근과 특근 시간 통계를 내서 관리하는 것이 가장 손쉬운 “노 력을 측정하는 도구”로 생각하고 있으며, 일정 준수만이 모든 과제의 목표로 지정하고 있기 때문이다. 살아남는 것이 목표 인 상황에서는 그럴수도 있을 것이다. 제대로 알지 못하는 것을 측정하려고 애쓰기 보다 눈에 보이는 것만 측정하면 되기 때문이다. 하지만, 그것이 경쟁력을 강화시켜주거나 시장에서 제품의 성공을 보장해주지는 못한다. 결국 지식 집약적인 기 술의 회사가 되지 못하면, 차별화는 없어지고 잡다한 기능의 합집합만 있을 뿐이다. 기능이 많다고 팔리는 제품보다 필요 한 기능의 품질이 우수한 제품이 성공하는 이유가 거기에 있다. 사람이 중요하다면 시간이 아닌 품질을 강조해야 한다. 양 을 강조하면 품질은 낮아질 것이고, 품질을 강조하면 자연스럽게 속도도 빨라지게 될 것이다. 소프트웨어 개발은 품질이 속도를 대변한다. 저품질이 비용을 발생시키며, 재작업이 대부분의 비용이다. 따라서, 재작업이 없는 제품을 만들기 위해서 과정에서 만들어지는 산출물의 품질을 높여야 한다. 품질이 나쁜 상태로 최종 단계에 이르게 되면, 당연히 재작업 양은 늘어나게 된다. 이미 조립된 상태에서 품질 수준을 높이는 일은 “현상만 완화시키는” 단기적인 대책을 만들 뿐이다. 문제는 상황이 조금만 바뀌어도 재발할 것이며, 문제를 다루는 사람의 역량에 따라 비용도 추가될 것 이다. 이런 식의 개발이 지속되면 신제품을 개발하는 속도에도 영향을 주게된다. 대부분의 소프트웨어 개발 회사는 신제품 개발 인력과 기존 제품 지원 인력에 구분을 두지 않고 있다. 따라서, 기존 제품의 문제는 신제품을 개발하면서 같이 처리 해야 하는 상황이다. 문제점이 많은 제품을 지원하기 위해 신제품 개발이 지연되는 현상이 지속해서 발생하게 된다. 고객 8 · [ 프로페셔널 프로그래머 ]
  • 9. 은 점차 약속한 일정에 대해서 의미를 두지 않게되며, 언제든 대체할 수 있는 다른 제품을 찾아 나서게 된다. 이런 상황에 서 유일한 해결책은 사람을 추가하는 것이지만, 값싼 인력은 많지만 제대로 된 인력은 찾아보기 힘든게 소프트웨어 업계의 현실이다. 또한, 제품의 수가 늘어나면 지원해야 할 제품도 많아지게 되며, 비례해서 인력의 수도 같이 늘어나는 빈익빈 현상이 되고만다. 매출이 늘어나더라도 이익이 늘어나지 않는 구조가 되고마는 것이다. 만약, 시장에 탁월한 경쟁자가 나 타난다면, 쉽게 경쟁력을 상실할 우려가 생긴다는 말이다. 품질을 높이는 것이 결국 시장에서 성공하는 길임과 동시에 속 도면에서도 경쟁력을 가지는 것이다. 소프트웨어 개발은 고품질을 만들기 위해서 속도를 희생해야 하는 것이 아니라, 품질 을 높이는 것이 속도를 보장해주는 분야라는 것을 이해해야 할 것이다. - 소프트웨어 개발은 사람에 의존한다. 하지만, 그것을 이겨내는 것이 상향 평준화를 이루는 길이다.- 9 · [ 프로페셔널 프로그래머 ]
  • 10. 2017/10/13 13:06 http://blog.naver.com/knix008/221116186429 [ 소프트웨어 산업의 본질 - 06 ][ 소프트웨어 산업의 본질 - 06 ] 낙서장(2017)낙서장(2017) 소프트웨어 개발은 고품질이 저비용이다. 여기서 말하는 비용이란 결국 일정의 지연을 의미한다. 즉, 저품질로 인해서 발 생하는 비용의 대부분은 과제의 지연이나 버그 수정 혹은 기능 추가의 지연을 의미한다. 일정이 지연되는 동안 사람에 대 한 인건비는 지출되어야 하며, 만회하기 위해서 추가되는 인력이나 근무시간의 연장 역시 비용의 추가로 이어지기 때문이 다. 교통비 몇 푼이면 충분하다고 생각할지도 모르지만, 근무시간의 연장은 결과적으로 근무 시간중에 만들어지는 제품의 품질이나 생산성에 영향을 주게된다. 결과적으로 절대 성공적으로 제품의 품질 수준을 정해진 일정 내에(혹은, 요구된 일 정에 따라) 만족시킬 수 없는 상태가 지속될 뿐이다. 소프트웨어 개발에서 말하는 고품질은 완벽하게 버그가 없다는 것을 증명하는 것이 아니라, 알려진 버그가 없다는 것을 의미한다. 따라서, 최대한 검증력을 확보해 가면서 검증 주기를 자주 가 져야하며, 검증의 범위도 높여야 한다는 의미다. 100% 완벽한 소프트웨어가 없더라도 대부분의 버그는 사전에 제거할 수 있으며, 그 비용도 비싸지 않다는 것을 이해해야 한다. 예를 들어, 자동화된 테스트를 만들 수 있는 시간이 없다고해서 수동 테스트만 고집한다면, 사람의 인건비에 대한 낭비만 초래할 뿐이다. 테스트 자체를 쉽게 하기 위한 방법도 설계와 구 현에서 필요한 요구사항 이기에, 코딩 업무에 “해야할 일”로 취급 되어야 한다. 과정의 품질을 높이면 최종 품질 수준도 높 아지며, 더 적은 노력으로 더 많은 일을 할 수 있는 상황이 될 것이다. 소프트웨어는 한번 만들 때 제대로 만들어야 한다. 나중에 고치면 된다는 생각은 버리는 것이 좋다. 그렇다고 완벽한 소프 트웨어를 만들겠다고 지나치게 기준을 높여도 안된다. 적당한 수준의 비용은 감수를 할 수 있지만, 그 비용이 지나치게 높 아지는 것을 경계해야 한다는 뜻이다. 코드가 많아지면 버그는 자연스럽게 늘어나기 마련이고, 버그는 코드의 복잡도와 밀 접한 관련을 가진다. 따라서, 복잡도가 지나치게 높아지는 것을 관리할 수 있는 방법을 체계적으로 실행해야 한다. 복잡도 는 논리적인 것이 있지만, 물리적인 것이 관리하기 쉽다. 물리적인 의존 관계를 모아서 관리해야 하며 될 수 있으면 낮은 수준으로 유지해야 한다. 논리적인 분기도 가능한 줄이는 것이 좋다. 내구 구조에 대한 의존은 낮추고 인터페이스에 의존 하게 만들어야 한다. 이해하는데 어려운 부분을 개선하는 것도 복잡도를 낮추는 것이다. 각종 소스 코드에 등장하는 객체 (Object : 변수, 함수, 상수, 파일, 디렉토리 등등)들은 적절한 이름을 가질 필요가 있는 것이다. 이 모든 것이 사람의 이해 를 돕는 방법을 구현되어야 한다. 이미 구현된 코드를 개선하는 것은 어렵기 때문에, 코드가 만들어지는 순간부터 개선 작 업도 함께 시작해야 한다. 모든 코드는 생성되는 순간부터 유지보수에 들어간다고 보는 것이 옳다. 통합과 테스트는 자주 할수록 비용이 적게 든다는 것도 알아야 한다. 고품질을 유지하기 위해서는 일정 비용이 들어가는 것을 감수할 수 밖에 없 다. 지나치게 들어가는 비용은 경계해야 하지만, 적절한 투자는 항상 미래에 위해서 필요한 부분이다. 10 · [ 프로페셔널 프로그래머 ]
  • 11. 고품질로 만들어진 소프트웨어는 유지보수 비용이 낮을 수 밖에 없다. 새로운 기능을 추가하거나 기존 버그를 수정하는데 필요한 시간도 단축된다. 당장 비용을 줄이고 싶다고 하더라도 가치를 만들어 낼 수 있는 투자는 해야하는 것이다. 간혹, 비용과 투자를 혼동하는 사람들이 있으며, 투자가 필요 없다고 믿는 사람들도 있다. 그들이 보는 시각은 항상 "바쁜일과 현 재"만 초점을 두고 있기에, 미래에 어떤 일이 생길지는 예상하지 못한다. 투자가 없으면 개선도 없다. 그리고, 그렇게 만들 어진 코드는 지속적인 유지보수 비용 발생의 원인이 된다. 저품질로 인해서 발생하는 비용은 문제를 찾아내는 단계가 늦어 질수록 더 비싸진다. 고객에게 배포된 이후에 발견되는 버그는 수정을 위해서 막대한 비용을 지불해야 할수도 있다. 개발 팀의 목표는 과제를 완료하는 것이 아니라, 제품이 시장에서 오래동안 살아남는 것 이어야 한다. 소프트웨어는 하드웨어와 달리 지속적인 변경을 요구하며, 그 변경을 통해서 꾸준히 생명력을 유지한다. 따라서, 변경을 쉽게 받아들일 수 있는 구조 를 만들지 않는다면, 변경 자체가 추가적인 비용으로 지출 요인이 되는 것이다. 고품질은 그런 비용을 줄일 수 있는 방법이 며, 빨리 만드는 것으로는 고품질을 달성하지 못한다. 빨리 만들면서 고품질을 달성하기 위해서는 반드시 "자동화된 테스 트"를 가져야만 한다. 자주 통합하고 테스트 하기 위해서는, 그 때마다 추가되는 기능과 모듈 들에 대한 검증력을 높여야 하기 때문이다. 자동화된 테스트를 만들기 위해서 필요한 것은 상품화에 들어가는 코드만이 전부가 아니다. 물론, 이런 부 분들을 오버헤드라고 생각한다면, 다른 고품질을 달성하기 위한 활동들은 사람에 의한 노력에 전적으로 의존하게 된다. 모든 투자가 가치를 만드는 것은 아니다. 하지만, 투자해야 할 시기를 놓치면 다시하기 힘든 것이 있다. 소프트웨어 개발은 초기부터 일정 부분 투자해야 할 항목을 정하고 시작해야 한다. 100이라는 노력을 투자할 수 있다면, 적어도 30이상의 노력은 산출물의 품질을 높이는데 투자되어야 한다. 모든 노력이 코딩에만 쏠리게 되면, 다른 투자해야할 부분들이 빚으로 남게된다. 빚이 쌓이면 지불능력을 상실하는 때가 오게되며, 그때는 새로 개발하는 것보다 못한 상태가 된다. 과거의 유산 에서 자유롭지 못한 상태가 되면, 앞에서 투자 했어야 할 노력보다 더 많은 노력이 개선에 투자해야 하는 상황이 되고 만 다. 물론, 좋다는 것은 안다고 이야기를 하지만, 아는 것에서 끝나고 마는 것이 현실이다. 투자를 생략한다면 처음에는 빠 른 것 처럼 보일지도 모른다. 하지만, 목표에 다가갈수록 점점더 생산성은 낮아질 것이며, 해결해야 할 문제들은 더 빠르게 늘어난다. 이를 극복하기 위해서 단기 처방전을 사용하는 것이 그 때로서는 최선이지만, 말 그대로 단기적인 대안일 뿐이 다. 개발자들은 개발이 한참 힘든 순간이 되어서야 후회하게 되고, 다음 프로젝트에서는 반드시 개선하겠다고 마음 먹는 11 · [ 프로페셔널 프로그래머 ]
  • 12. 다. 하지만, 그런 기회는 절대 다시 오지 않는다. 그때 못했던 것은 나중에도 하지 못한다. 소프트웨어 개발이란 한번 만들 어진 제품은 계속 유지 보수를 해야하며, 완전히 다른 제품으로 변경하지 않는한 문제는 끊임없이 해결해 주어야 한다. 다 시 말하면, 문제를 해결하느라 새로운 과제를 하더라도 시간이 부족하게 될 것이 분명하기 때문이다. 관리자는 개발자가 절대 노는 꼴을 보지 못하며, 유지보수나 구조 개선 작업, 테스트 자동화 등은 코드를 개발하는 것보다 우선 순위가 낮다고 보는 것이 일반적이다. - 저품질이 지연의 주된 이유다. 나머지는 관리자의 “도전적인 계획”에서 원인을 찾아야 한다.- 12 · [ 프로페셔널 프로그래머 ]
  • 13. 2017/10/16 08:56 http://blog.naver.com/knix008/221117895666 [ 완벽보다 최선을 선택하라. ][ 완벽보다 최선을 선택하라. ] 낙서장(2017)낙서장(2017) 어느 회사를 가더라도 소위 말하는 “꼴통”은 항상 있다. 높은 역량을 가진 사람들로만 채워진 조직에서 일하더라도, 수준이 낮은 사람은 존재하며 열심히 노력하지 않는 사람들도 항상 있기 마련이다. 사람은 완벽한 존재가 아니며 완벽하려고 노 력은 할 수 있지만 목표에 도달한 사람은 아직 없다. 우리가 할 수 있는 최선이란 것 자체가 정의할 수 있는 성격의 것이 아 니며, 매일 매일 조금씩 더 나아지려고 노력할 뿐이다. 소프트웨어 개발도 마찬가지다. 완벽한 소프트웨어는 존재하지 않 으며, 완벽에 가깝도록 만들려는 의지만 있을 뿐이다. 누군가 100% 무결한 소프트웨어를 만들었다면, 이미 거짓말을 하 고 있다는 것을 쉽게 알 수 있다. 사람이 완벽하지 않은데 만들어진 제품이 완벽할리가 없다. 따라서, 적당한 취약점은 인 정할 필요가 있다. 물론, 그 약한 부분이 유난히 다른 것에 비해서 드러나 보인다면 문제가 될 수 있지만, 그렇지 않다면 어 느정도 감수하고 나아갈 수 밖에 없다. 완벽하려고 더 많은 시간과 노력을 투자하기 보다, 완벽하지는 않지만 쓸만한 소프 트웨어를 만드는 것을 목표로 삼아야 한다. 노력이나 투자 자체가 없다면 문제가 있다고 볼 수 있으며, 30%이상의 노력이 소모되고 있는 것도 경계해야 한다. 자신이 해야할 일을 70%정도 하고 있다면, 한 일을 정리하는데 필요한 노력도 투자 하는 것이 옳다. 100%의 노력이 어느 정도 인지 모른다면, 하루 2시간을 넘지 않는 선에서 기존의 노력에 대한 정리 작업 을 하는 것이 좋을 것이다. 하지만, 직급이 낮거나 혹은 권한이 없는 경우에는 이 정도의 시간을 투자하는 것도 무리가 있 다. 따라서, 이때는 드러나지 않게 개선 활동에 투자하는 시간을 만들어야 한다. 실제로 높으신 분들은 구체적인 일은 잘 모른다. 뭔가 열심히 하고 있는듯이 보이기만 한다면, 특별한 간섭은 피할 수 있을 것이다. 이런 것들이 귀찮다고 생각한다 면, 자신을 위한 투자라고 생각해 볼 수도 있다. 그리고, 그 투자의 결실은 결국 돌아오기 마련이다. 완벽에 가까운 소프트웨어를 만드는 것은 가능하다. 예를 들어, 모든 제어 경로를 실행해 볼 수 있다. 하지만, 그것 자체가 너무 많은 시간과 노력을 필요로 하기에, 적절한 수준에서 제어 경로를 실행해 볼 수 있어야 한다. 작은 단위에서 전체 경 로를 실행하는 것은 가능하지만, 통합된 코드에서 모든 경로를 실행해보는 것은 예외까지 포함하기에 투자 대비 성과가 나 오지 않는다. 해볼 수 있는 방법은 작은 단위의 실행 경로에 대한 검증을 높이는 동시에, 통합된 수준에서는 주요 시나리오 및 예외 상황에 대한 검증을 해보는 것이다. 물론, 이를 위해서 미리 정의된 아키텍처와 디자인을 가지고 있는 것이 유리 하다. 즉, 검증 자체를 편하게 만들기 위한 구조를 미리 통합된 코드 내에 포함하고 있어야 한다. 그렇지 않다면, 자동화된 실행 자체가 어려울 수 있다. 만드는 것보다 검증이 힘들어지는 이유는 초기 투자의 부족을 나중에 복구 하려고 하기 때문 이다. 따라서, 초기에 조금만 신경써서 필요한 요소들을 미리 반영할 수 있다면, 생각보다 쉽게 자동화된 검증을 진행할 수 있다. 예를 들어, 버스(Bus)구조와 같은 것을 통해서 서로 통신하는 시스템의 객체들을 정의했다면, 테스트를 위한 에이 전트(Agent)를 이용해서 각각의 시스템 객체들을 나누어서 검증할 수도 있을 것이다. 물론, 이와 같은 노력이 의미를 가 지기 위해서는 상당 시간의 노력이 필요하다. 팀원들과 리더를 설득하려는 대화도 필요할 것이다. 거부감을 가지는 팀원들 도 있을 것이고, 과제 일정 지연에 대한 우려를 표하는 과제 담당자도 있을 것이다. 그런 모든 것들을 다 극복하는 것이 어 려울 수 있기에, 가능한 같이 할 수 있는 사람을 먼저 만드는 일이 필요하다. 이도 저도 안된다면, 혼자서라도 자신의 코드 13 · [ 프로페셔널 프로그래머 ]
  • 14. 만큼은 자동화된 검증을 할 수 있도록 만들어야 할 수도 있다. 어쨌든 그런 경험을 통해서 남보다 한 발짝 더 나아갈 수 있 다는 것은 분명하다. 대체로 경험이 많은 사람일수록 새로운 것을 받아들이는 속도나 늦다. 이것은 어쩔 수 없는 일이다. 새로운 경험이 기존의 경험과 반대되는 성향이 짙을수록 거부감은 더 커진다. 따라서, 이 떄는 먼저 보여주기를 선택하는 편이 좋을 수도 있다. 보지 않으면 믿지 않는 것이 대부분의 사람들이 가지는 태도다. 특히, 기존 경험이 있는 사람의 경우에는 직접적인 증거를 제시 하더라도 믿지 않을 가능성이 높다. 이유는 단순하다. 자신의 생각과 다르다고 느끼기 때문이다. 생각이 다르면 자신 의 권한이 축소될 위험이 있으며, 지금까지의 경험이 옳지 않다고 판단되는 결과를 만들고 싶지 않을 것이다. 일종의 불안 감이 뒤섞인 인생 경험의 부정을 취하기 때문에, 거부할 수 있는 모든 이유를 가져다 붙일 수도 있다. 이런 상황이라면 굳 이 부딪혀서 해결할 필요가 없다. 시간이 흘러 변화를 시도할 수 있는 때를 기다리며, 개인의 역량을 키우는 것을 차선으로 선택할 수 있다. 물론, 그렇다고 그 시간이 마냥 즐거울 수 만은 없을 것이다. 그렇다고 “아니오”라고 말하는 것도 조직에 서 “왕따”가 될 가능성이 있기에 바람직하지는 않다. 먼저 살아남는 것이 목표이며, 그 후에 자존심을 챙겨야 할 수도 있 다. 이런 저런 것들을 따지고 싶지 않다면, 자신의 의견이 받아들여지는 팀을 찾아보는 것도 좋을 것이다. 모든 일이 경험 보다 중요한 것은 방향이다. 잘못된 방향으로 아무리 많은 지식이나 경험을 쌓아봐야, 잘못된 결과만 반복해서 만들어낼 뿐이다. 경험이 많다는 것은 선택할 수 있는 폭을 줄이는 효과도 가지기 때문에, 주의해서 새로운 것들을 검토해야 한다. 만약, 자신이 잘못된 생각을 가지고 있다고 판단될 때는 겸허히 사실을 받아들이는 자세도 필요하다. 물론, 가장 힘든 일이 그런 것을 인정하는 것이지만, 그래도 더 잘못되기 전에 바로 잡는 것이 조금이라도 좋은 결과를 만들어 낼 수 있다. “아니 다”라고 생각될 때는 미련을 두지 말아야 하며, 무엇이 올바른 것인지 알기 위해서 일단은 모든 선입견을 내려놓아야 할 것 이다. 혼자서 일을 할 때도 기준은 정해야 한다. 이때 위안으로 생각해 볼 수 있을 정도의 수준을 만족시키기 위해서는 다음과 같 은 것들을 잣대로 삼아야 할 것이다. 하드웨어 성능으로 도달할 수 있는 목표의 80%이상, 독립적으로 실행될 수 있는 부 분이 최대 길이를 100라인 수준으로 정하기, 객체 지향 언어를 사용할 경우 클래스의 크기를 1,000라인 이하로 유지하 기, 단위 테스트 커버리지를 함수에 대해서 95%, 라인에 대해서 85%, 분기에 대해서 75%이상 가져가기, 복제된 코드 14 · [ 프로페셔널 프로그래머 ]
  • 15. 의 비율은 1%미만으로 하기, 함수의 파라미터 수가 5개 이상인 비율을 1%미만으로 만들기, 조건문의 중첩 수준이 3단 계 이상인 코드를 5%이하로 유지하기 등등, 다양한 100%가 아닌 것들을 만들어서 적용하는 것이다. 기준이 없으면 일 하는 것은 힘들다. 성과를 높이기 위해서는 측정해야 하며, 그것을 기준으로 얼마나 더 나아갈지 결정해야 하기 때문이다. 단순히 “잘, 많이, 더, 열심히, 꾸준히, 성과”아 같은 단어를 사용하는 것으로는 객관적인 잣대를 만들 수 없다. 대부분의 목 표가 형용사나 부사같은 말의 연속이라면, 결과는 이미 정해진 것이나 다름 없다. 즉, 할 수 있는 시간적인 여유가 있을 때 해보겠다는 말이 된다. 당연히 시간이 없으면 대충 마무리 할 것이 분명하다. 이런 식의 일이 반복되는 이유는 “기준”을 명 확히 제시하지 않기 때문이다. 개인이 어떤 일을 혼자서 하더라도 피드백(Feedback)을 적절히 얻어야 동기유발이 될 수 있다. 목표가 되는 기준을 만들었다면, 무슨 일이 있더라도 반드시 하겠다는 의지가 있어야 한다. 의지는 가지고만 있어선 안되고, 실행에 투입되어야 한다. 따라서, 하루 일과의 일부를 반드시 그 일을 하는데 집중할 필요가 있다. 그것이 반복되 면 결국 의지 자체가 노력과 자동으로 연결되며, 노력 자체가 습관화 될 것이다. 변화는 작은 것이라도 꾸준히 실천하지 않 으면 결과로 드러나지 않는다. 혼자만이라고 느낀다면 그 결과의 변화를 통해서 옆의 동료들과 대화를 나눌 수 있는 근거 자료를 만들 수 있을 것이다. 비록 완벽하지는 않을지라도 그 노력의 결과 만큼은 부정하지 못할 것이다. - 완벽하려고 노력은 하되, 완벽 자체에 집착하지 말라.- 15 · [ 프로페셔널 프로그래머 ]
  • 16. 2017/10/17 11:35 http://blog.naver.com/knix008/221118823020 [ 설계 품질이 결과를 좌우한다. ][ 설계 품질이 결과를 좌우한다. ] 낙서장(2017)낙서장(2017) 소프트웨어 아키텍처는 시스템을 구성하는 요소와 그들간의 관계 및 구성 요소 및 관계의 속성을 정의한다. 따라서, 요구 사항을 만족시키기 위한 구성 요소 및 관계의 정의를 포함하고 있어야 아키텍처라고 부를 수 있다. 대부분의 개발자들이 만드는 설계는 요구사항의 일부분에 한정해서 관련이 있으며, 기술적인 부분에 지나치게 치중하는 경향이 있다. 이는 아키 텍처 설계의 대부분의 과정이 고객과 동떨어져서 진행되며, 고객이 이해하는 언어로 작성되지 않기 때문이다. 이런 부분들 을 극복하기 위해서는 고객의 설명을 자세히 들어야하며, 될 수 있으면 고객의 언어를 이용해서 비지니스의 핵심이 되는 부분에 대한 설계를 진행해야만 한다. 개념의 차이가 발생하는 이유는 다른 언어의 사용과 같은 언어를 사용하더라도 상황 (Context)에 따른 의미 차이를 이해하지 못하기 때문이다. 따라서, 이런 부분을 해결하지 않는다면, 아키텍처 설계는 고객 의 진정한 요구(Needs)를 만족시키지 못할 가능성이 높다. 고객에는 외부의 사용자만 포함하는 것도 아니며, 가장 가까운 관계는 동료 개발자도 될 수 있다. 또한, 과제에 이해 관계를 가지고 있는 모든 사람을 대상으로 해야하는 것이 옳다. 이런 사람들의 요구가 서로 상충하는 부분이 있기에, 대화와 타협을 통해서 적절한 트레이드 오프(Trade-Off)를 취해야 하는 것은 당연한 일이다. 또한, 요구사항에는 성능만 포함되는 것이 아니라, 이식성, 테스트 용이성, 사용성, 보안성, 변경 용이 성 등과 같은 추가적인 것들도 같은 중요도로 다루어야 한다. 대체로 대부분의 개발자는 “성능”에 몰입하는 경향이 있지 만, 성능을 갖추기 위해서 희생되는 다양한 “비기능 요구사항”들은 시스템을 운영 유지 보수하는데 필요한 비용 발생의 원 인이 되기도 한다. 따라서, 아키텍처 설계는 이런 부분들도 고려해서 적절한 결정을 내려야 하며, 결정에 대한 근거를 명확 히 하는 근거가 될 수 있다. 단순히 설계만 하고 구현이 설계를 따라가지 않는다면, 이것 역시 대화의 단절과 요구사항 구 현의 부정확성만 키우게 될 것이다. 문서화는 복잡하고 어려운 일 일수록 더 필요하게 되며, 재활용이 많거나 단순한 과제 라면 간단한 설계만으로도 충분하다. 적절한 선택에 대한 가이드라인은 없지만, 그렇다고 아키텍처의 품질을 평가하지 못 할 이유도 없다. 설계의 품질이 결국 산출물의 품질과 연결되기 때문에, 검토 및 검증은 설계에 대해서도 유효하다는 것이 다. 설계가 복잡하면 구현도 복잡해 지고, 당연히 버그도 많이 발생한다. 실수를 할 가능성이 높다는 뜻이다. 처음부터 복잡한 것은 없지만 간단한 생각이라고 하더라도 추가되고 변경되면 복잡한 일이 되고 만다. 사실 복잡한 문제를 복잡하게 해결하 려고 노력하는 것은 어리석은 생각이다. 처음부터 모든 상황을 고려해서 만드는 것은 불가능한 일이며, 가능한 간단한 해 결책을 먼저 생각한 후에 조금씩 일반적인 상황에 맞춰나가야 한다. 물론, 일을 통해서 얻게되는 지식이 늘어나면, 특별한 상황에서 어떻게 처리해야 될지 결정해야 하는 부분들이 있다. 하지만, 일단은 가장 간단한 해결책 부터 고민하는 것이 일 의 시작이다. 설계를 위해서는 시스템을 구성하는 요소들을 판별해내야하며, 이는 대부분 명사의 형태로 존재하는 것들이 다. 모든 명사가 해당되는 것이 아니라, 핵심에 해당하는 부분부터 골라내는 것이 필요하다. 그외의 것들은 나중에 생각하 도록 한다. 이때 조심해야 할 것은 미리 구현을 생각해서 용어를 복잡하게 만드는 것이다. 단순히 하나의 시나리오에 기반 해서 그것에만 집중하는 것이 일을 간략하게 만드는 방법이다. 모든 것을 고려해서 좋은 것을 만들기는 어렵지만, 하나의 16 · [ 프로페셔널 프로그래머 ]
  • 17. 상황과 사용 시나리오만을 고려해서 설계하는 것은 어렵지 않을 것이다. 문제는 그 하나의 시나리오가 무엇이냐에 달려있 다. 핵심이 되는 시나리오를 선택하기 위해서는 사용자가 가장 많이 사용하는 기능에 초점을 맞출 필요가 있으며, 시간의 흐름에 따라 어떤 결정과 동작(혹은 이벤트)이 발생하는지 보도록 한다. 그것에 맞춰 고객이 원하는 기능을 만족시키기 위 해서 비지니스 로직에 필요한 구성요소를 판별하면 될 것이다. 기술적인 부분은 세부 설계나 시스템의 인프라 측면을 고려 할 때 하도록 하고, 일단은 고객이 사용하는 언어와 업무 프로세스(혹은, 동작 방식)를 이해하고, 필요한 구성요소들 간의 관계를 정의하는 것을 선행해야 할 것이다. 대표 시나리오 몇 개만 잘 구성할 수 있다면, 나머지 추가되는 시나리오는 연결 고리의 형태로 수평적인 확장을 통해서, 혹은 하위 시나리오의 형태로 설계해 나갈 수 있을 것이다. 설계 품질을 높이기 위해서는 요구사항의 수집과 분석이 선행되어야 한다. 어떤 일을 해야하는지 모르는 상황에서 내리는 결정은 오류가 있을 수 밖에 없다. 결정할 수 없는 것들은 결정을 미루는 것이 최선일 수 있다. 혹은, 알고 있는 부분에 한 정해서 결정하는 것이 좋다. 나중에 더 많은 정보를 얻게 된다면 그 떄 결정하는 것이 효과적일 것이다. 일단은 아는 내용 부터 명확히 결정해 나가는 방식을 취해야 할 것이다. 요구사항을 수집하는 과정이 없거나, 혹은 요구사항이 늦게 주어지 는 경우도 있다. 즉, 아키텍처를 설계하는 과정에서 요구사항의 수집이 제대로 되지 않을 가능성이 크며, 고객의 변심이나 추가적인 기능으로 인해서 아키텍처 자체를 변경해야 할 경우도 생긴다. 이를 위해서는 가능한 자세한 설계나 구현은 나중 으로 남겨두어야 할 것이다. 물론, 이것 조차도 불가능한 경우도 있다. 예정된 날짜에 결과물 제출을 요구받을 때이다. 이 떄는 설계된 부분에 대해서 명시적으로 결정되지 않았다고 기록을 남겨야 할 것이다. 부족한 설계의 결과물이 구현으로 연 결되지 않도록 만들기 위해서는 반드시 설계를 평가해야 한다. 따라서, 아직 정의되지 않은 기능이나 비기능 요구사항들에 대해서 미리 구현하는 것은 변경을 각오해야 할 것이다. 사실 이런 부분도 개발에서는 어쩔 수 없는 부분으로 받아들이는 경우가 많다. 과제 일정이 한정된 경우에는 어떤 식으로든 구현 단계로 진행할 수 밖에 없는 상황이 발생하는 것이다. 하지 만, 구현에서 변경이 가능하도록 만들기 위해서는 설계에서 불변인 부분과 그렇지 않은 부분을 명확하게 구분해 주어야 한 다. 그렇지 않다면 변경은 제어할 수 없는 수준에서 발생하게 되며, 결과적으로 과제 지연이 어쩔 수 없이 발생하기 때문이 17 · [ 프로페셔널 프로그래머 ]
  • 18. 다. 요구사항을 수집하는 다양한 방법들이 있지만, 실제로 고객(실 사용자)을 만나서 이야기하는 경우는 드물다. 가능하면 고객이 참여하는 것이 좋지만, 참여했을 때도 고객의 언어를 개발자가 이해하지 못하거나, 혹은 개발자의 언어를 고객이 이해하지 못하는 상황이 생긴다. 따라서, 요구사항 수집 활동은 고객의 언어를 사용하는 것을 우선해야 할 것이다. 분석도 마찬가지로 가능한 고객의 언어와 가깝게 하거나, 혹은 언어 사용에 대한 용어집을 만들어두는 것이 좋을 것이다. 이떄도 마찬가지로 구현에 필요한 언어는 상세 설계로 미루는 것이 좋을 것이다. 설계는 경험과 지식의 산물이지만, 지속적인 학습과 개선으로 수준을 높일 수 있다. 설계는 뛰어난 몇 사람에 의해서 주도 되는 활동이지만, 그렇다고 그 몇 사람에게만 한정하는 것은 좋지않다. 구현을 할 사람들이 이해하지 못하는 설계란 읽혀 지지 않는 문서와 다름없다. 그냥 한번 만들고 다시 뒤돌아 볼 일이 없기 떄문이다. 지속적인 학습과 개선이 가능하기 위해 서는 구현과 설계가 완전히 분리된 과정이 되어서는 안된다. 구현도 경험과 지식의 축적이 필요한 부분이며, 그것을 통해 설계가 제대로 되었는지 확인할 수도 있다. 따라서, 경험과 지식이 늘어나면 설계도 그것을 반영하기 위해서 더 정교하게 변화해야 한다. 제대로 알게되는 지식을 반영하는지 보기 위해서는 설계 문서의 갱신 날짜를 보면 된다. 즉, 계획된 산출물 로 등록된 이후에 변경이 없다면, 설계는 이미 “죽은 문서”밖에 되지 않는다는 말이다. 지속적인 개선이란 “살아있는 피드 백 루푸(Feedback Loop)”를 통해서만 가능하며, 변화가 없다는 말은 관리하지 않는 말과 동일하다. 따라서, 잘못된 설계 가 있다고 하더라도 구현에는 반영되었을지 몰라도, 설계에는 반영되지 않았을 가능성이 높다. 상세 설계를 하는 과정도 마찬가지다. 아키텍처 수준에서 설계한 내용이 옳지 못하다고 판단될 때는 그것을 개정할 수 있어야 한다. 상세 설계의 수 준은 아키텍처 설계에서 찾아내는 “구성요소와 관계” 및 “속성”의 세부 사항들을 정의하는 것이다. 따라서, 구체적인 수준 에서 올바르지 못한 결정을 찾아냈다면, 상위 수준의 설계에 대해서 피드백을 주어야 한다. 일을 시작할 때는 모르던 지식 들도 일을 마칠 때가 되면 더 이상 남아있지 않게된다. 즉, 개선할 점이 드러나는 순간은 과제의 완료 시점까지 지속 된다 는 것이다. 심지어 과제가 완료되어 실제 사용에 들어가더라도 이는 마찬가지다. 물론, 그 전까지 최대한 많은 부분을 찾아 내 수정하는 것이 좋다. 하지만, “복잡한” 일의 특성상 직접 사용해 보지 않으면, 그런 부분들을 찾아내기 힘든 경우가 많 다. 따라서, 조금이라도 수정을 줄이기 위해서는 가능한 빨리 사용할 수 있는 형태로 만들어야 한다. 핵심만 설계를 하고 결정되지 않은 것들을 뒤로 미루는 이유도 그것 때문이다. 가능한 완전하게 사용할 수 있는 “핵심”기능을 먼저 소위 말하는 풀 스택(Full Stack)으로 구현해 보는 것이 수정 노력을 최소로 만들어 줄 것이다. 계획에 이런 부분들을 적절히 배치할 수 있다면, 성공할 가능성도 조금씩 커질 것이 분명하다. - 복잡할수록 실행 전에 어떻게 할 것인지 계획해야 한다.- 18 · [ 프로페셔널 프로그래머 ]
  • 19. 2017/10/18 11:56 http://blog.naver.com/knix008/221119636806 [ 테스트하기 쉬운 코드 ][ 테스트하기 쉬운 코드 ] 낙서장(2017)낙서장(2017) 제품을 만드는 기술의 발전은 “구현”만 있는 것이 아니다. 만든 제품을 테스트 하는 것도 제품을 만드는 것 만큼 중요하다. 실제로 제품을 개발하면 검증을 어떻게 하느냐에 따라, 일정 지연 여부가 결정되기도 한다. 잘 만들기 위해서는 잘 만들 수 있는 방법을 미리 고안해야 하며, 테스트도 마찬가지로 과제 초기부터 고려해서 코드에 반영될 수 있어야 한다. 이미 대부 분의 코드가 만들어진 이후에 테스트를 하는 것은 낭비가 발생할 가능성이 높으며, 제대로 테스트 하기도 힘들어 검증과정 이 길어질 염려도 있다. 소프트웨어 제품을 만드는 대부분의 시간은 검증과 디버깅에 달려있기에, 이를 줄일 수 있는 방법 을 생각하는 것을 과제 개발에서 중요한 “요구사항”으로 간주해야 한다. 그렇지 않다면, 만들었다고 생각하는 순간부터 길 고 지루한 “디버깅” 시간을 가질 것이 분명하기 때문이다. 다른 것들도 마찬가지겠지만, 초기부터 조금씩 테스트를 위한 고 려를 구현에 포함 시킨다면, 투자에 대한 이익은 확실히 보장될 것이다. 사실 테스트 자동화 만큼 “남는 장사”는 없다고 보 는 것이 옳다. 01.01. 시스템의시스템의 상태를상태를 외부에서외부에서 파악할파악할 수수 있는있는 방법을방법을 고려한다.고려한다. ; 외부에서 시스템의 상태를 얻기 위해서는, 시스템에 상태를 모니터링 할 수 있는 에이전트를 만들어야 할 수도 있다. 혹 은, 특정한 저장공간이나 원격 시스템에 시스템의 로그를 저장할 수도 있을 것이다. 구현하는 시스템에 따라 다양한 방법 이 고려될 수 있지만, 시스템의 상태를 실시간으로 알 수 있는 방법을 제공하는 것은 디버깅을 위해서 중요한 고려사항이 다. 02.02. 입력의입력의 종류와종류와 가지수를가지수를 한정한다.한정한다. ; 입력의 종류와 가지수를 한정하는 것은 구현을 돕는 동시에 테스트도 쉽게 만든다. 예를 들어, 함수를 구현할 때 파라미 터의 수를 늘리면 입력으로 주어야 할 가지수가 늘어나게 된다. 당연히 테스트해야 할 케이스도 늘어난다. 또한, 값의 범위 를 제한하지 않으면 어떤 값이 유효한 값인지 알지 못한다. 이떄는 생각할 수 있는 모든 값을 넣어야 제대로 테스트 할 수 있을 것이다. 03.03. 단일단일 출력을출력을 가지도록가지도록 만든다.만든다. ; 단일 출력을 가진다면 실행의 결과를 출력을 통해서 확인하는 방법을 이용할 수 있다. 물론, 내부 데이터의 변경이 동반 되는 경우에는 외부에서 의존성을 삽입하는 방식으로 데이터를 인위적으로 검사할 수 있을 것이다. 예를 들어, 함수와 같 은 것을 검증할 때, 출력을 이용해서 정확히 실행 되었는지 확인할 수 있을 것이다. 04.04. 변경과변경과 질의를질의를 구분한다.구분한다. 19 · [ 프로페셔널 프로그래머 ]
  • 20. ; 변경과 질의를 같이하면 두가지 역할을 하나에 할당하는 것과 같다. 따라서, 둘 다를 검사해야 한다. 이 두가지를 분리한 다면 각각을 나누어서 검증할 수 있을 것이다. 당연히 둘을 분리하는 것은 역할과 책임 범위를 명확히 할 수 있으며, 각각 은 더 짧은 코드로 나누어지게 될 것이다. 의존성도 각각에 나누어서 관리될 수 있을 것이다. 05.05. 외부에외부에 의존하는의존하는 부분을부분을 가능한가능한 줄인다.줄인다. ; 외부에 의존하는 것이 많아지면 테스트를 위해서 만족시켜야 할 조건들이 늘어나게 된다. 따라서, 이런 경우 테스트 자체 보다 선행 조건을 만들어주는 일이 더 커지게 된다. 당연히 테스트 작성의 효율은 낮아질 것이고, 의존성을 해결하기 위해 서 코드를 이해하는 시간은 길어질 것이다. 테스트 케이스 작성 자체가 불가능한 상황이 될 지도 모른다. 06.06. 짧은짧은 코드를코드를 작성한다.작성한다. ; 짧은 코드는 단일 역할만 하는 실행 단위를 기초로 한다. 예를 들어, C언어라면 함수가 최소 실행단위가 되며, 하나의 함 수는 하나의 역할만 수행하는 것이 맞다. 즉, 단일 역할을 실행하는 짧은 코드를 작성해야 하며, 길이가 길어질 경우에는 여러 개의 작은 부분들로 나누어서 작성해야 할 것이다. 물론, 각각의 나누어진 부분들을 하나씩 검사하지 않고도 충분히 검증을 할 수 있다. 하지만, 중요한 부분이라고 생각되는 것들은 따로 검사할 수 있어야 한다. 07.07. 조건문의조건문의 수를수를 가능한가능한 줄인다.줄인다. 20 · [ 프로페셔널 프로그래머 ]
  • 21. ; 조건문의 수가 늘어나면 테스트를 위한 입력 조건을 만드는 가지수도 늘어나게 된다. 또한, 복잡한 조건문일 경우에는 실 행되지 않는 코드가 있을 수도 있다. 물론, 그런 코드를 발견하면 제거하는 것이 기본이지만, 특별한 예외 상황을 처리하기 위해서 그대로 두는 경우가 있다. 하지만, 그런 예외 상황을 만들어내는 것이 힘들어, 테스트 없이 그냥 두게되는 것이 일 반적이다. 조건문의 수는 성능에도 영향을 주기 때문에, 가능한 줄이는 것이 좋다. 08.08. 조건문조건문 자체를자체를 간략하게간략하게 만든다.만든다. ; 조건문 자체도 복잡하지 않아야 한다. 조건문이 복잡해지면 각각의 실행을 위해서 조건을 만들어낼 수 있는 조합 자체가 늘어나게 된다. 이해가 어려운 것은 당연한 결과다. 따라서, 조건문을 될 수 있으면 간단히 유지하려고 노력해야 하고, 이 해하기 어려운 조건문은 따로 분리해서 인라인 함수화 시키는 것도 좋다. 부정보다 긍정적인 조건문을 사용하는 것이 코드 를 읽는 사람이 더 이해하기 쉽도록 도울 것이다. 09.09. 외부에외부에 노출되는노출되는 부분을부분을 가능한가능한 줄인다.줄인다. ; 외부에 노출되는 것이 많으면 많을수록 코드는 스파게티처럼 꼬이는 것이 일반적인 현상이다. 사람은 알고 있는 사실을 이용해서 가능한 직접적인 조작을 시도하는 경향이 있다. 따라서, 정보를 감추는 일은 의존성을 약화시키는 첫 번째 방법 이다. 노출되는 정보다 적으면 테스트를 위한 선행 조건을 만들기도 쉬울 것이다. 10.10. 자원에자원에 대한대한 의존을의존을 외부에서외부에서 삽입할삽입할 수수 있도록있도록 만든다.만든다. ; 자원을 내부에서 생성하면 외부에서 알 방법이 없다. 그리고, 생성된 자원이 하드웨어나 혹은 테스트 하는 환경에 밀접한 관련이 있다면, 그것을 제공할 수 있는 방법도 없다. 예를 들어, 특정 레지스터나 타이머에 대한 의존성이 생긴다면, 테스 트 케이스에서 삽입할 수 있는 방법을 제공해 주어야 한다. 그렇지 않다면, 원활하게 테스트를 실행하기 어려울 가능성이 높으며, 테스트 대상이 되는 코드가 제대로 동작 하는지 확인하기도 어렵게 된다. 제품은 만드는 것보다 항상 어떻게 테스트 할 것인지를 먼저 고려해야 한다. 그러한 고려가 없다면 대부분의 중요한 시간 을 낭비할 가능성이 높다. 물론, 그런 대비에 너무 많은 시간을 사용하는 것도 옳지 않지만, 그렇다고 전혀 투자를 하지 않 는 것도 올바른 선택은 아니다. 적당한 비율을 찾는다면 7:3 정도로 하기 바란다. 특별한 이유가 있는 숫자는 아니며, 일의 효율과 투자의 적정성을 고려해서 코드 개발에 70%, 테스트를 위해서 30%의 노력을 사용하면 된다. 자신이 하고 있는 일에 대해서 검증할 수 있는 방법을 다른 사람에게서 찾는다면 프로패셔널이 아니다. 진정한 전문가라면 자신이 하는 일의 성격이 무엇인지 파악하고 그것에 맞는 방법을 찾아서 익히는 것이 기본 자세다. - 테스트 하기 쉬운 코드가 설계를 개선한다.- 21 · [ 프로페셔널 프로그래머 ]
  • 22. 2017/10/19 08:39 http://blog.naver.com/knix008/221120293450 [ 여유는 올바른 결정을 만든다. ][ 여유는 올바른 결정을 만든다. ] 낙서장(2017)낙서장(2017) 바쁜 사람은 문제에 대한 다양한 분석이 어렵다. 바둑이나 장기를 둘 때, 옆에서 훈수하는 사람이 더 상황을 잘 파악하는 이유도 그 때문이다. 객관적인 입장이 되지 않으면, 보여야 하는 것들이 제대로 보이지 않게된다. 시속 100km로 달리는 차를 운전할 때는 주위의 사물이 눈에 들어오지만, 200km로 달리는 차를 운전하는 사람은 자신의 바로 앞에 있는 상황만 인지할 수 있을 뿐이다. 물론, 심리적인 것과 시각적인 것이 다르다고 이야기 할 수 있을지도 모르지만, 어쨌든 바쁜면 나 쁜 선택을 하게되는 것은 어쩔 수 없다. 1시간짜리 회의라면 마지막 5분에 대부분 중요한 결정이 나기마련이다. 그 떄 올 바른 선택을 하기 위해서는 최대한 객관적인 입장에서 한발 물러나 생각해야 한다. 문제를 벗어나서 생각하면 해결책이 떠 오르지만, 문제 속으로 들어가면 풀어야 할 문제의 전체적인 모습이 보이지 않게 된다. 시간이 부족해서 급하게 내리는 결 정들의 대부분은 잘못될 가능성이 있기에, 가능하면 급한 결정은 뒤로 미루는 것이 현명하다. 위험하다고 생각되는 순간에 우리가 선택할 수 있는 최선의 것은 “우리 자신을 보호하는 것”밖에 없다. 이것은 문제에 대한 진정한 해결책이 아니라, 문 제를 회피하고 벗어나려는 방법이 될 것이다. 우리 자신을 위험에서 지켜내는 것이 “급한 결정이 할 수 있는 최선의 것”이 다. 개발자들이 시간이 부족할 떄 내리게 되는 대부분의 결정도 마찬가지다. 근본적인 해결책이 아닌 증상의 완화이거나, 미래의 가치를 낮추는 오류를 만들게 된다. 이런 결정들을 내리지 않기 위해서는 미리 마주할 수 있는 위험 상황에 대한 “행동 지침”을 만들고, 그것에 맞게 차분하게 대처하는 것이 현명한 방법이다. 개발자가 가장 자주 마주하는 위협 중에 하 나는 “일정 단축이나 부족”이며, 그런 상황에 대처하기 위한 방법은 “가능한 일을 하지 않는 방법을 생각하는 것”이 될 것이 다. 구현하지 않으면 문제도 발생하지 않는다. 따라서, 일하지 않으면 문제도 없는 것이다. 역설적이지만 일하지 않는 것이 가장 완벽한 처방일 수 있는 것이다. 따라서, 과제 계획에는 반드시 “응급 상황에 대한 대처 방안”을 미리 갖추는 것이 필 요하며, 그것에 맞게 행동하도록 훈련되어 있어야 할 것이다. 규칙은 사람을 편하게 만든다. 생각할 것이 없이 그대로 따르면 되기 때문이다. 물론, 규칙을 만드는 과정은 여러 사람의 참여와 동의가 필요하다. 그냥 무턱대고 만들면 아무도 안지키게 되기 때문이다. 일반적으로 규칙에는 두가지 점이 반영되 어야 한다. 첫 번째는 이미 효과가 있다고 증명된 것들이 포함될 수 있으며, 두 번째는 과제에 적합한 것들이 있을 수 있 다. 둘 간에 우선 순위는 항상 특수한 상황을 가정한 것이 높다. 일반적인 상황에서 적용할 수 있는 것들이 있는 반면에 특 정 과제에만 적용할 수 있는 것들이 있기 때문이다. 하지만, 문제가 되는 것은 두가지 규칙이 서로 상충하는 경우가 있다는 점이다. 예를 들어, 전역 변수를 쓰는 것이 일반적으로 좋지 못하다고 이야기하지만, 특정 과제에서 편의를 위해서(혹은, 성능이나 기타 다른 요인에 의해서), 전역 변수를 한정해서 사용할 수도 있기 때문이다. 상충하는 경우 어떻게 해결할 것인 가를 정하지 않으면 둘 중에 하나는 무시될 것이 분명하다. 따라서, 서로 충돌이 발생하는 경우를 위해서 협의 할 수 있는 창구나 방법을 마련해 두는 것도 필요하다. 대부분의 경우 일반적으로 “적절하다”고 생각되는 것은 사실은 특정 과제에만 적용되지는 않는다. 적용 정도가 차이가 나거나, 혹은 변형되어 사용될 뿐, 전체적으로 그르다고 보는 것은 옳지 않다. 상 충되는 부분이 있다면, 미리 규칙을 이야기 할 떄 정리하는 것이 가장 효과적일 것이다. 규칙을 정할 떄는 상식이나 경험적 22 · [ 프로페셔널 프로그래머 ]
  • 23. 인 부분을 배제할 필요가 있을 수도 있다. 예를 들어, 과거에는 이렇게 해왔다거나 혹은 이렇게 하는 것이 더 좋아보인다와 같은 의견은 엉뚱한 결과를 가져올 수도 있다. 상식이라고 생각되던 것이 거짓으로 판별되는 경우도 있으며, 잘못된 경험 이 편견을 만들어 낼 수도 있기 때문이다. 가능한 검증된 결과를 가지고 이야기하는 것이 많은 사람의 동의를 이끌어내고, 더 좋은 결과를 유도할 것이라는 점은 분명하다. 간혹, 성급한 결정이 돌이킬 수 없는 결과를 만들어 낼 수 있기에, 가능한 여유가 있는 상황에서 논리적으로 합당한 규정을 만들도록 노력해야 할 것이다. 사람은 여유가 없다고 느끼면 일 처리를 빨리 하려고 노력한다. 과정을 생략하고 결과에만 집중하도록 요구 받는다. 결정 은 신속하게 내려지지만 정확하거나 논리적이지 않을 수 있으며, 행위의 결과에 대한 검토는 건너뛰게 된다. 당연히 오류 가 스며들 가능성이 높아지는 것이다. 여유가 필요한 순간이 바로 이 떄다. 급하게 가고 있다는 생각이 들 때면, 다시 한번 지금까지 제대로 해 왔는지를 검토해야 한다. 더 나아가면 다시 돌아가야 할 길만 길어질 뿐이다. 지금 문제가 보이지 않는 다고 해서 문제가 없는 것이 아니며, 검토를 생략하면 당연히 문제는 숨어서 자라게 된다. 커진 문제를 해결하기 보다, 문 제가 작을 때 해결하는 것이 비용이 싸다. 이것은 누구나 아는 사실이지만 가벼운 증상을 키워서 중병으로 만드는 것과 같 다. 이쯤은 괜찮겠지라는 생각이 결국 치명적인 결과를 만드는 것이다. 완벽 하라고 이야기하는 것이 아니라, 최소한 뒤돌 아 볼 수 있는 시간이 필요하다는 것이다. 계속 앞으로만 달려가는 사람은 폭이 좁은 시야를 고수하게 되고, 결국 자신이 가고 있는 방향이 잘못되었다는 사실을 시간이 지나서야 알게된다. 그 때가 되면 이미 돌아가기에는 너무 먼 길을 왔기에, 관성을 그대로 갈 수 밖에 없다. 물론, 그 때라도 조금 여유를 가지는 것이 중요하기는 하지만, 이미 상황이 발생한 상태에 서는 이전에 가지고 있던 여유 마저도 없을 것이 분명하다. 복잡한 일을 하는 사람은 모든 상황을 다 보지 못한다. 모든 상 황을 다 고려한 판단도 불가능하다. 하지만, 만약 그 상황에 대응할 수 있는 “행동 강령”이나 “업무 규칙”이 있다면, 훨씬 더 효과적인 결과를 만들어 낼 수 있다. 앞만보고 가더라도 장애물이 나타날 경우 어떻게 해결할 것인지 미리 계획한다면, 회 피하거나 정면으로 극복하려고 노력할 것이다. 오히려 사태를 악화시키는 것은 임시적인 방편으로 지속적인 대응을 하겠 23 · [ 프로페셔널 프로그래머 ]
  • 24. 다는 생각이다. 상황이 바뀌면 대응 방법도 달리하는 것이 옳지만, 그렇다고 모든 것을 임시적인 해결책으로 완화 시키려 고 노력하는 것은 해답이 아니다. 예를 들어, 제품의 라인업을 다양화 하기 위해서 지속적으로 분기하는 코드를 삽입하는 것은 옳지 않다. 빠르게 고칠수는 있지만, 근본적인 해결책이 아닌 것이다. 그럴 경우에는 미리 제품 분기에 대한 정책을 만들어서 규격화 시킬 필요가 있다. 여유가 있을 때 생각을 정리하지 않으면 임시 방편만 만들다가 아까운 시간을 낭비하 게 되는 것이다. 노력이 결과를 만들기 위해서는 노력의 방향과 질적인 수준을 정해야 한다. 단순히 노력한다고 모든 일이 완성되는 것은 아니다. 누군가는 “1만 시간”을 사용해서 최고의 전문가가 되지만, 또 다른 누군가는 “1만 시간”을 사용해도 평범한 수준 에서 크게 차이가 나지 않을 수 있다. 따라서, 노력이 결과를 만들기 위해서 무엇을 어떻게 해야할지 세부적인 목표와 더불 어 행동 규정도 만들어야 한다. 물론, 그렇게 만들어진 것들이 지속적으로 사용되기도 해야하지만, 계속 더 효과적으로 만 들기 위해서 개선도 해야한다. 지금 부족하다면 근본이 되는 이유를 찾아야하고, 그것을 해결할 수 있는 방법을 축적해야 한다. 임시 방편으로 대응하는 것은 잘모르는 상황에 대해서 좁아진 시야로 할 수 있는 최선의 선택이다. 하지만, 그 때는 최선이었는지 모르지만, 시간이 흐르면 최악의 잘못된 선택이 될 수도 있다. 자신의 분야에 경험과 지식이 충분히 있다고 믿는 사람이라면, 적어도 장기적인 시각에서 올바른 선택이 무엇인지 확고하게 알고 있어야 한다. 단순히 “좋아보이거나 그래야 할 것 처럼 보이는” 결정들은 실패를 부르는 지름길이 될 수도 있다. 빨리 간다고 목표에 도달할 수 있는 것이 아니 라, 제대로 방향을 잡고 가야 좋은 결과를 만들 수 있다. 기초가 부족하다면 기초를 익혀야 할 시간도 필요하며, 경험이 부 족하다면 작고 빠르게 실패할 수 있는 방법도 찾아야 한다. 규칙은 신중하게 선택되어야 하며, 여러 사람의 동의가 필요한 부분이기에 시간을 투자할 충분한 가치가 있다. 또한, 한번 정해진 규칙은 꾸준히 지키는 것이 무엇보다 중요하다. 복잡함 을 정복하는 길은 작은 규칙적인 활동을 반복하는 것이며, 규칙 자체도 꾸준히 다듬어 나가는 것이 필요하다. 너무 많은 규 칙을 만들기 보다, 핵심이 되는 적은 수의 규칙을 만드는 것이 시작이다. 각각의 상황에 맞게 해석을 달리하는 것이 아니 라, 각각의 상황에 적합하도록 다듬는 것이다. 여유는 투자할 수 있는 노력이 있다는 것을 말하며, 놀고 있다는 뜻이 아니 다. 어떻게 여유를 사용해야 할지 모르는 것이 문제이며, 여유 자체가 없는 것이 더 큰 문제다. 여유가 주어지면 사람들은 자신의 행위에 대한 검토와 개선 방법을 만들지만, 여유 없는 삶이란 실수는 하지만 배우지 않는 반복적인 따분함의 연속 일 뿐이다. - 더 적게 일할 수 있는 방법을 고안 하라. 게으름은 효과적인 방법을 찾도록 만든다.- 24 · [ 프로페셔널 프로그래머 ]
  • 25. 2017/10/24 22:32 http://blog.naver.com/knix008/221124500807 [ 불안감의 정체 ][ 불안감의 정체 ] 낙서장(2017)낙서장(2017) 불안감을 느끼고 있는 상황에서는 좋은 판단을 내리기 어렵다. 가장 중요한 것은 불안감에 대응하는 방어적인 자세를 취하 게 되는 것이 최고 우선순위다. 따라서, 좋은 판단보다는 안정을 추구하는 것이 당연한 행동이며, 변화나 도전은 남의 이야 기로 치부해 버리고 만다. 회사는 변화를 추구하고 도전해야 한다고 이야기 하지만, 실무자 들이 느끼는 것은 가능한 자신 이 할 수 있는 일만 하는 것이 최선이고 최고의 가치다. 실패는 용납되지 않고 실패가 곧 낙인처럼 인식되는 회사에서는 도 전이나 혁신은 구글이나 페이스 북에서만 가능하다고 생각될 뿐이다. 불안감이 없어지지 않는한, 우리가 할 수 있는 일이 라고는 최대한 모험을 하지 않고 안정을 추구하는 것이 최선의 선택이다. 그렇다면 불안감이 생기는 원인은 뭘까? 불안감 은 크게 두가지 측면에서 온다. 첫 번째는 자신의 능력보다 큰 일을 맡았다고 생각 될 때이며, 두 번째는 무슨 일인지 모르 는 경우다. 자신의 능력보다 큰 일은 자신감을 감퇴 시키며, 모르는 일은 무엇을 해야할 지 막연하게 만든다. 확실한 것이 없는 상황에서는 가장 확실한 방법을 선택하기 마련이며, 대부분의 경우 새로운 것보다는 이미 해보았던 것을 선택하는 것 이 가장 안정적인 것이다. 불안감은 미지에서 나온다. 이미 경험한 것은 두려움이 아니다. 이미 알고 있는 것은 힘들지는 모르지만, 어느정도 감을 가 지고 대응할 수 있다. 불안감을 느끼는 것은 무엇인지 모르는 상황에서 나오는 행동이다. 따라서, 파악할 수 있는 절차와 방법이 필요하다. 신입 사원이 가지는 불안감도 마찬가지다. 새로운 일을 맡게 되면 불안감을 느낄 수 밖에 없으며, 불안감 은 곧바로 불편함과 거부감이 들도록 만든다. 불편한 것은 변화를 동반해야 해결이 되지만, 새로운 것들 받아들이는 것 자 체도 불안감을 키울 수 있기 때문에 상황이 악화될 가능성도 있다. 이것을 해결할 수 있는 유일한 방법은 그냥 "모르는 것 을 인정하는 것" 뿐이다. 모르는 것을 모른다고 표현할 수 있다면 누군가의 도움이나 해결할 수 있는 방법을 찾아야 한다는 것을 깨닫게 된다. 불안감을 가지고 아닌 척 해봐야 문제는 해결되지 않기 때문이다. 새로운 것을 받아들일 수 있는 마음이 드는 것도 "스스로 모르는 것을 인정"할 때 가능하다. 미지에서 나오는 불안감을 극복하기 위해서는 학습할 수 있는 시간 이 필요하며, 시험하고 실패할 수 있는 가능성이 열려있어야 한다. 마치 한번의 실패가 모든 실패로 결론나지 않도록 만들 기 위해서는 작은 시도에 대해서 즐겁게 실패할 수 있는 마음가짐이 필요하다. 25 · [ 프로페셔널 프로그래머 ]
  • 26. 바쁜 마음은 불안감을 증폭시키는 효과를 가진다. 잘 모르는 일을 주어진 시간내에 마무리를 지어야 한다는 압박감은 느껴 보지 않은 사람은 알 수 없다. 과제의 리더가 되지 않고서는 그런 감정을 쉽게 알 수 없을 것이다. 문제는 팀원이 느끼는 불 안감보다 리더가 느끼는 불안감이 과제를 엉뚱한 방향으로 몰고갈 수 있다는 점이다. 리더가 불안하면 팀원 들에 대해서 압박감을 줄 수 있으며, 압박받는 상황에서 일하는 팀원들은 될 수 있으면 간단한 해결방법(하지만, 잘못된) 선택을 하게 된다. 쉬운 선택이 올바른 것이 아닐 수도 있지만, 선택을 하는 순간에는 그것을 깨닫지 못한다. 특히, 복잡한 일일수록 잘 못된 선택의 결과는 후반으로 갈수록 효과가 커지게 되며, 그것을 깨닫는 순간 이미 너무 많이가서 다시 돌아가기 함든 상 황이 되고만다. 관성의 힘이 작용하는 것은 물리세계만이 아니라, 우리의 판단도 "이미 만들어 놓은" 것에서 자유로울 수 없다. 사실 바쁘다는 말이 가지는 의미는 일을 제대로 처리하는데 시간이 더 많이 필요하다는 것을 의미한다. 바쁘다는 말 로 단계를 생략해도 된다는 것이 아니다. 리더가 업무에 대한 기준이 명확하지 않다면, 팀원들은 일을 임의로 처리하게 된 다. 바쁘기 때문에 그렇게 해도 아무도 이의를 제기할 수 없는 것이다. 바쁜 마음이 든다면 어떻게 일을 하는 것이 제대로 하는 것인지 기준을 명확히 하는 것이 최선의 답이다. 당겨진 일정, 부족한 기술과 인력, 모자란 자금과 지원 등등 다양한 것들이 불안감을 제공한다. 이중 대부분을 해결해 줄 수 있는 것은 "더 높은 곳에 있는 분"이다. 따라서, 불안감을 조성하는 것도 대부분 그 분들의 일이며 해소하는 방법을 알 려주지도 않는다. 불안감을 조성해서 사람들의 동기를 자극하려는 "단순한" 욕구에서 그렇게 하는 경우와, 실제로 그런 일 정 밖에 만들지 못하는 것이 실력일지도 모른다. 과제가 지속적으로 지연되고 있다면, 다음 번 과제는 더 빨리 시작할 수 있는 방법을 생각해야 하는 것이 아닐까? "그럼에도 불구하고 목표 100%완료"라는 엉뚱한 목표를 제시하고 "도전의 식"과 "주인의식"을 강조하는 것도 그들이다. 문제는 그들 자신이 그런 과제를 하게 된다면 정말 그렇게 할까? 아마도 똑 똑 하셨던 분들이라 결코 그런 진흙 구덩이에 빠지는 과제에서는 일찌감치 발을 뺐을 지도 모른다. 도전적인 목표란 일을 할 수 있는 방법과 일정을 스스로 계획할 때 가능하다. 주인 의식은 권한이 주어졌을 때 생기는 감정이다. 그런 것들이 인 정 받지 못하는 상황에서 만들어지는 불안감은 극복할 수 있는 방법이 없는 것이다. 따라서, 극복하지 못하면 피할 수 밖에 없다. 스스로를 보호하지 못하면 당하는 수 밖에 없기 때문이다. 피할 수 있는 모든 방법을 강구해서 다양한 이유로 일정을 늦추거나, 노력이 많이 필요한 기능들을 제거하는 것도 그것 때문이다. 창의적인 노력이 필요한 복잡한 일을 하지만, 가능 한 다치지 않게 피하는 방법을 배우게 되는 것도 어쩔 수 없다. - 공포로 해결할 수 있는 것은 일을 망치는 방법을 고안하는 것 뿐이다.- 26 · [ 프로페셔널 프로그래머 ]
  • 27. 2017/10/25 08:36 http://blog.naver.com/knix008/221124696798 [ 환경이 사람을 만든다. ][ 환경이 사람을 만든다. ] 낙서장(2017)낙서장(2017) 코딩은 정신 활동이다. 따라서, 코딩하는 사람의 정신 상태가 코드에 영향을 줄 가능성이 높다. 코딩이 원활하게 이루어지 기 위해서는 그 일을 하는 사람의 심리적인 상태가 안정적이어야 하며, 그렇지 못할 경우 좋은 코드가 나오지 않을 것이 분 명하다. 야근이나 특근은 미진한 부분에 대한 만회를 할 수 있는 시간이다. 바쁜 상황에서 처리하지 못했던 남은 업무를 마 감할 떄 활용할 수 있는 유일한 기회다. 상시 야근과 특근이 일상화가 되면 하루 동안 사용해야 할 한정된 정신력이 분산되 는 효과를 낳으며, 생산성이 떨어지는 것은 당연한 결과일 것이다. 선진국과 우리나라의 산업 생산성에 대한 비교를 하면 서, 우리나라는 일을 많이 하면서 생산성이 높지 않아서 고비용 저효율이라고 이야기 한다. 이는 선택의 문제이며 우리나 라의 대부분의 관리자들은 고비용이 들더라도 많은 일을 할 것 처럼 보이는 것을 선택했기 때문에 발생하는 결과일 뿐이 다. 마치 조직의 구성원이 효율이 낮아서 그런 것 처럼 보이는 말을 하지만, 실질적으로 높은 가치를 만드는 일보다 빨리 조금이라도 많이 만들어 싸게 파는 것을 전략적으로 추진했기 때문에 나오는 현상이다. 효율을 높이고자 한다면 주어진 시 간에 고부가 가치를 생산할 수 있는 일을 해야한다. 또한, 하나의 가치를 만들더라도 더 큰 시장에서 팔 수 있도록 표준화 된 제품을 만들어 주어야 한다. 서비스를 제공한다면 한정된 작은 시장보다는 큰 시장을 대상으로 해야하며, 물질적으로 손에 잡히는 것보다 생산과 동시에 소비가 이루어질 수 있는 것들을 만들어야 한다. 노동 집약적인 산업에서 지식 집약적 인 산업으로 이동하는 이유도 마찬가지다. 하지만, 그 모든 것을 가능하게 만들기 위해서 가장 필요한 것은 구성원의 “올바 른 정신 활동이 가능한 상태”를 만들어주는 것이 선행되어야 한다. 사람은 하루에 한정된 노력 만을 투자할 수 있으며, 투 자 효과가 극대화가 되기 위해서는 사소한 낭비를 줄이고 집중할 수 있는 분위기를 유도해야 한다. 그런 환경이 되지 못한 다면 시스템을 탓해야지 사람을 탓하고 있어서는 안된다. 누구나 좋은 환경에서 자라면 훌륭한 인재가 될 것이라는 것은 다 알면서도, 좋은 환경 만들기에 인색하게 굴면서 좋은 인재 타령만 해선 안될 것이다. 좋은 환경은 좋은 코드를 만든다. 정신 상태가 맑은 상황에서 코딩하는 것이 당연히 더 적은 버그를 만든다. 피곤하고 지친 상태에서 만드는 코드는 잠재적인 버그의 개수를 늘린다. 하지만, 우리가 일을 하는 방식은 “더 많이 더 빨리”에 가깝다. 따라서, 더 많은 코드를 더 빠르게 만들기 위해서 더 오랜 시간을 일하게 되는 것이 현실이다. 맑은 정신 상태를 유지하기 위해서는 적절한 휴식이 필요하지만, 휴식 시간을 길게 가지면 노는 것 처럼 보여서 관리자들은 싫어한다. 정신이 지치면 사람들이 하는 반응은 “더 느리게 집중하지 않고” 코딩하게 된다. 당연히 일하는 시간은 길어지지만 품질이 나쁜 코드가 만 들어진다. 사람의 정신력이란 무한정 뽑아서 쓸 수 있는 것이 아니라, 휴식을 취해야만 회복할 수 있다. 휴식 시간이 짧아 지면 당연히 뽑아낼 수 있는 정신력도 적을 수 밖에 없다. 적은 정신력을 길어진 시간에 맞추기 위해서는 집중의 밀도가 낮 아질 수 밖에 없는 것이다. 사람에 대한 평가를 내릴 때, 그 사람이 얼마나 오래동안 근무를 했는가를 따진다면, 일의 품질 보다는 자리에 앉아 있는 시간만 평가를 받게 된다. 대부분의 관리자들은 자리에 앉아서 일하고 있는 모습을 보기 좋아하 며, 자신이 쉽게 그런 상황을 파악할 수 있는 것을 바랜다. 잠시 일어나서 훑어보는 것으로 누가 아직 퇴근하지 않고 일하 는지 알고 싶어한다. 그리고, 그것이 그들이 할 수 있는 최선의 “빠른 납기 달성을 위한 방법”처럼 보이기도 한다. 하지만, 27 · [ 프로페셔널 프로그래머 ]
  • 28. 문제는 납기를 만족했다고 일이 끝나지 않는다는 점이다. 비용은 납기 이후에 발생하면 대처하기 위한 시간도 길어지며 큰 낭비를 가져오는 성향이 있다. 흐리멍텅한 정신으로 만든 문제들이 납기 이후에 발생하지 않을 것이라고 장담할 수 있을 까? 우리가 만드는 코드의 테스트 범위도 모르는 상황에서 단순히 테스트를 통과했다는 의미를 납기 이후까지 확장할 수 있을까? 그것은 근거없는 낙관일 뿐이다. 그리고, 그 낙관은 쉽게 손상되는 것이 일반적이다. 좋은 코드를 만들기 위해서는 “역량있는 인재”들이 필요하지만, 그런 인재들은 비싸고 움직이지도 않는다. 이미 회사에서 그런 인재들을 충분히 대우하고 있을 것이 분명하다. 또한, 역량있는 인재를 찾는 것도 쉽지 않다. 누가 역량이 있는지는 옆에서 일해본 사람만이 알 수 있기 때문이다. 대부분의 역량있는 인재들은 더 환경이 좋은 회사를 선호한다. 금전적인 부 분이 만족되면 그 다음은 회사의 분위기를 찾게 되는 것이다. 인재들은 환경이 좋지 않다면 아무리 많은 돈을 주더라도 쉽 게 회사를 떠난다. 남는 사람들은 “인재(인간 재앙)”에 가까운 사람들이 될 가능성이 높다. 물론, 이것도 사람을 길러내는 회사의 시스템적인 문제다. 동일한 출발선에서 시작하더라도 누군가는 역량있는 인재가 되고, 누군가는 재앙을 몰아오는 사람이 되는 것이다. 그런 차이를 만드는 것이 바로 회사의 체계(시스템)와 분위기다. 사람을 아끼는 회사라면 인재를 키 우는데 투자를 아끼지 않을 것이다. 적어도 스타트 업과 같은 벤처라고 하더라도 좋은 인재를 찾기 위한 여러가지 아이디 어는 가지고 있을 것이다. 그것들 대부분이 단순히 “연봉”만을 이야기 하지는 않는다. 좋은 환경이라고 해서 무조건적인 “여유”를 말하는 것은 아니다. 사람이 성장하는데는 적절한 도전 목표와 그것을 자율적으로 해결할 수 있도록 만들어주는 시스템이 있어야 한다. 단순히 좋은 분위기만 유지하고 편하다는 느낌으로는 만족되지 않는 “발전하고자 하는 욕구”가 있 기 때문이다. 좋은 인재들은 자신이 발전하고 있다는 느낌을 가지고 싶어한다. 마냥 반복되는 지루한 업무는 그들에게 따 분함만 줄 뿐이다. 자신이 결정하고 행동할 수 있는 것도 중요한 요구사항이다. 아무 것도 결정할 권한이 없고 누군가의 일 방적인 의견이나 명령만 들어야 하는 상황은 인내력이 아무리 강한 사람이라도 참아내기 힘들다. 아마도 그런 환경을 이겨 낸 사람은 이미 새로운 것에 대한 도전 정신이나 자발적인 동참과 같은 부분은 “뇌에서 제거”되었을지도 모른다. 28 · [ 프로페셔널 프로그래머 ]
  • 29. 사람이 무한한 능력을 가지고 있다고 이야가 하지만, 그것을 뽑아내서 쓰는 것은 시스템의 몫이다. 잘못된 시스템을 아무 리 활용해봐야 나올 수 있는 아웃풋은 쓰레기에 가까운 결과물일 뿐이다. 무한한 잠재력이라고 하지만 휴식이 없이는 서서 히 밑바닥을 드러내는 우물이 되고말 것이다. 많은 일을 빠른 시간내에 마칠 수는 있을지 모르지만, 그 각각의 처리한 일들 이 제대로 되었다는 보장은 할 수 없다. 한번에 많은 일을 하게 되면 정신적인 소모가 커지게 되며, 결국 더 오랜 시간을 보 충을 위해서 필요로 한다. 이것이 지켜지지 않으면 뽑아내 사용할 수 있는 역량도 줄어들기 마련이다. 관리자들은 인정하 기 힘들겠지만 이것이 현실이다. “더 열심히, 더 오래, 더 많이”하라고 이야기하는 것에도 한계가 있는 것이다. 일정을 아무 리 당긴다고 하더라도 한 사람이 열 달 할 일이 열 사람이 한 달내에 끝내지는 못한다. 커뮤니케이션과 동기화에 따르는 오 버헤드도 필요하며, 야근과 특근으로 지치게 만들수록 일은 더디게 진행될 것이 분명하기 때문이다. 무한한 능력을 발휘할 수 있도록 만들기 위해서 관리자들이 유일하게 할 수 있는 것은, 과제에 필요한 모든 것 중에서 자신의 능력으로 해결할 수 있는 것들을 제공하는 것 밖에 없다. 맑은 정신을 가질 수 있는 휴식과 적절한 도전적인 일정 및 자유로운 방법의 선택, 불필요한 숙제를 줄여주는 것등이 좋은 인재를 끓어들이고 효과적으로 능률을 높일 수 있는 유일한 방법이다. 아무리 다그 치고 야단친다고 하더라도 효과는 잠시 밖에 지속되지 않는다. 관리자의 목소리가 커지면 구성원의 목소리는 작아지고 불 만 수준은 커지는 것이 당연하다. 큰 목소리를 낸다고 일이 제대로 돌아간다면 목소리 큰 사람이 가장 높은 자리를 차지해 야 옳을 것이다. 좋은 코드는 좋은 환경에서 나오며, 그 환경을 만드는 것이 관리자의 몫인 것이다. 환경이 좋다면 역량있 는 인재가 회사를 마다할리가 없다. 사람이 회사를 떠나는 가장 큰 이유 중에 하나가 자신이 생존해야 할 공간에서 제공받 지 못하는 것(해결되지 않는 욕구)이 있기 때문이다. - 인재는 인재를 알아보고, 좋은 환경은 좋은 인재를 끌어들인다.- 29 · [ 프로페셔널 프로그래머 ]
  • 30. 2017/11/14 21:10 http://blog.naver.com/knix008/221140028509 [ 과제 관리자 되기 ][ 과제 관리자 되기 ] 낙서장(2017)낙서장(2017) 과제 관리자의 대부분은 과제 관리를 모르는체로 과제 관리자가 된다. 그들은 개발 경험이 많거나, 연차가 오래되었다고, 혹은 성공한 프로젝트 경험을 가지고 있다는 이유로 과제 관리자의 위치로 간다. 물론, 그들이 할 수 있는 일은 기존의 과 제 관리자가 해오던 것을 최대한 위배하지 않는 것이다. 동일한 템플릿을 사용하고, 남들과 같은 방법으로 같은 내용을 기 술해서, 비슷하게 발표하고 보고한다. 전임 관리자들도 과제 관리에 대해서 배운 것은 없지만, 시간을 통해서 알게되는 "관례"에 익숙한 방법을 그보다 앞선 전임 관리자 처럼 했을 것이 분명하다. 따라서, 우리는 제대로 관리자가 될 준비가 되 지 않은 상태에서 관리자가 되는 것이다. 준비없는 관리자가 할 수 있는 것은 개발자 시절에 자신이 했던 일을 반복하는 것 뿐이다. 새로운 것을 배우지 못했다면, 지금까지 알고 있는 것이라도 잘할 수 밖에 없다. 개발자로서 잘하던 사람들도 관리 자가 되면 자신의 역할이 바뀌었음을 인식하지 못하고, 소위 말하는 "대리"처럼 행동하게 된다. 자세한 것은 잘 보지만 전 체 그림을 그리지 못하며, 자신이 관심있는 일은 주의 깊게 보지만, 전공했던 것과 관련이 없는 일은 시선에서 놓치게 된 다. 관리자가 된 후에 배우는 것도 과제 관리가 아닌 팀 빌딩이나 "좋은 관리자란 무엇인가"라는 이야기 밖에 없다. 사실 그런 교육은 크게 전문적인 지식을 요구하는 것은 아니기에, 강사들도 많고 교육 비용도 비싸지 않다(현재 관련된 일을 하고 있 는 사람들을 낮춰보는 것은 절대 아니기에 오해 없기를 바란다.). 그때 배우는 좋은 관리자가 되는 길이라고 해봐야 대부분 비슷한 이야기 뿐이다. "코치가 되려고 노력해야 하며, 보스가 아닌 리더가 되라"는 것이다. 팀원 들과 대화를 많이 해야하 고, 그들이 일을 즐길 수 있는 환경을 만들어야 한다는 이상적인 이야기 뿐이다. 그런 리더가 있으면 좋지만 그렇지 않은 리더가 많은 이유가 그 때문이다. 좋은 리더보다 더 드문 것은 "훌륭한 과제 관리자"다. 그들의 가치는 과제를 성공으로 이 끄는 핵심이며, 그들의 가지는 전문적인 기술은 교육을 통해서 전달할 수 있기에 중요하다. 투자를 하려면 좀 더 목적이 확 실한 곳에 하는 것이 옳은 방향이 아닐까? 30 · [ 프로페셔널 프로그래머 ]
  • 31. 관리자가 되기 위해서는 과제 관리 방법을 알아야 한다. 예를 들어, 과제의 일정을 산출하거나, 해야할 일을 정리하는 WBS(Work Breakdown Structure)를 만들어 낼 수 있어야 한다. 하지만, 대부분의 경우 일정 산출은 자신의 경험에 의 지하는 부분이 많으며, 과제의 기능이나 난이도, 인력 구성, 마일스톤에 따른 기능의 우선 순위 등등은 충분히 고려하지 않 는다. WBS도 대부분의 경우 간트 차트(Gantt Chart)정도만 생각하고 툴을 이용해서 그때 수정할 뿐, 거의 일정 관리 목 적으로만 사용하는 것이 현실이다. 우리는 실제로 과제에 대한 관리 방법에 대해서는 문외한 이면서도 나름 자신은 과제 관리에 대해서 철학이 있다고 생각하고 있는지도 모른다. 그렇다고 모든 사람이 PMP(Project Management Professional) 자격증을 따라는 것은 아니다. 적어도 “성공할 가능성이 높은 과제 관리 방 법”에 대해서 체계적인 교육이 필요하며, 그것을 통해서 상위 관리자들도 과제의 개발자 역할을 할 때와 다른 관점에서 과 제를 바라보아야 한다는 것을 익혀야 한다. 개발자가 진급해서 관리자가 되지만, 그렇게 성장한 관리자는 과제 관리에 대 한 좋은 경험과 지식은 가지지 못한체로 역할을 맡게 된다. 당연히 제대로 된 과제 관리자가 되지 못한다. 리더가 되건 보 스가 되건 상관없이 “과제 관리”는 항상 진행해야 하는 업무다. 소프트웨어 개발은 벌써 50년이 넘는 역사를 가지고 있다. 물론, 다른 분야에 비하면 터무니없이 짧은 것도 사실이다. 하 지만, 50년의 시간동안 과제 관리자들이 놀고만 있었던 것은 아니고, 수많은 실패 사례를 분석해서 나름의 성공적인 방법 론들을 만들어 왔다. 애자일(Agile)도 어떻게 보면 그런 실패의 산물인지도 모른다. 실패를 했기에 더 나은 방법이 있는지 찾아 보았을 것이고, 실패를 했기에 성공하는 방법에 대해서 아낌없이 투자를 했던 것이다. 애자일이 만병 통치약은 아니 지만, 그렇다고 자신의 과제에 적용하지 못할 이유도 없다. 예를 들어, 기능별 구현 전략이나 조기(Early) 테스트, 상호간의 대화를 통한 문제 발견 및 해결 노력, 지속적인 개선과 자기주도적인 팀원 들의 개발 참여 등은 모든 과제에서 유용한 방 법이다. 아쉬운 것은 경험하지 않은 것에 대한 막연한 실패의 두려움과 터무니 없는 일정을 주고도 “열심히”만 강조하는 관 리자들의 마인드다. 물론, 그들 나름의 고민도 있고 성과 지향이라는 어쩔 수 없는 부분도 있지만, 그렇다고 “우물에서 숭 늉을 찾는다”는 말이 되어서는 안될 것이다. 31 · [ 프로페셔널 프로그래머 ]
  • 32. - 훌륭한 과제 관리자를 만나는 것은 그 자체가 축복이다.- 32 · [ 프로페셔널 프로그래머 ]