brunch

You can make anything
by writing

C.S.Lewis

by 타자 Jun 03. 2023

클린 코드가 왜 필요하다고요?

이자에 허덕이는 개발 생활은 편할 수 없습니다.

어디서 본 듯한 이야기


 가상의 스타트업 내부 상황을 상상해 보자.


 이 회사는 IT 기술 기반의 스타트업이다. 창립 멤버들이 회사에 살다시피 일하며 제품을 론칭했고, 입소문을 타며 빠르게 이용자가 늘었다. 개발자들은 쏟아지는 요구사항과 변경사항을 밤을 새우며 제품에 빠르게 적용해서 우여곡절 끝에 비즈니스 궤도에 올.


 그리고 n 년 ,


 최고 기술 책임자(CTO)가 된, 원년 개발자 멤버 A는 직원들의 개발 속도가 답답하다. 사업 초기를 생각해 보면 그렇게 요구사항과 변경사항이 물밀듯 쏟아졌는데도 한 달이면 다 해결이 됐는데, 지금은 상대적으로 적은 분량의 요구사항 주어지는데도 반영되는데 한 달이 걸린다. A는 아주 가끔, 본의인지 아닌지는 모르겠지만, 직원들에게 이런 말을 흘린다.


 예전에는 정말 빠르게 개발했었거든요. B님! 우리 그거 2주 만에 끝냈었지 않나요?


 정말 가끔이긴 하지만 답답함을 참지 못하고 팀장 회의에서 일정을 보고하는 팀장들에게 이런 말을 하는 경우도 있다.


제가 하면 1주일이면 충분할 것 같은데요.


 이제 관점을 바꿔보자. C는 1년 전, 이 회사에 신입으로 입사한 개발자다. C는 클린 코드 중요하다는 사실은 알지만 기한이 촉박하니 어쩔 수 없이 코드가 나오는 대로 저장소에 추가다. C는 리팩토링이 하고 싶지만 어떻게 해야 할지 모르겠고, 선임들이나 팀장에게 물어봐도 매번 애매한 답변만 돌아올 뿐이다.


 한 번 더 관점을 바꿔보자. D는 지난달에 이 회사에 입사한 5년 차 개발자다. 간단한 요구사항 하나 구현하는데 확인하고 테스트해야 하는 부분들이 너무 많다. 이곳저곳에 보이는 중복 코드와 목적조차 불명확한 변수나 무의미해 보이는 조건문이 지나치게 많기 때문이다. 조금씩 코드를 정리하며 작업을 진행하는데 CTO가 지나가면서 한 마디를 던진.


D님, 조금 더 힘내주세요.
빠르게 개발하는 개발자가 좋은 개발자인 거 아시죠?


 자, 가상의 스타트업 상황이라고 적어놨지만 이쯤 되면 비슷한 업력의 스타트업의 개발자들은 본인 동료가 사연 제보라도 한 건 아닌가 싶을 수도 있겠다.


 왜 이런 상황의 스타트업이 많고, 왜 다들 비슷한 경험을 하게 되는 것일까?


 답은 여러 가지가 있겠지만 우리는 개중 가장 일반적인 원인 하나를 살펴보자. 우리가 클린 코드의 본질과 목적을 온전히 이해하기 위해 반드시 앞서 이해해야 할 개념이 바로 그 유명한 '기술 부채(technical debt)' 되시겠다.



기술 부채?


 기술 부채의 개념을 이해하기 위해서는 부채(debt)가 무엇인지 알아야 한다.

제법 기술적으로 생겼지만 기술 부채의 '부채'는 이 부채가 아니다.


 부채는 우리말로 '빚'이고, '빚'에는 '이자(interest)'가 따른다. 예시를 함께 보자.

 4천만 원짜리 차를 사는데 난 2천만 원 밖에 없다. 그래서 2천만 원을 카드사에서 빌려서 차를 샀다. 난 2천만 원을 카드사에 갚아야 하고 이자는 연 10%다. 1년에 2백만의 이자를 갚아야 하는데 생활비가 빠듯해서 미뤘더니 이자에 대한 이자까지 붙기 시작했다.


 위 예시를 말만 바꿔보면 다음과 같다.

 3주짜리 요구사항을 구현하는데 난 1주밖에 없다. 변수명을 대충 짓고 기존 코드 복붙과 검색으로 찾은 코드를 이용해 작업을 일단 완료한 뒤 리팩토링을 하려고 했다. 그런데 내가 리팩토링을 하기 전에 동료가 이 코드를 이용한 새 기능을 추가해 버렸다. 이제 난 코드를 수정하려면 동료의 작업분까지 수정해야 한다. 수정을 망설이는 사이 또 다른 동료가 내 코드와 내 코드를 이용해 추가된 새 기능을 나름의 방식으로 정리한 뒤, 기존 기능을 또 변경했다.


 인터넷에서 알고리즘 문제 풀이를 보다 보면 보통 서너 개의 변수명을 이용해 10줄 남짓한 코드로 해결할법한 문제를 수학적 기법을 통해 별도의 변수 선언 없이  두 줄로 푸는 풀이가 공유되어 있는 경우를 쉽게 찾아볼 수 있다.

 

 이런 코드는 좋은 코드일까?


 모든 동료가 직관적으로 이해하고, 필요한 경우 별다른 어려움 없이 수정까지 할 수 있다면 좋은 코드가 맞다. 하지만 이해하는데 별도의 맥락이(일반적이지 않은 수학 정리라던가) 필요하거나, 원 작성자에게 설명을 들어야 이해할 수 있다면 어떨까? 그런 코드는 리뷰 단계에서 가차 없이 반려되어야 한다. 코드 저장소는 현시점의 우리만 사용하는 것이 아니기 때문이다.


 아래의 경우를 생각해 보면 이유를 쉽게 체감할 수 있을 것이다.

1. A가 복잡한 수학 정리를 이용해 짧게 작성한 코드를 제품에 적용

2. B 입사, 해당 코드 발견 후 며칠을 이해하려고 끙끙대다 A에게 질문, A는 설명하고 B는 이해

3. C 입사, 역시 해당 코드 발견 후 B에게 질문, B는 끙끙대다 애매한 부분을 다시 A에게 질문, A는 기억을 되짚어서 간신히 설명

4. D 입사, 해당 코드 발견 후 B, C에게 물었는데 명확하게 설명하지 못 함, A는 퇴사한 상황, 며칠을 조사해서 코드 원리 알아내고 팀 내 공유

5. E 입사, 해당 코드 발견 후 D에게 질문, C와 D에게 함께 설명 들음


 시간이 실로 어마어마하게 낭비되는 것을 알 수 있다. 더 큰 문제는 해당 코드가 저장소에서 사라지지 않는 이상, 저 시간 낭비의 사이클이 지속적으로 일어난다는 것이다.


 해당 코드에서 파생되는 추가 공수를 '이자'로 볼 때, 이런 이자를 발생시킬 가능성이 높은 코드가 많아지면 실제 파생되는 이자 사채 수준으로 어난다. 기술 부채가 반드시 코드에만 적용되는 개념은 아니지만, 적어도 코드 레벨에서는 어떤 식으로든 이자를 발생시키는 코드를 '기술 부채'라고 부른다.



기술 부채가 쌓이면?


 간단한 기능 수정 작업 하나를 예로 들어 보자.

 큰 틀에서 보면 작업은 아래와 같은 순서로 이루어질 것이다.


1. 요구사항 분석

2. 요구사항 적용 시 기존 정책 위배 등 문제 여부 검토

3. 기존 API 기능 분석

4. 수정 시 영향 범위 파악

5. 개발방향 검토

6. 영향 범위에 대한 테스트 코드 작성 또는 점검

7. 코드 수정

8. 테스트 및 영향 범위 내 부작용 발생 여부 검토

9. 코드 리뷰

10. 배포


 기술 부채가 없거나 무시할 수 있을 만큼 작다면, 1~10단계의 한 사이클을 도는데 적게는 수 시간에서 많게는 1주 정도의 시간에 작업이 하나둘씩 완료될 것이다.

 하지만 기술 부채가 무시할 수 없을 정도로 쌓이면, 이자부터 처리해야 주어진 일을 진행할 수 있고, 이자의 규모는 작업이 시작되기 전에는 추정하기 쉽지 않다. 이는 곧 공수 산출의 어려움으로 이어지고, 공수 산출의 어려움은 곧이어 일정 관리의 어려움으로 이어진다.


 의외로 기술 부채의 이자는 작업의 특정 단계를 지연시키는 것이 아니라 모든 단계를 지연시키는 평등한 특성을 보인다. 대략적인 예를 들자면 아래와 같다.


[1, 2단계] 이미 구현된 기능이 필요 이상으로 복잡한 경우, 요구사항도 복잡해진다. Minimum Viable Product가 그리 구체화하기 힘든 개념이 아님에도 기존 기능이 복잡하면 Maximum Viable Product 나오는 빈도가 확연이 늘어난다. 요구사항을 정련하고 관계자 간 눈높이를 맞추는데 짧게는 수 일에서 많게는 수 주까지의 시간과 노력이 요구된다.

필요 이상으로 복잡한 기능 역시 기술 부채다.


[3단계] 기존 코드 동작을 이해하는데 시간이 필요 이상으로 소모되거나, 이 정도면 양호하다. 심한 경우 기존 코드 작성자에게 찾아가서 설명을 들어야 이해를 할 수 있는 경우도 얼마든지 생길 수 있는데 기존 코드 작성자가 회사 내에 존재하지 않는 경우도 있을 수 있다.


[4단계] 시간에 쫓기면 기존 코드를 이해하고 정리하기보다, 당장 발등에 떨어진 불부터 꺼야 한다. 즉, 기존 코드와 무관한 새 코드로 기능을 구현해야 하는 상황에 몰리게 된다. 눈치챘겠지만 이 '새 코드'는 조직의 기술 부채 역사에 새로운 획을 그을 확률이 대단히 높다.


[5-10단계] 중복 코드나 중복 구현, 책임이 명확하지 않은 객체들의 춘추전국시대가 벌어지면 이 단계는 이미 유명무실하다고 봐도 무방하다. 함께 수정되지 말아야 할 부분이 수정되고, 함께 수정되어야 할 부분이 수정되지 않는다. 개발자와 테스터가 꼼꼼하다면 테스트에 드는 시간이 무지막지하게 늘어나는 것으로 이자가 정산될 것이고, 불행히 그렇지 못하다면 배포 후 결함을 마주하고, 그에 대한 값을 치러야 한다.


 최상급 엔지니어만으로 개발팀을 구성하고 충분한 기한 내 개발을 진행하는 집단이라면 기술 부채를 쌓지 않거나, 최소한의 기술 부채를 유지하면서 개발 조직을 운영할 수 있다. 이런 집단은 다수가 실존하지만, 회사는 이런 개발 집단을 조직의 목적을 위해 운영하는 것이 불가능에 가깝다.(배꼽>>배)


 다시 말해 당신이 회사에 소속된 개발자라면, 그리고 기술 부채를 줄이기 위한 TF가 활동 중인 상황이 아니라면 필연적으로 기술 부채는 쌓이고 있다. 그리고 그 상태가 방치되면 글의 초입부에 나온 '어디서 본 듯 한 이야기'가 더 이상 남의 이야기가 아니게 될 수도 있다.



그래서 클린 코드가 뭔데?


 다시 클린 코드 이야기로 돌아오자. 클린 코드의 정의는 대단히 다양하다. 오래되고, 유명한 개념으로, 개발을 업으로 하는 사람이라면 클린 코드에 대한 이미지를 가지고 있다.

I like my code to be elegant and efficient.The logic should be straightforward and make it hard for bugs to hide, the dependencies minimal to ease maintenance, error handling complete according to an articulated strategy, and performance close to optimal so as not to tempt people to make the code messy with unprincipled optimizations.

난 내 코드가 우아하고 효율적이었으면 한다. 로직은 명확하되 의도와 다르게 동작할 틈이 없어야 한다. 불필요한 의존성은 없어야 하고, 명시적이고 전략적인 예외 처리가 되어 있으며 최선의 성능도 보장되어야 한다. 그래야 딴 놈들에게 최적화를 한답시고 코드를 엉망으로 만들 빌미를 주지 않을 테니까.
- Bjarne Stroustrup


 온갖 정의 속에서 공통되는 부분을 뽑아보면 아래와 같다.


 클린 코드는 '주어진 조건 하 기술 부채를 최소화한 코드'다.


 

그렇다면 왜 클린 코드를 작성하지 않나?


 클린 코드가 좋다는 것을 모르는 개발자는 없다. 신입 개발자들도 경이로운 확률 99.9%로 '클린 코드는 좋은 코드이고, 클린 코드를 만들어야 한다'는 것을 알고 있다.


 그런데 왜 클린 코드를 작성하지 않는가?


 단언컨대 대다수의 개발자는 클린 코드를 작성하지 않는 것이 아니라 작성하지 못하는 것이다. 타자의 주니어 시절에는 시간이 부족해서 클린 코드를 작성할 수가 없는 것이라고 생각했다. 결론부터 말하면 일단 이건 아니었다.

 

 일단 클린 코드가 필요한 이유에 대해서는 충분한 설명이 되었다고 생각되기에 목적을 달성한 시점에서 이 글은 마무리하며, 클린 코드를 작성하지 못하는 이유에 대해서는 다음 글에서 이어 다루겠다.



정리


 클린 코드가 필요한 이유는 기술 부채를 최소화하기 위해서다.

 기술 부채를 줄여야 하는 이유는 부채로부터 발생한 이자가 조직의 생산성을 저하시키고, 조직의 기민성을 떨어트리고, 구성원들의 의욕을 저하시킬 뿐 아니라 구성원에 대한 평가도 왜곡시키는 만악의 근원이기 때문이다.

 이 간단하고 명료한 사실을 아직 모르는 관리자와 개발자가 많은 작금의 현실이 안타까워 어떻게든 이해시키고 납득시키고자 주저리주저리 예시를 들어 내용을 작성해 봤다. 기술 부채의 위험성에 대해 조금이라도 경고의 의미가 전해졌으면 좋겠고, '우리 정도면 괜찮다'라고 생각하는 사람이 있다면, 이미 괜찮지 않을 확률이 당신 생각보다 훨씬 높을 수 있다는 경고를 이 자리를 빌려 전한다.

작가의 이전글 나도 개발자나 한번 해볼까?
브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari