brunch

You can make anything
by writing

C.S.Lewis

by 개앞맵시 이복연 Dec 05. 2022

더 나은 개발자를 꿈꾸며 걸어온 길..

(주니어 개발자를 위한) 좋은 소프트웨어 엔지니어링이란?

★ <구글 엔지니어는 이렇게 일한다> 발표를 듣고 한 주니어 개발자께서 다음과 같은 질문을 던져주셨습니다.

좋은 소프트웨어 엔지니어링이란?

주니어 개발자로서 당장 시작할 수 있는 것은?


이번 글은 이 분을 위해 정리한, 제가 걸어온 길입니다. 


안타깝게도 저는 개발자로서 대단한 업적을 남기지 못했습니다만, 그렇기에 보통의 주니어 개발자 분들께 메시지를 전달하기에는 더 적합하리라 기대해봅니다.




저는 소프트웨어 엔지니어링 전공자가 아닙니다. 학부 때 수업조차 듣지 않습니다. 돌이켜보면 그저 고품질의 소프트웨어를 최대한 효율적이게 개발하고 싶어 한 평범한 개발자였습니다. 그러다 보니 깔끔한 코드와 더 효과적인 구조에서 시작하여, 점차 도구는 물론 일하는 방식(프로세스와 개발 문화)에까지 시야가 넓어졌습니다. 당장의 문제를 개선하는 방법을 고민하고 익히다 보니 자연스럽게 관련된 다음 분야를 접하게 되는 식으로 영역이 확장되었습니다.


이제부터 제가 ‘더 나은 개발 방법’을 향해 걸어온 길은 되짚어보겠습니다. 너무 옛이야기기도 하고, 그리 대단하지도 않아서 큰 도움은 안 될 겁니다. 소시민 개발자가 작게 시작하여 조금씩 발전해가는 모습을 보시며 “소프트웨어 엔지니어링이란 게 꼭 그리 거창해야 하는 건 아니구나. 나도 당장 실천할 수 있겠네라는 정도만 느끼고 가시면 저는 만족합니다. ^^



첫 프로그램의 다잉 메시지

먼저, 제가 처음으로 제대로 된 소프트웨어를 개발한 건 중1 여름방학 때였습니다. 형과 함께 밤잠 안 자가며 타일 기반의 그래픽 소프트웨어를 개발했죠. 8086(XT) 컴퓨터에서 언어는 GW 베이직을 썼고, 보름 정도 걸린 거로 기억합니다. 형과 함께(we) 만든 그래픽(graphic) 소프트웨어라고 해서 ‘Wegra’라고 불렀습니다. 당시 컴퓨터 잡지 <마이크로소프트웨어>의 ‘나의 자랑 나의 프로그램’ 코너에 실린 유사 프로그램보다 뛰어나다고 스스로 생각했습니다. (<마이컴>이었나?)


대략 아래 정도 느낌의 프로그램이었습니다.


타일들을 먼저 만들고, 도장 찍듯 캔버스에 찍어 그림을 완성하는 형태였죠. 당시 유행하던 쿼터뷰 방식 게임의 맵 같은 걸 만들며 놀았습니다. 위 그림에선 참고용으로 고전 명작 게임 <울티마 6>의 화면을 잘라 붙였습니다. CGA 시절이라 제가 만든 건 4 컬러였습니다. ㅎㅎ


학교에 가져가서 친구들에게 자랑도 하고 재미있게 가지고 놀다가 2.0 버전을 만들 계획을 세웠습니다. 그런데 2.0 코딩을 시작한 지 얼마 되지 않아 1.0을 저장해둔 디스켓에 덮어써버리는 실수를..


짧게 생을 마감한 이 프로그램이 지금 제 ID가 되었고, 제 첫 작품에서 버전 관리의 중요성을 몸소 체험하여 훗날 버전 관리 도구라는 개념을 접하자마자 바로 사용하게 된 계기가 되었습니다.



객체지향과 리팩터링

베이직, 어셈블러, C 정도를 접해보았던 대학 1학년 여름방학. 객체지향이란 무엇인가 궁금하여 서점에 가서 C++와 자바 책들을 훑어보았습니다. 몇 권을 읽다 보니 ‘아하!’ 하는 순간이 오더군요. 개념이 아주 재미있어서, 한동안은 객체를 규정하고 역할을 나누는 일에 흠뻑 빠져 살았습니다.


동작하는 코드를 만들고, 개선하고, 개선하고, 개선하는 일을 반복했습니다. 체계가 잡히진 않았고 개념도 없었지만, 리팩터링을 열심히 반복한 것이죠. 이 과정에서 코드의 설계를 보는 눈이 많이 개선되었다고 느꼈고, 그때의 제 개발 방식을 ‘적극적 시행착오 수련법’이란 이름으로 정리해두기도 했습니다.



디자인 패턴과 개발 프로세스

객체 설계에 빠져 살다 보니 자연스럽게 ‘객체지향 분석 설계’라는 주제가 눈에 들어왔습니다. 또 책을 몇 권 읽게 되었는데, 그중 <Applying UML and Patterns>라는 책이 큰 감명을 주었습니다. 하나의 프로젝트를 점진적으로 완성시켰는데, 이터레이션을 돌며 새로운 기능을 추가하가나 다양한 디자인 패턴을 적용하여 기존 설계를 개선했습니다. 이를 통해 GoF의 패턴과 GRASP 패턴을, 그리고 이터레이티브 프로세스를 체계적으로 익힐 수 있었습니다.



버전 관리와 지속적 통합 도구를 쓰다

버전 관리 ‘도구’를 본격적으로 사용하기 시작한 건 2000년으로 기억합니다. 제대 후 학업과 병행하며 다닌 회사 덕분입니다. 그 회사에서 사용하던 Visual Age for Java라는 도구에는 로컬 히스토리(local history)라는 기능이 기본으로 제공되었습니다. 정확히 기억나진 않지만 중앙의 버전 관리 도구로는 마이크로소프트의 비주얼 소스세이프를 사용했을 겁니다. 지금 생각하면 상당히 원시적인 버전 관리 도구지만, 내 첫 작품인 Wegra를 날려먹은 기억 때문에 존재 이유를 즉각 깨달을 수 있었죠.


그 후 삼성 소프트웨어멤버십에 들어가서는 친구 한 명과 함께 멤버십 서버에 CVS를 설치하고 사용법을 설파했습니다. 지금은 Git을 사용하는 게 너무 당연하지만, 당시에는 버전 관리라는 개념을 모르는 사람이 의외로 많았습니다. 소스 코드를 보관하던 하드 디스크가 깨져서 회사가 파산하는 일이 실제로 일어나던 시대입니다.

Apache Ant를 접한 시기도 대략 이 즈음입니다. 어떻게 알게 되었는지는 기억나지 않지만 버전 관리 도구 관련 글을 읽다가 자연스럽게 접했을 수 있겠네요. 어쨌든 이를 활용해 빌드와 테스트를 자동화했고, 리눅스 crontap울 써서 빌드가 주기적으로 진행되게 했습니다.


저는 졸업 후 SE 조직 내의 품질 보증(QA) 팀부터 시작하여 기회를 잡지 못했지만, 소프트웨어멤버십 때 저와 함께 CVS 등을 설파한 친구는 팀 내에 지속적 빌드를 구축하고 다른 팀들에도 전파하는 성과를 거두었습니다.


참고로 제가 QA팀부터 시작한 이유는 향후 제가 만들 제품들에 대해 ‘이건 내가 만들었다’라고 자신 있게 이야기할 수 있었으면 해서였습니다. 품질이 떨어지면 안 된다고 생각해서 이 기술부터 익혀두려 했습니다. 그래서 처음 들어갈 때부터 2년 후에는 개발 팀으로 옮길 것이라고 당당히 이야기했습니다.



핵심은 사람이다

시간을 약간 거슬러 올라서.. 다시 대학생 때입니다. 소프트웨어 설계와 프로세스, 버전 관리 등 협업을 위한 개념을 많이 익혀 한창 자신감도 있고 써먹어보고 싶었던 거 같습니다. 프로젝트를 기획해서 친구들과 역할을 나눠 개발을 진행했습니다. 멋진 콜라보와 결과를 기대했지만 안타깝게도 기대한 만큼의 협업이 이루어진 프로젝트는 없었습니다.


물론 학생들끼리 반 취미로 하는 프로젝트가 잘 진행되면 오히려 이상했을 수도 있죠. 하지만 제가 그때 깨달은 건 ‘내가 팀원들을 모듈처럼 생각했구나’였습니다. 흥미로운 프로젝트, 말끔한 설계, 체계적인 프로세스를 준비했으니 팀원들이 제 생각대로 움직여주리라 착각한 거죠. 그들이 프로젝트에 무엇을 기대하는지, 실제로 얻어갈 수 있는 건 무엇인지, 개인적인 관심사는 무엇인지, 학교 일이 얼마나 바쁜지 등등.. 사람 자체에 대해서는 전혀 관심이 없었습니다.


이런 데 관심이 있었다 한들 얼마나 달라졌을까 싶지만, ‘핵심은 사람이다’라는 사실을 본격적인 사회생활 전에 깨달았다는 게 참으로 다행이라고 생각합니다. 물론 핵심이 사람임을 깨닫는 것과 '사람을 이해하는 것'은 전혀 다른 이야기입니다. ^^ 사람을 그마나 이해하게 된 건 개발자 경력 막바지가 되어서였고, 지금도 사람은 정말 어렵습니다.



IDE를 스토킹하다

학생 때 저는 자바를 주력 언어로 삼았습니다. 완전 초창기에는 UltraEdit라는 텍스트 에디터를 쓰다가 IBM Visual Age for Java를 거쳐 이클립스로 옮겨왔죠.


지금에 와서 보면 평범한 오픈 소스 개발 방식일 수 있지만, 이클립스 개발 방식은 당시 저에게는 매우 신선했습니다. 그때 기준으로는 상당히 짧은 주기(2개월이었던 듯)로 안정된 마일스톤 버전을 릴리스하면서, 릴리스마다 새 기능들을 ‘New and Noteworthy’라는 이름으로 깔끔하게 정리하여 공개했습니다. 릴리스 노트와 비슷하지만, 새로운 기능을 사용자 눈높이에서 소개하고 사용법을 알려주는 문서였습니다.


신기능을 써보는 게 재미있어서 매번 챙겨봤는데, 어떤 기능이 왜 들어갔는지를 살펴보다 보면 자연스럽게 ‘기존 방식’과 ‘더 나은 방식’이 비교됩니다. 특히 리팩터링 기능들이 한창 추가되던 시기였어서 개선 전/후 코드를 비교하며 장단점을 배우게 되었죠. 유용한 기능은 바로 써보며 기존 제 코드도 되돌아보는 기회로도 제격이었습니다.


이 경험을 계기로, 도구에 추가되는 기능의 의미를 생각해보는 게 개발 역량을 키워줄 수도 있다는 걸 깨달았습니다. 다른 사람은 어떤 도구를 쓰는지, 어떤 점이 좋아서 그 도구를 선택했는지를 알아보는 일도 역시 같은 이유로 역량 개선에 도움이 됩니다.



정적 분석 도구를 개인 교사로 고용하다

제가 정적 분석 도구를 처음 접한 시기와 계기는 정확히 기억나지 않습니다. 아마도 IDE를 스토킹하는 과정에서 각종 플러그인들을 살펴보는 과정에서 사용하기 시작한 게 아닌가 싶습니다. 어쨌든 언제부터인가 저는 개인 프로젝트에서 항상 Checkstyle과 Findbugs를 사용하고 있었고, 설정을 익스포트하여 다른 팀원에게도 권했습니다.


정적 분석 도구를 처음 적용했을 때는 충격이었습니다. 습관적으로 리팩터링하고, 유용한 기능은 항시 일반화하여 라이브러리로 만들어 쓰던 저였는데.. 잠재적 버그를 참 많이도 찾아내더군요.


코드 리뷰나 짝 프로그래밍이 제대로 이루어지지 않던 시기라, 저를 제외하고는 제 코드를 관심 있게 분석해준 첫 주체가 바로 정적 분석 도구들이었습니다. 코드의 어떤 부분이 어떤 경우에 문제가 생길 수 있고, 그래서 어떻게 고치면 더 나은지를 친절하게 알려줬습니다. 멋진 스승이자 사수였죠.


당시 C/C++용 분석 도구들은 false alarm이 많아 생산성을 저해한다는 이야기도 많았는데, 자바는 달랐습니다. 정확도가 거의 100%였죠. 그리고 자바에서 배운 게 다른 언어에도 적용되는 사례가 많았으니, 저는 운도 조금 좋았던 거 같습니다.



애자일을 일찍 혹은 뒤늦게 깨우치다

더 나은 개발 프로세스는 영원한 제 관심사였습니다. 하지만 SE 조직에서 개발팀으로 옮긴 후로 소프트웨어 공학 주제의 책이나 자료를 따로 보지는 않았습니다. 대신 실무를 뛰며 주변에서 목격되는 문제들을 푸는 일에 소소하게 계속 관심을 두었죠. SE 조직에 있을 때, SE 조직 구성원 대부분이 이론은 빠삭하지만 실무 경력이 전무하여 괴리를 많이 느낀 것도 주된 원인이었을 겁니다.


어쨌든 저는 학생 때부터 프로세스에 관심이 많았고, 이터레이티브 방법론의 본질을 꽤나 정확하게 꿰뚫고 있다고 생각했습니다. ‘사람이 핵심’ 임도 학생 때 이미 깨우쳤고요. SE를 공부한 건 개발을 제대로 하기 위해서였지, SE 이론이 궁금해서가 아니었습니다.


개발팀으로 옮긴 후로도 시간이 제법 지나고, 처음으로 작은 팀의 리더가 되었습니다. 몇 개월 후 열리는 국제 행사 때 전시할 데모 프로그램을 만드는 시한부 프로젝트였지만, 우리나라뿐 아니라 인도에서 근무하는 팀까지 함께 이끌며 미국 회사의 PC용 서비스를 모바일로 옮기는 작업을 하게 되었죠.


시간대가 다른 세 지역에 분산되어 있는 개발자들을 이끌며 저는 코드를 매일 빌드하고, 엔진과 전체 앱의 안정 버전을 격주로 교차 릴리스하면서 한 번도 일정을 지연시키지 않았습니다. 저는 요구사항을 명확히 정의/공유하고, 릴리스된 모듈의 정상 동작 여부를 바로 검증하고, 제기된 이슈는 모두 다음날 실무자들이 출근하면 결론이 나와 있도록 했습니다. 실무자들이 자신의 전문 분야와 관련한 문제라면 직접 결정하고 결과만 통지하도록 했습니다. 결과에 대한 책임은 제가 지고요. 엔지니어들이 외부 요인 때문에 블록되는 시간을 최소로 줄이려는 의도였습니다. 물론 저와 함께 일한 엔지니어들이 우수했고, 인도 팀에도 훌륭한 리더가 있었기에 가능했다고 생각합니다.


당시 저는 익스트림 프로그래밍, TDD, 애자일 같은 용어를 들어는 봤지만 진지하게 고민한 적은 없었습니다. 과거 리팩터링 개념도 모르고 어설프게나마 리팩터링을 반복했듯, 애자일을 몰랐지만 이미 많은 면에서 애자일스럽게 움직였습니다. 애자일보다 훨씬 넓은 개념의 개발 프로세스를 공부했고, 실무에서 어떻게 응용할지를 고민하다 보니 비슷한 결론에 도달했을 겁니다.


실제로 한 세미나에서 세계적 방법론 대가께서 ‘기존 프로세스도 애자일하다’라고 이야기할 때 저는 당연하다고 생각했습니다. 단지, 너무 많은 경우의 수를 따져서 완전정복 식으로 이야기하는 게 문제였죠. 분량에 압도되어 핵심이 무엇인지 알 수 없게 한달까요? 핵심을 알고 나면 그 외의 것들은 처한 상황에 맞게 꺼내 쓸 수 있는 거대한 도구 상자가 되어줍니다.


이 프로젝트 후 얼마 지나지 않아 스크럼 책을 한 권 읽게 되었습니다. 그동안 제가 약간의 지식과 조금의 현장 경험을 토대로 그려온 미천한 생각들을 깔끔하게, 훨씬 훌륭하게 정리해뒀더군요. 출발점이 달랐더라도, 지향점이 같다면 비슷한 결론에 도달하는 것 같습니다.



마침내 지속적 통합

앞서 Ant와 crontab으로 만든 지속적 통합을 개인 프로젝트에 적용해보았다고는 했으나, 회사 실무에서 활용하기까지는 몇 년이 더 지나야 했습니다.


조직 바꾸기 실패/성공 사례 모음에서도 언급한 이야기입니다. 당시 저는 꽤 큰 조직에 속해 있었습니다. 빌드는 make를 이용했고, 개발 브랜치가 5~10개는 되었을 겁니다. 그래서 통합 때마다 며칠은 기본이고 심하면 일주일도 넘게 지연되었죠.


저는 사태가 이 정도까지 되기 전에 지속적 빌드를 제안했습니다. 하지만 팀에 경험자가 없어서인지, 지연이 별다른 문제가 아니라고 생각했던 것인지.. 아무튼 중요하게 다뤄지지 않았습니다.


그렇게 몇 년이 흐르고 문제는 점점 심각해지기만 했습니다. 지금 진행 중인 통합이 끝나면 추가하려던 기능을 6주 후에나 합칠 수 있었던 적도 있습니다.


그러다가 지속적 통합을 구축해본 사람이 합류하였고, 저는 다시 한번 도입을 제안했습니다. 다행히 이번에는 모든 게 잘 맞아떨어졌습니다. 전보다 문제가 훨씬 심각해졌고, 그 사이 지속적 통합 도구도 많이 발전했고(Jenkins의 전신인 Hudson이 쓰이던 시절), 구축 경험자까지 합류했으니까요. 일단 구축되면 팀원들이 배워야 할 것도 많지 않아서, 팀이 완전히 적응하기까지도 오랜 시간이 필요하진 않았던 걸로 기억합니다.


제가 직접 구축한 건 아니지만, 변화를 꼭 제가 주도해야 하는 건 아니죠. ^^ 더 좋은 방향으로 나아가는 데 조금이나마 힘을 보탰고, 혜택은 모두가 누리게 되었습니다.



마치며

지금까지 제가 개발자 시절에 걸은 소프트웨어 엔지니어링 여정의 스냅샷을 몇 개 살펴봤습니다. 업계를 일찍 떠나서 할 이야기가 많지 않은데, 또 민감할 수도 있는 내용은 생략해야 해서 살짝 아쉽습니다.


어쨌든.. 혹시 눈치채셨는지요? 이 과정에서 제가 ‘소프트웨어 엔지니어링을 해야지’라며 달려든 적은 없습니다. 처음에도 이야기했듯이 항시 ‘올바르고 효율적으로 고품질의 소프트웨어를 개발’하고 싶었을 뿐입니다. 그러다 보니 자연스럽게 주변에 관심이 생기고, 더 나은 방법을 찾게 되고, 이것저것 시도해보며 조금씩 깨달음을 얻은 것 같습니다.


그러면서 중심은 항상 ‘사람’ 임을 잊지 않으려 노력했습니다. 사람 중에서도 관리자보다는 실무자를 초점에 뒀습니다(제가 그 위치여서 더 그랬을 겁니다). 개발 방식을 바꾸고 문화를 바꾸려면 결국 사람을 바꿔야 합니다. 그런데 다른 사람을 바꾸는 건 정말 어려운 일이죠. 최소한의 변화로 확실한 효과를 얻을 수 있어야 그나마 조금씩이라도 움직입니다. 그래서 실질적인 혜택을 주어야 하며, ‘정말 더 좋군’이라고 스스로 느끼게 만들어야 합니다. 저는 이 부분을 잘 해내지 못했습니다. 실무자 중에는 동조하는 사람이 제법 되었지만, 관리자까지 끌어들이긴 쉽지 않았습니다. 저도 일개 팀원일 뿐이었는데.. 너무 조급했습니다. 그래서 혼자서는 제법 발전한 듯하지만, 함께 변화한 경험은 많이 부족합니다.


지금은 개발 업계를 떠났지만, 사람이 모여 만든 조직은 대체로 비슷함을 느낍니다. 좋은 문화를 전파한다는 건 결국 사람들을 변화시키는 일입니다. 나 스스로도 변화하기 어려운데, 남을 변화시키기란 훨씬 어려운 게 당연하겠죠. 이어서 다음 글에서는 ‘좋은 문화 만들기’의 방법론적인 이야기를 간략히 정리해볼까 합니다. (정리 글)

브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari