소프트웨어 개발의 이념 전쟁: 개발자는 왜 그런가요?
과거 냉전 시대의 공산주의와 자본주의처럼 양립할 수 없는 두 가지 이념이 소프트웨어 개발 분야에 존재한다. 바로 원리주의와 실용주의다. 소프트웨어 개발은 매우 복잡한 과정이며, 이 두 가지 이념은 각기 다른 방식으로 문제에 접근한다. 따라서 원리주의와 실용주의는 소프트웨어 개발의 성패를 좌우하는 중요한 요소라 할 수 있다.
원리주의자들은 체계적인 소프트웨어 개발 이론을 바탕으로 개발을 진행해야 한다고 믿는다. 이들은 유지보수의 중요성을 강조하며, 장기적인 관점에서 신중하게 코드를 작성할 것을 주장한다. 반면 실용주의자들은 문제를 최대한 간단하고 빠르게 해결하는 데 초점을 맞춘다. 소프트웨어는 복잡하기 때문에 아무리 신중하게 코드를 작성해도 효과가 없다고 생각한다. 그래서 초기에 많은 시간을 투자하기보다는 문제가 발생할 때마다 즉각 대응하는 것이 효율적이라고 믿는다.
대부분의 개발자는 극단적인 원리주의와 실용주의 사이 어딘가에 위치하겠지만 이 글에서는 극단적인 원리주의 개발자와 실용주의 개발자에 초점을 맞춰서 설명한다. 이들의 상반된 관점과 접근 방식, 그리고 협업 과정에서 발생하는 문제들을 살펴본다.
1. 원리주의 팀원
1.1 실용주의 팀장과의 갈등
성장 욕구와 열정이 넘치는 주니어 개발자는 원리주의적 성향을 보일 가능성이 높다. 이런 원리주의 팀원이 원리주의 팀장을 만나면 행복하겠지만 현실은 원리주의 팀원과 실용주의 팀장의 조합이 더 많다.
실용주의 팀장에 속한 원리주의 팀원은 개발팀에서 힘든 위치에 놓일 수 있다. 팀장에게 코드 리뷰를 기대하지 못하는 것은 당연하고 팀장이 일정을 재촉하기 때문에 코드 품질에 신경 쓸 여력도 없다. 일정에 여유가 있어서 리팩토링을 하더라도 팀장의 눈치를 봐야 한다. 원리주의 팀원은 문제가 발생하면 그 원인이 무엇인지 파악하고 올바르게 조치하기 위해서 노력한다. 그런데 실용주의 팀장이 원인을 무시하고 문제를 쉽게 해결할 수 있는 방법을 제시할 수 있다.
이런 일이 반복되면 원리주의 팀원은 답답함을 느낀다. 팀장의 역량과 책임감이 부족하다고 여기게 된다. 팀장에게서 배울 것이 없고 존경할 만한 업무 태도도 아니라고 생각하기 때문에 팀장을 무시하는 언행을 하기도 한다. 팀장도 그것을 느끼고 원리주의 팀원을 감정적으로 대한다. 원리주의 팀원은 정신적으로 점점 힘들어지고 결국 퇴사를 하게 된다. 그렇지만 회사를 옮겨도 결국 높은 확률로 실용주의 팀장을 만나게 되기 때문에 원리주의 팀원의 어려움은 쉽게 해결되지 않는다.
1.2 성장을 저해하는 프로젝트
원리주의 팀원은 성장 욕구가 강한 만큼 회사의 업무가 자신의 성장에 도움이 되지 않는다고 생각하면 초조해 할 것이다. 성장에 도움이 되지 않는 일은 기술부채가 잔뜩 쌓인 코드를 유지보수 하거나 신규 개발이라도 오래되거나 대중적이지 않은 기술을 사용하는 프로젝트가 있다.
이런 상황에서 실용주의 팀장이라면 현재 상황을 유지하려는 경향이 강하기 때문에 대규모 리팩토링이나 신기술 도입을 가능한 피하려고 할 것이다. 원리주의 팀원이 대안을 제시해도 수용하지 않을 것이다. 첫 단추를 잘 꿰어야 하듯이 주니어 시절의 프로젝트가 개발자의 성장 방향에 큰 영향을 줄 수 있다. 맞지 않다고 생각되면 과감하게 팀을 떠나는 것도 나쁘지 않다.
그러나 팀장이 원리주의 성향이라면 기다리는 것을 추천한다. 현재 프로젝트에 기술적인 문제가 많다면 새로 만들 기회가 생길 수도 있다. 그렇게 되면 기존 프로젝트를 유지보수 하면서 도메인과 요구사항을 파악했기 때문에 기술에 더 집중할 수 있는 환경이 될 것이다. 물론 원리주의 팀원 자신이 그런 프로젝트를 맡을 수 있을 만큼 준비가 되어있어야 한다.
1.3 원리주의 팀원에게 전하고 싶은 말
원리주의 팀원에게 이런 말을 전하고 싶다.
“회사는 학원이 아니다.”
회사는 내 시간과 기술을 팔고 돈을 받는 곳이다. 회사에서 하고 싶은 일만 할 수는 없다.
나는 잦은 이직을 하고 여러 팀장을 만나면서 내 뜻을 존중해 주는 팀장도 있었지만 그 중에서 두 번은 극단적인 실용주의 팀장이었다. 이 극단적인 실용주의 팀장은 자신감과 열정이 넘치는 어린 팀원이 마음에 들지 않았는지 노골적으로 견제하는 모습을 보여주기도 했다. 그래도 나는 팀원의 입장에서 최대한의 존중을 했다고 생각한다. 팀장과 갈등을 겪고 있을 때 다른 팀원들에게 내가 뭔가 잘못했냐고 여러차례 물어봤지만 단지 둘이 안 맞아서 그렇다는 대답이 대부분이었다.
지금 생각해 보면 실용주의 팀장 자신의 개발 역량이 뒤쳐지는 것을 불안해 하는 와중에, 원리주의 팀원이 디자인 패턴이나 리팩토링 같은 개발 이론을 공공연하게 떠들고 다니면서 그 불안감을 더 자극한 것은 아닐까 싶다. 그래서 실용주의 팀장의 눈에 자신감 넘치고 눈치는 없는 팀원이 곱게는 안 보였을지도 모른다.
2. 원리주의 팀장
원리주의 팀원의 열정이 계속 된다면 대체로 원리주의 팀장이 된다. 팀장이라고 했지만 프로젝트의 주도권을 갖고 개발하는 위치에 있다면 여기에 해당한다.
2.1. 오버 엔지니어링
원리주의 팀장은 미래 대비에 지나치게 집착하는 경향이 있다. 이는 과도한 추상화, 불필요한 디자인 패턴의 적용 등의 오버 엔지니어링으로 나타난다. 이것은 오히려 코드의 복잡성을 높이고 개발 효율성을 저하시키는 결과를 초래한다. 유지보수를 위한 원리주의가 오히려 유지보수성을 해치는 비극이 되는 것이다.
이런 오버 엔지니어링은 관리자에게 답답함과 불안감을 느끼게 한다. 원리주의 팀장이 설계의 중요성을 강조하면서 열심히 하고는 있는데 눈에 보이는 결과물이 없으니 일정이 무척 걱정된다. 프로젝트 초기에는 시간 여유가 있어서 믿고 기다려 보지만 한계점에 이르면 적극적으로 일정을 관리하게 된다.
원리주의 팀장이 미래 대비를 철저히 할수록 프로젝트 전체를 통찰하는 데에는 약할 수 있다. 그런데 설계와 기술연구에 많은 시간을 소비한 상태에서 프로젝트 중간에 요구사항이 크게 변경되거나 미처 파악하지 못한 기술적인 문제가 드러나면 어떻게 될까?
원리주의 팀장은 이런 문제의 원인이 개발팀 외부에 있기 때문에 자신의 책임이 아니라고 생각할 수 있다. 그리고 이런 문제에 대비하는 것은 불가항력이기 때문에 프로젝트 기간을 늘리거나 기능을 줄이는 것이 합리적이라고 생각할 수 있다. 그러나 관리자는 이런 변화나 문제에 쉽게 대응하지 못한다면 왜 설계에 많은 시간을 할애했는지 납득할 수 없을 것이다.
이렇게 되면 관리자 입장에서는 유지보수야 어찌됐든 당장의 생산성이라도 높은 실용주의 팀장의 개발 방법이 더 나을 수 있다. 원리주의 팀장은 그런 관리자의 평가를 납득하지 못한다. 좋은 품질을 위한 자신의 노력이 부정당하는 것에 답답함을 느낀다.
일부는 내 이야기다. 나는 새 프로젝트를 시작하면 항상 기술적인 도전 과제를 설정하고는 했다. 이번 프로젝트에서는 TDD나 DDD를 적용해 보는 식으로 말이다. 이 도전이 얼마나 많이, 또 오래 지속되는지는 관리자의 피드백에 달렸다. 대체로 프로젝트를 시작하고 한 달이 넘도록 제품 개발은 더디고 기술 연구만 하고 있으면 개발 진행이 더디다는 관리자의 주의가 주어진다.
2.2. 오버 프로세싱
오버 프로세싱은 과도하게 형식적이고 비효율적인 개발 프로세스를 뜻한다.
오버 엔지니어링이 관리자를 힘들게 한다면 오버 프로세싱은 팀원들을 힘들게 하는데, 주로 다음과 같은 것들이 있다.
- 지나치게 형식적이고 자세한 개발 문서 요구
- 지나치게 엄격한 코딩 규칙 적용
- 테스트 커버리지에 대한 강박
원리주의 팀장은 높은 테스트 커버리지를 달성하기 위해 팀원들에게 과도한 테스트 작성을 요구하곤 한다. 물론 테스트는 중요하지만, 무작정 커버리지 수치를 높이는 데에만 집중하다 보면 오히려 코드의 유연성이 떨어지고 테스트 코드 자체가 복잡해져서 유지보수가 어려워진다.
원리주의 팀장의 올바른 개발 방법론 주장에 팀원들은 많은 기대를 할 수 있다. 그러나 얼마 지나지 않아 원리주의 팀장의 지나치게 체계적인 접근과 꼼꼼한 계획 요구에 팀원들은 지칠 것이다.
원리주의 팀장의 관리가 느슨하다면 팀원들은 조금씩 지시를 무시하기 시작할 것이다. 반면, 관리가 철저하다면 팀장 자신이 코딩할 시간이 줄어드는 것은 물론이고, 팀원들의 사소한 잘못들을 지적하게 된다. 팀원들은 사소한 지적에 압박감을 느낄 것이고, 원리주의 팀장은 팀원들의 부족함에 답답함을 느낄 것이다.
원리주의 팀장의 지나친 요구사항들은 때로는 팀장 자신도 완벽하게 해내기 어려운 업무일 수 있다. 특히 소프트웨어 설계는 복잡하고 추상적인 개념을 다루기 때문에, 자신의 아이디어를 명확하게 문서화하는 것조차 쉽지 않다. 그런데도 원리주의 팀장은 경험이 부족한 팀원들에게 제대로 된 가이드라인도 없이 설계를 요구하곤 한다. 이는 마치 초등학생이 독후감을 써야 하는 것만큼이나 팀원들에게는 막막한 일이 될 수밖에 없다.
새 회사에 팀장으로 합류했을 때였다. 이전 팀장이 열정 넘치는 원리주의자였는지 팀원들에게 테스트의 코드 커버리지 100%를 요구했다고 한다. 물론 100%를 유지하는 것은 좋은 목표다. 문제는 함수마다 테스트를 꼼꼼하게 작성해서 작은 변경에도 많은 테스트가 깨진다는 것이다. 함수는 독립적으로 실행되는 것이 아니라 다른 함수를 호출하고 호출된다. 그래서 테스트는 유지보수와 생산성 등을 고려해 적절한 단위로 작성되어야 하는데, 이 부분이 간과된 것으로 보인다.
결과적으로 테스트 코드가 1/10로 줄어들면서 팀원들은 더 적극적으로 테스트 코드를 작성하게 됐다.
2.3. 문제의 원인
원리주의 팀장은 가장 많은 시행착오를 겪는 시기인데, 이는 권한에 비해 실력과 경험이 부족하기 때문이다. 개인에 따라서는 넘치는 자신감이 문제를 더 키우기도 한다.
열정과 자신감은 어느 정도 상관관계가 있기 때문에, 열정이 넘치는 원리주의 팀장은 높은 자신감을 가지는 경향이 있다.
높은 자신감은 문제의 원인을 다른 사람에게서 찾게 만들고, 강한 자기 주장을 하게 만들기도 한다. 이런 언행은 관리자와 동료들에게 큰 부담이 되는데, 본인은 그것을 알지 못한다.
마지막으로, 원리주의 팀장에게 이런 말을 전하고 싶다.
“하고 싶은 일이 아니라, 해야 하는 일을 해라”
하려는 일이 꼭 필요한 일인지 냉정하게 자신의 생각을 돌아봐야 한다. 원리주의 팀장은 본능적으로 하고 싶은 일을 해야 하는 일이라고 합리화 하는 경향이 있다.
3. 실용주의 팀원
원리주의 팀원은 회사 일을 성장의 기회로 삼으려고 하는 반면에 실용주의 팀원은 회사의 일을 경제 활동으로 받아들인다. 그래서 문제가 있을 때 원리주의 팀원은 과도한 노력을 기울이게 되고 실용주의 팀원은 최소한의 노력으로 문제를 해결하려고 한다.
실용주의 팀원은 다양한 유형이 있다.
첫 번째 유형은 성실하지만 개발에 대한 열정은 낮은 경우다. 이런 유형은 원리주의 팀원이 힘들어 하는 일을 잘 할 수 있기 때문에 개발에 대한 열정이 낮은 것이 단점은 아니다. 개발에 대한 욕심이 적은 만큼 문제를 일으키는 일도 적어서 무난하게 회사 생활을 할 수 있다.
두 번째 유형은 성실하고 개발에 대한 열정도 높은 경우다. 나는 이런 유형의 개발자를 만났을 때 처음에는 이해가 되지 않았다. 개발에 대한 열정이 높다면 원리주의 팀원이 될 것 같은데 유지보수에 대한 관심이 없다. 문제점을 지적하고 몇 번 가이드를 해도 결국은 최소 비용으로 문제를 해결한다.
이런 유형의 실용주의 팀원은 개발에 대한 순수한 열정이라기 보다는 일에 대한 열정이 높은 것이고 필요에 의해서 개발에 관심을 갖는 경우인 것 같다. 그러다 보니 더 좋은 회사로 이직하는 데 도움이 되는 기술을 우선해서 학습하는 경향이 있다. 실용주의 팀원이 디자인 패턴을 공부한다면 그것이 궁금하기 보다는 면접에서 문제로 나올 수 있기 때문이다. 그래서 깊이있게 학습하지는 않는다. 알고리즘도 열심히 학습하는데 코딩 테스트에 필요하기 때문이다.
세 번째 유형은 일에 대한 열정이 낮은 경우다. 이런 경우 보통은 회사 업무가 마음에 들지 않아서 동기부여가 되지 않는 원리주의 팀원인 경우가 많다. 혹은 그냥 일 자체에 관심이 없는 경우다.
열정이 낮아도 일만 제대로 한다면 팀장과 갈등은 크지 않을 것이다. 문제는 일이 하기 싫으니 책임을 점점 소홀히 한다는 것이다. 예를 들어 코드를 변경하면 테스트를 꼼꼼히 해야 하는데 테스트는 커녕 빌드만 해서 완료 보고를 하는 경우다. 또는 지시한 일만 수동적으로 수행할 뿐 스스로 일을 찾아서 하지는 않기 때문에 팀장의 관리 비용이 높아진다. 이런 일을 반복하면 다른 사람과의 관계도 안 좋아질 것이다.
어떤 유형이든 실용주의 팀원은 개발자로 성장하기 힘들다. 한 회사에 오래 머물면서 중간 관리자가 되는 것이 보통이다. 그런데 중간 관리자가 되는 것은 쉽지만 차별화되는 장점이 없다면 그 자리를 끝까지 지키는 것은 어려울 수 있다. 관리자가 된 것을 후회하는 경우를 많이 봐온 입장에서 자신이 원하는 방향이 무엇인지 심사숙고 하기를 조언한다.
실용주의 팀원에게 이런 말을 전하고 싶다.
“쉽고 편한 길은 없다. 고민하는 만큼 성장한다.”
실용주의 팀원은 효율을 우선하기 때문에 고민의 기회가 적다. 그러나 인간 관계든 개발이든 고민하는 만큼 성장할 수 있고 성장하는 만큼 차별화를 이룰 수 있다.
4. 실용주의 팀장
많은 개발자들이 실용주의 팀장이 되는데 실용주의 팀원은 물론이고 원리주의 팀장도 실용주의 팀장이 될 수 있다. 실용주의 팀원이 실용주의 팀장이 되는 것은 자연스러운데, 원리주의 팀장이 실용주의 팀장이 되는 것은 무슨 말일까?
원리주의 팀장이 OOP, 디자인 패턴, TDD, DDD, MSA 등 많은 개발 방법론과 아키텍처를 학습하지만 실제 프로젝트에 적용하기는 쉽지 않다. 이런 방법론과 아키텍처는 서로 이어져 있어서 프로젝트에 적용하려면 정말 많은 노력과 경험이 필요하다.
예를 들면 MSA(Microservices Architecture)를 올바르게 적용하려면 현대적인 개발 방법의 근간인 OOP와 디자인 패턴은 물론이고 DDD(Domain-Driven Design)를 잘 알아야 한다. 그런데 현실은 OOP와 디자인 패턴조차 제대로 깨닫지 못하는 경우가 보통이다. TDD(Test-Driven Development)도 OOP/디자인패턴은 기본이고 도메인에 대한 이해와 유연한 설계가 가능해야 한다.
이 정도 수준에 이르지 못하면 학습했던 개발 방법론을 실제 프로젝트에 적용하는 것은 힘들다. 프로젝트에 적용해 봤으나 결국 문제만 키우는 경험을 몇 번 하고나면 개발 방법론을 현실과 동떨어진 이상론으로 치부하게 된다.
그래서 실용주의 팀장의 눈에 원리주의 개발자는 아직 현실을 모르고 그럴듯한 이론에 빠져서 헛된 시간을 보내는 것으로 보인다. 실용주의 팀장은 주변에서 개발 방법론의 중요성을 외치는 많은 동료들을 봐왔지만 개발 일정만 늦어질 뿐 딱히 품질이 좋아지는 경우를 본 적이 없다. 그래서 원리주의 팀원의 노력을 시간 낭비로 보고 한심하게 여기기도 한다.
실용주의 팀장은 기술에 관심이 적은 만큼 요구사항 분석과 일정 관리에 더 많은 노력을 기울인다. 그 과정에서 자연스럽게 관리자로 전향하게 된다.
나는 실용주의 팀장이 코드 리뷰와 같이 적극적으로 기술 리드를 하는 경우를 본 적이 없다. 팀원들에게 모듈 단위로 일을 할당하고 결과를 확인하는 정도가 보통이다. 팀원이 해결하지 못하는 기술적인 문제가 발생하면 직접 해결하기도 하지만 팀원이 늘어가면서 관리자에 조금씩 가까워지는 것 같다.
실용주의 팀장이 관리자로 전향하는 이유 중에 하나는 개발이 새롭지 않고 반복적이기 때문이다. 실용주의 팀장은 새로운 기술이나 방법론을 학습하지 않기 때문에 개발 과정도 과거와 크게 달라지지 않는다. 이런 반복적인 작업에 염증을 느끼고 관리자가 되는 경우도 종종 보게 된다.
내 경험에 실용주의 팀장은 SI 같은 1년 미만으로 진행되는 프로젝트에서 좋은 성과를 낼 수 있다. 그러나 프로젝트가 1년 이상 지속되면 품질 관리가 어려워지면서 관리자도 문제가 있는 것을 눈치채기 시작할 것이다.
그런 실용주의 팀장이 자사 프로덕트를 개발하게 되면 계속 다시 만드는 전략을 취하기도 한다. 그러니까 코드를 계속 개선하는 것이 아니라 프로젝트가 일정 수준에 다다르면 복잡해진 기존 코드는 그대로 두고 처음부터 새로 만들기 시작하는 것이다. 이렇게 조금씩 기능을 확장해 나가는 전략을 취하는데 반복하는 주기는 보통 1~3년 정도라고 생각된다.
실용주의 팀장이 프로덕트를 다시 만드는 일 없이 몇 년 동안 유지하는 경우도 있다. 개발 담당자가 바뀌지 않는 경우인데 그 담당자가 퇴사하면 유지보수 능력이 급락하게 되고 결국 다시 만들어야 하는 상황이 된다.
마지막으로, 실용주의 팀장에게 이런 말을 전하고 싶다.
“할 수 있는 일이 아니라, 해야 하는 일을 해라”
떄로는 원인을 알 수 없는 버그로 많은 연구와 시행착오를 겪어야 할지도 모른다. 단순히 문제를 덮기 위한 코드를 작성한다면 대부분은 다른 형태로 더 큰 문제가 되어서 돌아온다.
5. 마이크로 관리자
마이크로 관리자(Micromanager)는 조직 내에서 구성원들의 업무 수행 과정에 지나치게 관여하고 통제하려 하는 관리자를 말한다.
마이크로 관리자는 크게 두 가지 배경으로 나뉜다. 하나는 개발자였다고 주장하는 관리자이고, 다른 하나는 개발 경력은 없지만 어느 정도 안다고 생각하는 관리자다. 이들의 공통점은 자신이 충분히 안다고 착각하는 것이다.
마이크로 관리자가 자신의 실력을 과신한다는 점에서 원리주의 팀장과 비슷한 면이 있는 만큼 원리주의 팀장의 문제점을 일부 공유하는데 대표적으로 철저한 설계와 문서 작성 요구가 있다. 차이가 있다면 관리자인 만큼 프로젝트와 조직 전체에 미치는 영향이 더 크다는 것이다.
마이크로 관리자는 직접 개발을 하지 않기 때문에 쉽게 원리주의적 접근을 선택기도 한다. 이는 관리자가 개발 현장에서 벗어나기 때문에 현실적인 제약보다는 이상적인 접근을 선호하게 되는 경향 때문이다.
보안 관련 회사에서 팀원으로 일했을 때의 일이다.
회사 서비스의 품질이 지속적으로 하락하자 관리자는 각 팀장에게 설계 문서를 작성하라는 지시를 내렸다. 당시 C++로 작성된 소스 코드는 한 개 파일이 50k 라인을 넘을 만큼 복잡하게 얽혀있었다. 설계를 기반으로 구현하는 것이 기본인데, 관리자가 제시한 해결책은 구현을 기반으로 설계 문서를 작성하라는 것이었다.
결국 개발팀은 약 3주 동안 설계 문서를 작성하다가 중단하고 말았다. 비극은 이 지시를 내린 관리자는 개발자들의 실력이 부족해서 자신의 지시를 따르지 못한다고 생각한다는 것이다.
개발팀의 역량 강화가 필요한 상황이라면, 관리자가 직접 개입하는 대신 역량 있는 개발자를 충원했어야 한다.
관리자와 팀장은 각자의 역할이 있다. 팀장이 관리자가 되어서는 안 되겠지만, 관리자도 팀장이 되려고 하면 안 된다. 관리자가 팀장의 역할을 하면 팀장은 자신의 역량을 제대로 발휘할 수 없고 관리자도 관리 업무에 집중할 수 없게 된다.
경험상 관리자가 개발을 직접 리드하는 것은 불가피한 상황이라기보다는 본인의 희망에 따른 선택인 경우가 많다. 쉽게 말하자면, 개발 리드가 관리자의 취미생활처럼 여겨진다. 현명한 관리자라면 팀장을 교체하거나 팀의 업무를 조정할 것이다.
이런 말이 있다.
“의인불용 용인불의(疑人不用 用人不疑)”
중국 사서 송사(宋史)에 나오는 말로, 의심 나는 사람은 쓰지 말고 쓴 사람은 의심하지 말라는 뜻이다.
특정 정보를 서비스하는 회사에서 팀원으로 일했을 때였다. 이 회사의 개발팀은 8명 내외였고, 대표는 명석한 인물이었으며 개발 팀장은 열정과 실력을 갖춘 존경받는 개발자였다.
내가 이 회사에서 일하던 당시, 대표는 개발 과정에 적극적으로 개입했지만, 창업 초기였기 때문에 서비스 장애가 발생해도 서로 이해하는 분위기가 있었다.
몇 년 후 퇴사하고 다시 찾아갔을 때, 개발 조직은 크게 바뀌어 있었다. 기존 개발자들은 독립된 공간에서 각자 명확하지 않은 업무를 하고 있었고, 중요한 업무는 대표가 직접 구성한 새로운 개발팀이 맡고 있었다. 이유를 물어보니, 대표가 품질 문제를 지속적으로 제기하다가 결국 자신이 직접 개발 리드를 선언하고 새로운 팀을 꾸린 것이었다.
대표가 개발 리드를 하면서 얻은 것은 또 한 번의 큰 시행착오뿐이다. 이 경우에도 대표는 자신의 기준을 만족시킬 수 있는 개발자를 채용했어야 했다.
6. 원리주의 팀장과 실용주의 팀장의 갈등
한 프로젝트에서 원리주의 팀장과 실용주의 팀장이 원만한 협력 관계를 유지한다면, 이는 그들이 싸울 여력이 없을 정도로 큰 위협이 존재한다는 의미이다. 예를 들어, 고객의 심한 갑질이나 고압적인 마이크로 매니저와 같은 상황이 있을 수 있다.
그것이 아니라면 API 설계 등 협력이 필요한 부분에서 원리주의 팀장과 실용주의 팀장은 사사건건 의견이 충돌할 것이다.
6.1. 원리주의 팀장의 입장
원리주의 팀장은 실용주의 팀장이 자신의 발목을 잡는다고 생각한다.
실용주의 팀장은 API를 설계할 때 자신의 코드 변경을 최소화 하는 쪽으로 주장한다. 결과적으로 API가 직관적이지 않아서 이해하기 어렵고 원리주의 팀장이 더 많은 작업을 해야 한다.
프로젝트가 진행되면서 새로운 API가 필요하지만 실용주의 팀장은 기존 API를 사용할 수 있다면 비록 사용하기가 좀 불편하더라도 기존 API를 고수한다.
이렇듯 원리주의 팀장은 실용주의 팀장이 자신의 편의만을 추구하며 통찰력을 비롯한 개발 역량이 전반적으로 부족하다고 생각한다.
실용주의 팀장의 의견을 계속 따르면 결국 프로젝트에 큰 문제가 생길 것이라는 불안함을 떨치기 어렵다.
프로젝트의 설계가 오래되고 구조적 문제를 안고있지만 이것을 해결하기 위한 대규모 리팩토링 계획에 실용주의 팀장은 반대만 한다.
이렇게 단순한 개발 전략은 자신의 성장에도 도움이 되지 않는다.
6.2. 실용주의 팀장의 입장
실용주의 팀장은 원리주의 팀장이 쓸데없이 일을 벌린다고 생각한다.
원리주의 팀장은 자신도 완벽하게 다루지 못하는 기술을 무리하게 도입함으로써 프로젝트를 불필요하게 복잡하게 만든다.
개인의 성장에만 집착한 나머지 프로젝트의 일정이나 성공은 뒷전으로 미룬다고 생각한다.
원리주의 팀장과 API를 합의했는데도 불구하고 원리주의 팀장이 계속해서 조금씩 변경을 요청할 수 있다. 원리주의 팀장이 디테일에 지나치게 집착하면서 프로젝트의 진행을 방해한다.
대규모 리팩토링이나 다시 만들어야 한다는 주장을 하지만 그런다고 해서 딱히 좋아질 것 같지 않고 좋아진다는 보장도 없다.
6.3. 마이크로 관리자의 중재
마이크로 관리자는 의견 충돌이 발생하면 양측의 의견을 듣고 논리적으로 판단할 수 있다고 생각한다.
비록 마이크로 관리자는 공정하고 객관적으로 판단하려고 하겠지만, 이런 상황은 이미 원리주의 팀장이 불리한 입장에서 시작하게 된다.
무언가를 변경하려거나 새로운 기술이나 방법론을 적용하려는 것은 원리주의 팀장이다. 따라서 원리주의 팀장은 자신의 논리를 소프트웨어 개발 이론과 섞어가면서 장황하게 설명해야 한다.
반면에 실용주의 팀장은 가능한 변화를 최소화 하거나 간단한 해결책을 선호하기 때문에 자신의 논리를 쉽게 설명할 수 있다.
그래서 둘의 논쟁이 시작되면 실용주의 팀장은 원리주의 팀장의 주장에 ‘왜요?’라고 묻기만 하면 된다. 원리주의 팀장이 어지간한 지식이 있어도 실용주의 팀장의 ‘왜요?’ 공격을 방어하기는 쉽지 않다. 어느 순간 설명하기 어려운 지점에 이를 것이다. 더군다나 개발 지식이 부족한 마이크로 관리자까지 이해를 시켜야 하기 때문에 원리주의 팀장은 2:1로 논쟁하는 입장이 된다.
원리주의 팀장 자신도 제대로 알지 못하는 개발 이론을 마이크로 관리자에게 설명해봤자 설득력은 없을 것이다. 마이크로 관리자는 막연히 그럴듯 하다고 느낄 뿐이다. 결국 마이크로 관리자가 처음 생각했던 논리적인 판단은 어려워지고, 서로의 감정을 고려한 적절한 타협안을 제안하는 것이 보통이다.
마이크로 관리자는 이런 일이 반복되면 이해하기 쉬운 실용주의 팀장의 의견으로 기울게 된다. 더군다나 결과물도 비교적 빨리 확인할 수 있으니 마다할 이유가 없다.
혹은 마이크로 관리자가 둘이 잘 협의하라는 지시와 함께 중재를 포기하는 경우도 있는데, 이것은 최악의 선택이다. 마지막 브레이크마저 사라진 두 팀장의 갈등은 극한으로 치닫고 프로젝트를 무사히 마치지 못 할 것이다.
6.4. 해결 방안
애초에 두 팀장이 치열하게 논쟁해야 하는 상황을 만든 것은 마이크로 관리자다. 마이크로 관리자 자신이 팀장들을 중재할 수 있다는 착각과 개발을 리드하고 싶은 욕심이 합쳐져서 최종 결정권을 자신이 가졌을 확률이 높다.
이런 둘을 중재할 수 있는 것은 압도적인 경험과 역량을 갖춘 상위 기술 책임자 뿐이다. 정확하게는 상위 기술 책임자가 개발 팀장을 주도적으로 리드해야 한다. 개발 팀장들이 협의를 한다는 것은 상위 기술 책임자가 없기 때문이다. 문제는 일반적인 개발 팀장들이 납득할 수 있는 압도적인 경험과 역량을 갖춘 상위 기술 책임자를 찾는 것이 쉽지 않다는 것이다.
상위 기술 책임자가 없는 상황에서 관리자가 둘을 직접 중재하는 것은 어렵고 그렇다고 어느 한 쪽을 편들자니 다른 쪽이 반발하는 것이 부담스럽다. 그러나 손실을 각오하고 프로젝트의 특성에 따라서 명확하게 한 쪽에 책임과 관한을 부여하는 것이 장기적으로 좋을 것이다. 단기 외주 프로젝트라면 실용주의 팀장이 리드하고 지속적인 개선이 필요한 자사 프로덕트라면 원리주의 팀장이 리드하도록 해야 한다.
유럽에 본사를 둔 어느 회사에 근무했던 경험이다.
이 회사는 상당히 큰 온라인 서비스를 개발하고 있었다. 여기에는 여러 개발팀이 하나의 서비스를 만들고 있었고 QA팀도 따로 있었다. 주목할만한 것은 아키텍트 팀이 있고 거기서도 최상위 아키텍트가 있었다는 것이다.
이렇게 설계,구현,테스트로 조직이 나뉘어져 있었기 때문에 개발에 들어가기 전에 아키텍트, 개발팀, QA팀이 모여서 설계와 테스트 방법에 대해서 논의한다.
이 회사에서 인터페이스를 포함한 설계에 대한 결정은 아키텍트 간에 이뤄졌기 때문에 개발팀 간에 불협화음을 찾기 어려웠다. 설계에 대해서 개발팀장과 아키텍트 사이에 의견이 다를 수는 있지만 설계 권한과 책임은 아키텍트에 있었기 때문에 문제가 되는 경우는 없었다.
7. 결론
원리주의와 실용주의가 다툼의 원인은 아니다. 이념에 차이가 있어도 서로에 대한 신뢰만 충분하다면 서로를 존중하며 프로젝트를 잘 진행할 수 있을 것이다.
다툼은 인간이기에 갖게 되는 개인 감정과 욕심 때문에 발생한다. 개인 감정과 욕심으로 인해 이해관계가 충돌하면 틈이 생기기 마련인데 서로 다른 이념이 이 틈을 크게 벌리는 것 뿐이다.
관리자 입장에서는 실용주의 개발자의 주장이 유용하게 생각될 것이다. 그런데 실용주의 개발을 계속했을 때 회사가 어떤 모습일지를 신중하게 고민해 봐야 한다.
원리주의 팀장의 개발 방식은 당장 성과가 나오는 것이 아니고 자기 주장도 강하고 오버 엔지니어링으로 비용이 높아진다. 이런 시행착오를 회사가 감당하지 못하고 실용주의로 흐른다면 결국 실용주의 개발자만 남을 것이다. 실용주의 개발자가 다수를 차지한 상황에서 관리자가 품질에 문제의식을 느끼고 원리주의 개발자를 채용해봤자 기존에 자리잡은 실용주의 팀장들의 텃새를 버티기는 힘들 것이다.
그렇다고 원리주의 개발자가 다수를 차지하면 연구에 전념하거나 실험적인 기술을 도입하면서 생산성이 급격하게 떨어질 수 있다. 개발 방법론에 대한 이해도 완전하지 않기 때문에 소프트웨어 품질이 크게 좋아지는 것도 아니다.
소프트웨어 품질을 중요하게 여기는 관리자는 원리주의 개발자의 시행착오가 어느 정도 가치를 가진다고 생각한다. 그러나 원리주의 개발자의 성장은 생각보다 더딜 수 있다.
이런 문제를 해결하려면 적어도 한 명의 유능한 상위 기술 책임자가 있어야 한다. 상위 기술 책임자는 원리주의 개발자의 시행착오를 크게 줄일 수 있고 실용주의 개발자를 적재적소에 배치할 것이다.
상위 기술 책임자를 확보할 수 없다면 결국 회사가 개발하는 제품의 성격에 따라서 개발자의 성향을 선택해야 할 것이다. 자사 프로덕트라면 실용주의 개발자는 최소화 해야 한다. 단기 외주 프로젝트라면 원리주의 개발자를 최소화 해야 한다. 기술부채가 쌓일수록 유지보수가 어려워지는 것처럼 당장 개발자가 부족하다는 이유로 채용 부채를 쌓게 되면 개발 조직의 유지가 어려워질 것이다.