다양한 아기발걸음으로 배우기
지난 주에 있던 일이다. 동료 중국 개발자에게 모듈 개념 구현을 설명하기 위해 코드 리뷰를 했다. 코드를 보며 다룬 대화의 내용을 대략 묘사하면 아래 그림과 같다.
모듈화의 기준은 무엇인가?
애초에 M(앞서 언급한 중국 개발자)이 짠 코드는 위 그림과 조금 차이가 있었다. M이 짠 코드는 Tenancy 모듈(우리는 REST API를 제공하는 웹 서비스를 모듈이라 부른다)에 접근할 때 파라미터로 태넌트 ID를 주면서 특정 택배사가 우리 시스템에 발급해준 key 값을 받아왔다. 내가 M에게 조언한 것이 바로 위 그림처럼 '외부 시스템이 발급한 key를 Tenancy에 넣지 말고 택배사 식별자 정도로 수정하자'는 내용이다. 이해를 돕기 위해 그림을 조금 바꾼다.
그림에서는 택배사를 하나만 그렸지만, 현재 사용하는 택배사가 3곳이고, 향후 변경 가능성이 있다. 그리고, 우리가 다루는 태넌트(tenant)는 수십개 규모다. 혹시 택배사가 특정 태넌트의 키(key)를 바꾼다 가정해보자. 위 그림처럼 하면, 태넌트 키는 Shipping 모듈에서 다루기 때문에 이곳만 수정하면 된다. 애초 M이 짠 코드라면, Tenancy 모듈에서 해당 경우를 찾아 매번 수정해줘야 한다. 대화과정에서 M은 이렇게 코드가 얽혀 있으면(tightly-coupled) 배송 관련 내용이 바뀔 때마다 Tenancy 모듈 변경이 필요하다는 사실을 본인 운영 경험에 기초해 이해했다. 그리고, 이런 코드는 의례 코드량도 방대하고 경우의 수가 많아 복잡해짐을 미루어 짐작했으리라.
아기발걸음과 Separation of Concerns
한편, M이 임춘봉훈장님 추천으로 객체지향분석설계 책을 공부하고 있었기에, 앞서 설명한 원칙을 지칭하는 말이 뭐냐고 물었다. 책 내용과 자기 일을 연결지을 수 있는지 확인하고, 그런 습관을 알려주기 위한 의도였다. 이때, 내 머리속에 들어있던 말은 관심사 분리(Separation of Concerns)였는데, M의 입에서는 아기 발걸음이란 말이 나왔다. 작년부터 이 친구들과 함께 하면서 내가 무수히 많이 반복하고 강조했던 말이었다. 그런 이유로 이 친구들에겐 나와 아기 발걸음을 연상짓는 것은 무리가 아니었다. 일단, 나는 틀리지 않다고 말했다. 다만, 아기 발걸음 대신 관심사 분리로 볼 수도 있다고 답했다. 아기 발걸음은 행동하는 주체 입장에서 쓰는 말이고, 다루는 주제 자체를 두고 이야기하면 관심사 분리라고 부연했다. 다음날 M은 코드를 수정하기 시작했다. 그리고, 이 일을 잊을 수밖에 없는 바쁜 일상이 이어졌다. :)
인텔리J에서 파일을 생성하는 깨알같은 차이
그 후 토요일 아침 마침 여유가 있어 노트북을 펼쳤다. 인터넷 상에 있는 간단한 React.js 튜토리얼을 따라해보려고, 동료에게 물어 즐겨찾기만 해두고 한참 미룬 일을 했다. 동료들이 쓰는 React.js에 대해 조금은 알아야 그들의 말에 공감할 수 있고, 그래야 관련 이슈를 이해할 수 있기 때문이다. 인텔리J를 몇 달만에 열었더니 사용법이 가물가물했다. 자연스레 내 작업은 코딩과 인텔리J 메뉴 확인이 혼재되었다. 이러는 중에 자바스크립트 파일 하나를 만들려고 아래와 같이 메뉴를 실행시켰다.
이때, 머리속에서는 이렇게 물었다.
여기서 그냥 엔터 키를 쳐서 빠르게 파일(File)을 만들고 확장자를 .js로 붙이는 것이 좋을까 아니면 다운키를 네번 더 눌러서 JavaScript File 생성 기능으로 만드는 편이 좋을까?
생각을 멈추고 일단 후자를 택했다. 다음 번에 파일을 하나 더 만들어야 해서 이번에는 전자의 방법을사용했다. 둘을 비교하니 키를 네 번 더 눌러서 내가 얻을 수 있는 것은 아래와 같은 자동 생성 파일 주석이었다. 첫번째 방법을 쓰고 확장자 이름을 .js로 붙여주면 다른 기능은 똑같이 적용되었다. 상충 관계(trade-off)를 이해하는데 매우 효과적인 방법이었다.
여기까지 작업할 때는 이런 경험을 굳이 아기 발걸음과 연결하지 못했다.
실수는 학습의 스승(or driver)
토요일 오전 한가로운 코딩 과정에서 느낀 생각과 M과 코드 리뷰에서 나눈 경험이 연결되는 순간은 따옴표 하나 잘못 써서 발생한 디버깅 과정에서 시작되었다. 내가 따라하던 튜토리얼 내용은 이것(https://velopert.com/921)인데, 아래와 같이 코딩하고 결과를 확인했더니 문제가 생겼다.
1 2 3 4 5 6 7 8
render() { return( <div> <Header title="{this.props.headerTitle}" /> <Content title="Tony" /> </div> ); }
한참동안 원인을 못찾다가 다시 코드를 원래로 돌리고 하나씩 수정해서 오류를 확인했다. 위 코드는 원래 아래와 같이 썼어야 했다.
1 2 3 4 5 6 7 8
render() { return( <div> <Header title={this.props.headerTitle} /> <Content title="Tony" /> </div> ); }
그리고, 원인을 알고 나니 비로소 무턱대고 따라하던 마음 자세가 바뀌었다. 문제 원인을 몰라 답답해하며 여기저기 수색하느라 불안정했던 내 마음은 매우 차분해졌다. 마치 평온한 내리막 길을 자전거를 타고 가는 기분과도 같았다. 편안하게 튜토리얼에 나온 내용을 단계적으로 수정해가며 학습 상황을 스스로 잘 통제[1]하고 있다고 느꼈다.
이런 편안한 경험에서 나는 아기 발걸음을 떠올렸다. 또, 테스트 주도 개발에서 실패(Fail)를 먼저 겪도록 하는 이유도 이와 같을 것이라고 기억을 소환했다. 테스트 주도 개발 흐름은 아기 발걸음 원칙을 적용한 전형적인 사례라 할 수 있다. 2015년 이후 아기 발걸음이라는 원칙을 삶에 투영하려는 내 노력은 일상의 경험속에서 습관을 바꿔나간다. 작게는 위와 같이 코딩하는 짧은 시간 속에서도 이뤄지고, 개발자를 돕는 과정에서도 벌어진다. 더 크게는 작년에 시작한 나의 역할과도 연관지어진다.
아기 발걸음과 나의 일
작년 3월 중국에서 일을 시작했다. 일의 목표를 한 마디로 기술하면, 조직을 바꾸고 싶어하는 이곳 경영자의 도전을 돕는 일이다. 작년 초만 해도 이 회사는 하나의 통합 데이터베이스와 기다란 프로시져로 만들어진 프로그램인 탓에 수정이 어려운 전형적인 레거시 시스템 운영조직이었다. 나는 과거 다년간의 (실패) 경험으로 문제의 본체인 레거시 시스템(혹은 여러 시스템중에 가장 핵심인 레거시 시스템)을 종심타격해야 한다는 사실을 알았다.
하지만, 경험에 의해 감으로 돌진했을 뿐, 종심타격 방법을 알고 있었던 것은 아니다. 계획에 집착하는 사람들은 결코 이해하지 못하는 진실이 바로 여기에 있다. 나는 조직 구성원 중에서 하고자 하는 의지가 간절한 사람들에게 내가 생각하는 돌파방법을 이야기하고, 그들이 할 수 있는 것을 돕는 식으로 함께 해왔다. 그들이라고 지칭하는 사람들은 경영자외에도 다양한 역할을 하는 사람들이다. 물론, 가장 긴 시간을 함께 하는 것은 개발자와 경영자였지만, 그들 외에 테스터와 관리자와도 상당한 시간을 함께 했다. 또한, 통역을 하거나 인사팀에 속한 사람들과도 함께 문제를 풀었다.
아무튼, 그렇게 1년 하고 5개월이 지난 지금 돌아보니 종심타격 방법이 조금 선명해졌다. 바로 레거시 시스템이 해야 할 일부 기능을 빠르게 구현해서 레거시 시스템의 새로운 일부가 되는 것이었다. 우리가 문제라고 여겼던 레거시 그 속으로 깊이 들어가야만 해결이 가능하다는 당연한 사실을 삶을 구성하는 순간들을 통해 배운 것이다.
차세대 프로젝트가 실패하는 이유
최근 8년 전에 참여했던 프로젝트 지인 연락을 받았다. 당시 의뢰인(필자는 당시 구축 프로젝트 컨설턴트였다)이었던 모기업 IT 운영 책임자는 망설이고 망설이다가 차세대 프로젝트를 하시기로 결정하고, 도움을 청해왔다. 나는 구두로도 비슷한 의도로 말씀을 드렸으나 당시에는 즉흥적 대화로 명료하게 뜻을 전하지 못했다. 생각이 미친 김에 다시 한번 글을 빌어 왜 차세대 프로젝트를 하지 말아야 하는지 말씀드리려고 한다.
차세대 프로젝트[2]는 외부인력이 주도하여 문제를 파악하고 시스템을 완전히 새로 만드는 방법을 취한다. 하지만, 현재 존재하는 시스템에 깊이 침투하여 문제 자체를 명확하게 학습하지 못하면, 해결책을 얻을 수 없다. 문제를 모르는데, 어떻게 해결한다는 말인가? 한국에서 지난 10여년 상식처럼 여겨졌던 차세대 프로젝트는 열심히 하고 못하고를 떠나, 차세대 프로젝트를 한다는 그 자체로 이미 잘못된 길을 가는 것이다. Solution-First라고 불러도 좋을 외산 방법론(CBD, MDD 방법론, MDM 등)이나 솔루션(SAP, Oracle, 미들웨어 등) 납품을 우선해서 시스템을 구축하는 과거의 접근은 문제 파악에는 아무런 도움이 되지 않는다. 어떤 솔루션을 도입했는지에 관계 없이 문제 파악을 충분히 하지 않고, 다시 만들면 문제를 지극히 피상적[3]으로만 파악한 후 해답을 찾으려하여, 결과적으로 도리어 문제를 회피하는 효과를 낳는다.
외산 기술을 빠르게 모방하는 소프트웨어 후진국의 과오를 빨리 인지하고, 이제는 우리의 문제를 정확히 인지하고 자신들의 노하우를 소프트웨어 형태로 축적하는 방법을 익혀야 한다. 그런 이들만이 과거를 빠져나와 후진을 면할 수 있다.
카뱅 신드롬과 차세대 프로젝트
SNS를 통해 접하는 지인들 소식이나 한국 뉴스를 보면 인터넷 전문은행인 카카오뱅크 이야기가 큰 화제다. 내 또래 소프트웨어 개발자에겐 짜릿한 현상이다. 15년, 20년씩 개발을 좋아해 이 일을 해왔던 이들에겐 도리어 긴 부조리속에서 기대했던 (당연한) 일이 벌어진 것이다. 반면에 소프트웨어 개발을 잘 모르는 대다수 사람들이 이해하기는 매우 어려운 일이 아닐까 싶다. 모은행장이 카뱅처럼 하자고 목소리를 높였다고 하는데, 그 방법을 (아주) 조금이라도 알고 있을까? 모른다면 (아마 모른다는 사실을 모를 수도 있지만) 결과를 빨리 내려하고 조급해하기 보다는 일단 알아가는 과정에 초점을 맞춰야 한다. 안그러면 결과를 내기는 커녕 평생 모르고 인생을 끝낼 수도 있다.
끝으로, 프로그래밍을 모르는 관리자나 경영자들이 시스템에 대한 의사결정을 해야 할 때, 최소한 위키피디아에서 시스템의 뜻을 찾아보고 깊이 생각해보기를 권한다. 아직도 시스템이 유기적이라는 사실을 일상에서 몸으로 배우는 내가 이 글에서 힌트를 2개 드리겠다. 왜 나는 인사팀이나 통역하는 친구들과도 함께 무언가를 했느냐는 점이 하나의 힌트다. 두 번째는 카뱅과 달리 대부분의 은행은 단시간에 절대로 카뱅처럼 할 수 없다는 사실이다. 그 이유는 아주 간단하다. 은행이 프로그램 대부분을 직접 만들지 않기 때문이다. 그래서, 그들은 자신들의 진짜 문제를 잘 모를 가능성이 매우 높다.
주석
[1] 따옴표를 넣다가 뺐다가, 호출하는 컴포넌트에서 호출되는 컴포넌트 옮겨가며 Props 값을 넣다가 뺐다가 하며 기대값과 결과를 확인하기
[2] 차세대 프로젝트란 회사의 중요한 업무 시스템을 외부 회사에 개발을 맡겨서 완전히 새롭게 만드는 일을 의미합니다.
[3] 여기서 피상적이란 시스템 자체에 존재하는 문제를 존재 형태에 준해서 이해하지 않고, 프로그램 배포 형태나 테이블 구성 정도의 대강의 윤곽수준의 조사나 관련자 탐문 정도로 문제를 파악하는 수준을 의미