가장 좋은 소프트웨어 조언이 가장 따르기 어려운 이유
규칙으로 정리되는 조언은 배우기 쉽지만, 정작 값진 조언은 상황마다 해석이 달라져 따르기 어렵다. Remo H. Jansen이 실천형 조언과 판단형 조언을 구분해 설명한다.

Why the Best Software Advice Is the Hardest to Follow
Not all software advice is created equal. Some advice is practical. It tells you exactly what to...
개요 #
소프트웨어 개발 조언은 두 종류로 나뉜다. 하나는 그대로 따라 하면 되는 실천형 조언, 다른 하나는 상황에 맞게 해석해야 하는 판단형 조언이다. Remo H. Jansen은 전자가 널리 퍼지는 이유와 후자가 훨씬 값진 이유를 정리했다.
"함수를 작게 유지하라", "매직 넘버 대신 상수를 쓰라" 같은 조언은 배우기 쉽고 가르치기 쉽고 검증하기도 쉽다. 그래서 코딩 표준에 들어가고, 린터가 잡아주고, 코드 리뷰에서 확인한다. 반면 "잘못된 추상화는 중복보다 비싸다" 같은 조언은 체크리스트로 바뀌지 않는다.
Jansen이 던지는 경고는 여기서 나온다. 좋은 관행을 지키는 것과 좋은 엔지니어가 되는 것을 혼동하기 시작하는 순간이 문제라는 것이다.
흑백이 분명한 조언 #
실천형 조언의 강점은 결정할 일을 줄여준다는 데 있다. 주니어 개발자도 무슨 뜻인지 바로 안다. 시니어는 가르칠 수 있다. 리뷰어는 200줄짜리 함수를 가리키며 "이건 쪼개는 게 좋겠다"고 말할 수 있다.
책 한 권으로 배워서 내일 바로 적용하고, 효과를 즉시 확인할 수 있다. Jansen은 Clean Code 같은 책이 그토록 영향력을 가진 이유가 바로 여기에 있다고 본다. 조언의 상당 부분이 실행 가능한 형태라서, 원칙을 읽고 나면 코드를 쓰면서 바로 옮길 수 있다.
Photo by Nemuel Sereti on Pexels
규칙으로 바뀌지 않는 조언 #
"잘못된 추상화는 중복보다 비싸다"는 문장은 단순해 보이지만 규칙으로 바꾸려 하면 막힌다. 이 코드를 중복시켜야 하나? 어떤 때는 그렇고 어떤 때는 아니다.
허용할 수 있는 중복의 양은 얼마인가. 두 코드가 얼마나 비슷해야 추상화 대상이 되는가. 지금은 닮았지만 앞으로 다르게 진화할 가능성이 크다면 어떻게 하나. 추상화가 지금 코드를 복잡하게 만들지만 나중의 중복을 막아줄지도 모른다면?
이 질문들에 답하는 체크리스트는 없다. 판단이 필요하고, 판단은 경험에서 나온다. 잘 작동한 추상화도 봐야 하고, 괴물로 변한 추상화도 봐야 한다. 너무 일찍 설계한 추상화를 바꾸는 비용을 직접 치러봐야 하고, 아무 문제도 일으키지 않은 중복과 결국 유지보수 지옥이 된 중복을 둘 다 겪어봐야 한다.
그걸 다 지나고 나서야 이 조언이 제대로 쓸모를 갖는다. 규칙이기를 멈추고 사고방식이 된다.
같은 조언, 달라지는 의미 #
Jansen이 소프트웨어 엔지니어링에서 흥미롭다고 꼽은 지점이 이것이다. 커리어의 다른 시점에 똑같은 조언을 듣고도 매번 다른 것을 이해하게 된다.
경력 초반에 누군가 DRY를 알려준다. 그러면 중복을 찾아 헤매기 시작한다. 두 코드가 비슷해 보이면 추상화한다. 파라미터가 반복되면 공통 객체를 만든다. 여러 클래스가 비슷하게 동작하면 베이스 클래스를 만든다. 조언을 잘 따르고 있는 셈이다.
그리고 몇 년 뒤 다른 원칙을 만난다. "잘못된 추상화보다는 중복이 낫다." 갑자기 DRY가 그렇게 간단해 보이지 않는다. 중복 자체가 문제가 아니라는 걸 알게 된다.
중복은 두 개념을 독립적으로 유지하기 위해 치르는 값일 때가 있다. 추상화가 중복보다 더 심한 결합을 만들 때가 있다. 그냥 반복하면서 도메인이 어떤 추상화를 원하는지 말해줄 때까지 기다리는 게 최선일 때도 있다.
조언이 바뀐 게 아니다. 조언을 해석하는 능력이 바뀐 것이다.
규칙에서 직관으로 #
사례가 충분히 쌓이면 말로 설명하기 전에 패턴이 먼저 보이는 시점이 온다. 어떤 추상화를 보면 뭔가 잘못됐다는 느낌이 드는데, 그 이유를 바로 설명하지는 못한다. "이건 아직 추상화하지 말자" 정도로 말하게 된다.
왜? 전에 똑같은 상황을 봤을 수도 있고, 이런 추상화가 어떻게 진화하는지 겪어봤을 수도 있다. 지금은 똑같아 보이는 두 대상이 완전히 다른 이유로 변할 것 같다는 감이 왔을 수도 있다.
Jansen은 여기서 직관이 마법이 아니라고 짚는다. 생각을 대체하는 것도 아니다. 실패와 트레이드오프와 그 결과를 충분히 겪은 뇌가 패턴을 자동으로 알아보게 된 결과다.
문제는 직관을 가르치기가 규칙보다 훨씬 어렵다는 데 있다. "함수를 작게 쓰라"는 5분이면 가르친다. 하지만 함수가 언제 너무 큰지, 왜 큰지, 쪼개는 게 오히려 코드를 나쁘게 만드는 건 어떤 경우인지를 5분 만에 전달할 방법은 없다.
좋은 조언끼리 충돌할 때 #
판단형 조언이 어려운 또 하나의 이유가 있다. 좋은 조언 두 개가 서로 부딪히는 경우다.
- 단순하게 유지하라.
- 코드를 중복시키지 마라.
- 이른 추상화를 피하라.
- 변하는 것을 캡슐화하라.
전부 좋은 조언이다. 그런데 하나를 따르면 다른 하나를 따르기 어려워질 때는 어떻게 하나. 이런 상황에는 컴파일러 경고가 뜨지 않는다. 어느 원칙이 이겨야 하는지 알려주는 린터도 없다. 직접 결정해야 하고, 그 결정은 맥락에 달려 있다.
경험 많은 엔지니어들이 같은 코드를 두고 서로 다른 의견을 내면서도 양쪽 다 합당한 근거를 갖는 이유가 여기 있다. 한쪽은 규칙을 알고 다른 쪽은 모르기 때문이 아니다. 미래와 도메인, 변경 비용, 위험에 대해 서로 다른 판단을 하고 있기 때문일 수 있다. 소프트웨어 엔지니어링의 회색 지대다.
스크럼과 애자일 선언문 #
Jansen은 같은 구분이 코드 밖에서도 보인다며 스크럼과 애자일 선언문을 예로 든다.
스크럼은 구체적인 것을 준다. 역할, 이벤트, 산출물, 규칙이 있다. 팀이 배워서 비교적 빠르게 도입할 수 있고, 그래서 조직에 매력적이다. "우리는 스크럼을 하고 있다"고 말할 수 있다는 데서 오는 안심이 있다. 프레임워크가 있고 관행이 정의돼 있다. 일정에 넣을 세리모니도, 만들어낼 산출물도 있다.
애자일 선언문은 다르다. 네 가지 가치와 열두 가지 원칙을 주지만, 조직을 운영하는 완결된 매뉴얼은 주지 않는다. 프로세스와 도구보다 개인과 상호작용을, 계획을 따르기보다 변화에 대응하기를 중시하라고 말한다. 이런 문장은 해석과 판단을 요구한다.
개인과 상호작용을 중시한다는 말이 프로세스가 쓸모없다는 뜻은 아니다. 변화에 대응한다는 말이 계획이 쓸모없다는 뜻도 아니다. 진짜 물어야 할 질문은 "둘 중 어느 쪽을 따를까"가 아니라 "이 상황에서 이 원칙을 어떻게 적용할까"다. 그리고 후자가 훨씬 어렵다.
애자일 뒤의 판단력을 기르지 않고도 스크럼을 도입할 수 있다. 세리모니와 보드와 역할과 용어를 다 갖추고도 그 밑에 깔린 원칙은 놓칠 수 있다. 프레임워크를 따르는 것과 그 배경의 원칙을 이해하는 것은 다르다.
쉬운 조언이 이기는 이유 #
실천형 조언이 우세한 데는 자연스러운 이유가 있다. 측정이 되고 가르치기 쉬우며, 리뷰에서 확인할 수 있고 조직이 커져도 그대로 굴러간다.
회사는 "함수는 작아야 한다"는 코딩 표준을 만들 수 있다. 하지만 "현재 도메인과 앞으로의 변화 가능성을 고려해 적절한 추상화 수준을 경험과 판단으로 정하라"는 표준은 만들기 어렵다. 앞쪽은 규칙이 되지만, 뒤쪽은 뭘 하는지 아는 사람이 있어야 굴러간다.
조직은 규칙으로 바뀌는 것을 선호한다. 그게 나쁜 일은 아니다. 실천형 조언은 대단히 유용하다. 문제는 실천 규칙을 충분히 모으면 언젠가 좋은 판단력이 생긴다고 믿을 때 시작된다. 규칙을 더 많이 안다고 트레이드오프를 더 잘 다루게 되지는 않는다. 어느 시점에는 이 상황에서 어떤 규칙이 중요한지 결정하는 능력을 길러야 한다.
Photo by ThisIsEngineering on Pexels
규칙에서 원칙으로 #
Jansen은 가장 값진 조언이 가장 따르기 어려운 조언이기도 하다고 말한다. 무엇을 하라고 정해주지 않고, 생각하게 만들고, 문제를 볼 렌즈를 준다. 경쟁하는 두 아이디어의 균형을 직접 잡으라고 요구할 때도 있다. 처음에는 답답할 수 있다. 우리는 레시피를 원한다. 올바른 아키텍처를 알려달라고, 언제 추상화해야 하는지, 함수가 얼마나 커야 하는지, 디자인 패턴을 언제 도입해야 하는지 정확히 알려달라고 말하고 싶어진다.
하지만 소프트웨어는 맥락 안에서 만들어진다. 팀도 도메인도 제약도 사람도 불확실성의 정도도 다 다르다. 경험이 쌓일수록 중요한 엔지니어링 결정 상당수에 보편적인 정답이 없다는 걸 알게 된다. 판단이 필요하고, 판단이 어려운 건 결정을 직접 책임져야 하기 때문이다. 뒤에 숨을 체크리스트가 없다.
그래서 Jansen은 더 나은 엔지니어가 되는 과정이 나쁜 규칙을 좋은 규칙으로 바꾸는 일이 아닐 수도 있다고 본다. 규칙에서 원칙으로 천천히 옮겨가는 일에 가깝다는 것이다. "그렇게 하라고 들었다"에서 "이게 보통 왜 유용한지 이해한다"로, 그리고 마침내 "트레이드오프를 이해했고, 여기에 적용할지 내가 판단할 수 있다"로.
기르기 훨씬 어려운 능력이다. 하지만 일단 갖추면 실천형 조언이 오히려 더 유용해진다. 규칙을 버리는 게 아니다. 더 잘 이해하게 된다. 언제 따라야 하는지 알고, 두 규칙이 충돌하는 지점을 알아보고, 무엇보다 언제 따르지 말아야 하는지를 알게 된다. 경험이 조언을 지혜로 바꾸는 지점이 거기다.
글 끝에서 Jansen은 독자에게 두 가지를 물었다. 커리어에서 만난 가장 쓸모없었던 실천형 조언은 무엇이었나, 그리고 규칙을 주지는 않았지만 소프트웨어를 보는 방식을 바꿔놓은 판단형 조언은 무엇이었나.
이 글은 위 출처를 바탕으로 한국 독자를 위해 재작성한 기사입니다. 원문의 사실과 수치에 근거하며, 별도의 견해를 포함하지 않습니다.
