brunch

You can make anything
by writing

C.S.Lewis

by 정주홍 Oct 12. 2020

한 번 할 때 잘하자

소프트웨어 개발을 하다 보면 이전에 만들어뒀던 코드를 다시 보고 수정해야 할 일이 정말 많다. 크게 경우를 나눠보면 1. 예상치 못한 작동이 발생해서, 2. 새로운 기능을 추가로 개발해야 해서 정도일 것 같다. 나는 두 가지 경우 모두 "한 번 할 때 잘하는 것"이 중요하다고 믿는 편이다. 애자일(agile)하게 고객에게 제품을 전달해야 한다는 이유로 잘 지켜지지 않는 경우가 많은데 어느 정도 가치관의 문제도 포함된다는 것을 염두에 두고 글을 읽어주시길 당부드린다.


예상치 못한 작동이 발생하는 경우는 버그를 포함한 경우를 쓴 것이다. 버그가 발생한 경우라고 쓰지 않은 이유는 실제로 개발할 때 입력과 출력을 모두 생각해내기 쉽지 않기 때문이다. 알고리즘 문제를 푸는 경우만 생각해봐도 예상치 못한 입력에 의해 시간복잡도가 만족되지 않는 경험을 할 수 있다. 실세계에서는 정말 다양한 입력이 발생한다. 웹 페이지를 개발하는 경우를 생각해보자. 사용자는 온갖 환경에서 다양한 시나리오로 서비스를 이용한다. 소위 말하는 행복 경로(Happy Path)로만 서비스를 이용하지 않기 때문에 예상치 못한 사용자의 행동(입력)이 발생할 수 있고, 그로 인해 기대치 않은 작동(출력)이 발생하는 것이다.

소프트웨어 내에서의 문제가 없더라도 환경에 의해 문제가 발생할 수 있다. 확장성의 문제가 여기에 포함된다. 예를 들어 MySQL table에 사용자 행동 로그를 저장하는 경우를 생각해보자. DB 서버의 성능에 따라 일정 규모까지는 문제없이 운영될 것이다. 하지만 트래픽이 점점 더 많아짐에 따라 더 이상 원래의 DB 서버로는 버티지 못하게 된다. 평상시와는 다를 바 없는, 동일한 입력이 발생했지만 기대되는 출력을 하지 못하게 되는 것이다.

새로운 기능을 추가로 개발해야 하는 경우는 거의 항상 발생하는 일이라고 봐야 한다. 고객에게 더 큰 가치를 제공하기 위해 업데이트를 계속해나가야 하기 때문이다. 기존과 비슷한 요구 사항을 추가로 제공하기 위한 작업이면 괜찮지만 아주 다른 요구 사항을 만족시켜야 하는 경우엔 굉장히 고통스럽게 된다. 당장 기능 개발은 해야 하니까 예외 처리나 하드 코딩 등으로 상황을 모면할 순 있지만 이것이 반복되면 더 이상 유지 보수를 하기 어려운 코드가 된다.


예상치 못한 입력에도 견고한 소프트웨어를 만들기 위해서는 깊게 고민을 해야 하는데 그럴 시간이 없었을 수 있다. 더 큰 규모가 됐을 때도 잘 버틸 수 있는 구조로 개발을 해둘 수 있는 여유가 없었을 수도 있다. 예상치 못한 입력이나 더 큰 규모를 아예 경험해본 적도 없을 수 있다. 밀려오는 요구 사항을 당장 만족하는 업데이트를 해야만 하는 상황이었을 수 있다. 따라서, 이것을 기술 부채라 말할 수도 있을 것이다.

개인적으로는 그럼에도 불구하고 개발할 때 더 정성을 들여야 한다고 믿는다. 현실적으로 기술 부채를 갚는 시간 같은 건 절대 따로 생기지 않는다. 항상 해야 할 일들은 쌓여있기 때문이다. 시간이 생기면 오히려 가성비 좋은 다른 어떤 일을 해야 한다. 수많은 기술 부채들 중 가성비 좋은 일로 선정되는 일은 잘 없다.

그렇기 때문에 개발을 할 때 당시에 더 잘 개발해야만 한다. 그때만큼은 그 일에 가장 집중할 수 있는 상태이기 때문이다. 지금 작성하고 있는 코드가 나중의 변화에 유연하게 대처할 수 있는 코드인지, 다양한 입력에도 강건하게(보통 Robust 하다고 한다) 작동하는 코드인지 등을 고민해야 한다. 이렇게 하는 것은 개발자의 역량과 직접적인 연관이 있다. 역량 있고 경험 많은 개발자라면 그동안의 경험에 비춰 좋은 코드를 작성할 수 있기 때문이다. 또한, 도덕적인 문제도 연관된다. 이렇게 정성 들여 개발하는 것은 당장의 요구 사항만 만족하는 코드를 작성하는 것보다 훨씬 많은 시간이 들기 때문이다.


오히려 나는 당장 작동하는 소프트웨어를 배포하기보다 좀 더 시간을 들이는 것을 권하는 편이다. 매우 역량 있는 개발자가 아니라면 금방 작성한 코드에 빈틈이 많은 경우가 잦기 때문이다. 그로 인해 자꾸 유지 보수를 해야 하는 상황이 발생하면 오히려 더 큰 손해가 된다. 왜냐하면 사람이 동시에 여러 일을 완벽하게 할 수 없기 때문이다. 흔히 아는 문맥 전환 비용이 그것이다. 

예를 들어, Infra와 관련된 작업을 하다가 과거에 개발해둔 Worker에 문제가 생겼다는 것을 알게 됐다고 하자. 당장 수정이 필요한 문제라면 기존에 진행하던 작업을 그만두고 Worker의 코드를 들여다봐야 한다. 오랜만에 다시 보는 코드는 적응의 시간을 요구한다. 만약 굉장히 복잡한 비즈니스 로직이거나 독특한 요구 사항이 있는 경우 당시에 왜 그렇게 코드를 작성했는지 잘 기억하기 어렵다. 테스트가 잘 작성되어 있었으면 다행이지만 그렇지 않을 경우 또다시 End to End 테스트와 QA를 하는 과정이 필요하다. 

이것이 반복되면 무시할 수 없는 시간 소모가 된다. 그렇기 때문에 처음 개발할 때 좀 더 시간을 들여 잘 개발해두는 것을 주장하는 것이다. 코드를 처음부터 잘 짜기 어렵다면 개발할 때 어떤 시나리오가 존재하는지, 어떤 고민들이 있는지라도 잘 정리해두거나 문서화를 해두면 나중에 유지 보수를 할 때 큰 도움이 된다.

유지 보수를 할 필요가 없을 정도로 강건하게 개발해뒀다면 더할 나위 없이 좋다. 위에서 언급한 과거의 코드를 다시 돌이켜봐야 하는 일 자체가 없어지기 때문이다. 원래 하던 일을 계속 집중해서 하면 된다. 개인적으로 이 부분은 개발자의 역량을 판단하기 위한 척도 중 하나로 봐야 할 정도라고 생각하는 편이다. 보통 역량을 판단할 때 주어지는 일을 잘 쳐내는 개발자가 좋은 개발자로 인식되기 쉽다. 하지만 그 척도로만 판단할 경우 추가적인 유지 보수를 발생시키는 비용이 포함되지 않는다. 그러한 유지 보수는 개발을 했던 당사자가 항상 하는 것이 아니기 때문에 비용이 분산되고, 결국 판단이 어렵게 된다.


그렇다면 한 번 할 때 잘하기 위해서는 어떤 노력들을 해볼 수 있을까? 개인적으로 백엔드 개발자로서 생각하는 방법론들은 크게 다음과 같다. 1. End to End로 시나리오를 생각해볼 것, 2. End to End까지 실행되는 과정에서 필요한 모니터링 및 Alert을 잘 설정했는지 점검해볼 것, 3. 그동안의 경험으로 예상되는 미래의 변경 상황에 잘 대처할 수 있는지 생각해볼 것 정도이다.

End to End로 시나리오를 생각해보는 것은 강건한 소프트웨어를 만드는데 도움된다. 처음부터 끝까지 발생할 수 있는 경우의 수들을 나열해보면 개발할 때 미처 생각하지 못한 케이스가 존재하는지 생각을 잘할 수 있다. 이 과정에서 스펙 수준에서 제한이 필요할 수 있다는 생각도 할 수 있다. 예를 들어, URL 데이터를 저장하는 상황을 생각해보자. 아예 규격이 잘못된 URL이 입력되는 경우도 있을 것이고, 너무 긴 URL이 입력될 수도 있을 것이다. 규격이 잘못된 URL는 저장하는 것이 무의미할 수도 있고, 너무 긴 URL은 확장성 문제를 일으킬 수 있다. 이런 경우 스펙상으로 제한을 하는 것이 도움된다. 이것은 선대응에 해당하는 부분이다.

End to End까지 실행되는 과정에서 필요한 모니터링 및 Alert을 잘 설정했는지 점검하는 것은 후대응에 해당한다. 앞서 시나리오를 열심히 생각하여 개발한다 하더라도 미처 예상치 못한 문제는 얼마든지 발생할 수 있다. 이 경우에는 문제가 발생한 것을 먼저 인지라도 할 수 있어야 한다. 만약 로그를 확인하기 어렵거나 Alert 설정이 미흡하다면 디버깅이 어렵고, 고객보다 문제를 먼저 인지하고 고칠 수 없다.

미래의 변경 상황에 잘 대처할 수 있는지 생각하는 것은 어떻게 보면 뻔하다. 내가 생산하는 코드는 거의 무조건 나중에 변경이 생길 수 있다고 생각해야 한다. 그렇지 않은 경우가 거의 없기 때문이다. 만약 현재의 환경이나 요구 사항에 매우 강결합된 상태로 개발한다면 나중에 변경하기가 쉽지 않다. 아주 교묘하게(tricky) 요구 사항을 만족시키는 경우도 생각해봐야 한다. 보통 그렇게 요구 사항을 만족시키는 것은 나중에 다른 요구 사항을 만족시키기 어렵게 하기 때문이다. 이 경우 요구 사항을 조절하기 위해 1번과 같이 스펙 제한을 제안해야 할 수 있다.


물론 당장 일을 쳐내야 하는 입장에 놓인 경우가 많기 때문에 한 번 개발할 때 잘하는 것은 쉽지 않은 일이다. 시간을 많이 들이거나 경험이 많이 축적되어 있어야만 가능하기 때문이다. 그렇기 때문에 오히려 이것을 잘할 수 있는 개발자가 빛날 수 있는 것이라 생각한다. 이렇게 한 번 할 때 잘하면서도 생산성이 뛰어난 개발자라면 더할 나위 없다.

과거 동료 중 한 분이 얘기했던 말 중 하나가 있다. 그분의 개발 철학 중 하나는 작성한 코드를 최대한 다시 볼 일이 없게 하는 것이었다. 이 말에는 테스트를 잘 만드는 것뿐만 아니라 정말 강건한 소프트웨어를 개발하는 것이 포함된 말이기 때문에 깊은 인상을 받았었다. 지금도 나는 그 말을 되새기며 내가 작성한 코드를 다시 볼 일이 없도록 잘하고 있는지 고민한다. 앞으로도 유혹에 넘어가지 않고 이 노력을 계속하고 싶다.

마지막으로, 한 번 할 때 잘하는 것은 물론 중요하지만 그러기 위해 생산성이 심각하게 저하되는 것은 피해야한다. 고객에게 가치를 제때 전달할 수 없다면 이 모든 노력이 무용지물이기 때문이다. 유명한 격언도 있지 않나. Make it work, then make it better. 어쨌든 소프트웨어로 가치를 전달하는 것이 개발자의 임무라는 것을 잊지 말자.

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