Why the Best Software Advice Is the Hardest to Follow
좋은 소프트웨어 조언은 왜 따르기 어려울까요
작은 함수나 의미 있는 변수명처럼 실행 여부를 쉽게 확인할 수 있는 규칙과, 상황에 따라 판단해야 하는 원칙을 구분합니다. 경험은 규칙 사이의 충돌과 추상화의 비용을 가늠하는 판단력을 키우며, 좋은 엔지니어는 규칙을 외우는 데서 원칙을 적용하는 단계로 나아간다고 설명합니다.
- 주제
AI 요약
작은 함수, 매직 넘버 대신 상수 사용, 의미 있는 변수명처럼 실천 방법이 분명한 조언은 배우고 확인하기 쉽습니다. 코딩 표준이나 린터, 코드 리뷰에도 적용할 수 있어 팀에 빠르게 퍼집니다. 하지만 이런 규칙을 잘 따른다고 좋은 엔지니어가 되는 것은 아닙니다. 더 어려운 조언은 정답을 정해 주지 않고, 상황에 맞는 판단을 요구합니다.
규칙과 판단의 차이
실용적인 조언은 “이렇게 하세요”, “이렇게 하지 마세요”처럼 바로 행동으로 옮길 수 있습니다. 반면 판단에 기반한 조언은 상황에 따라 해석해야 하는 원칙입니다. 때로는 이미 배운 다른 원칙과 충돌하기도 합니다. 보편적으로 맞는 답이 없으므로 경험과 맥락을 살펴야 합니다.
“잘못된 추상화는 중복보다 비용이 큽니다”라는 조언이 그렇습니다. 중복을 없애야 하는지, 어느 정도 비슷해야 추상화할지, 지금은 비슷해 보여도 서로 다른 방향으로 바뀔 코드라면 어떻게 할지 정해진 체크리스트가 없습니다. 너무 일찍 만든 추상화를 바꾸는 비용과 해롭지 않은 중복, 시간이 지나 유지보수 문제로 커지는 중복을 모두 겪어야 이 조언을 규칙이 아닌 사고방식으로 이해하게 됩니다.
DRY 원칙도 경력에 따라 다르게 읽힙니다. 초반에는 비슷한 코드가 보이면 공통 추상화로 묶으려 합니다. 그러나 코드 중복이 두 개념의 독립성을 지켜 주기도 하고, 추상화가 중복보다 더 큰 결합을 만들기도 합니다. 두 코드가 현재 비슷해 보여도 앞으로 서로 다른 이유로 바뀔 가능성이 있다면, 도메인의 형태가 드러날 때까지 중복을 유지하는 편이 나을 수 있습니다. 조언이 바뀐 것이 아니라, 조언을 해석하는 능력이 달라진다는 설명입니다.
경험이 만드는 판단력
경험이 쌓이면 추상화가 어긋난 듯한 느낌을 먼저 알아차릴 때가 있습니다. 그 직감을 곧바로 설명하지 못하더라도, 과거에 비슷한 추상화가 어떻게 변했는지, 겉으로 같은 두 요소가 서로 다른 이유로 바뀔지를 감지하는 경우입니다. 소프트웨어 개발에서 직감은 마법이나 사고의 대체물이 아닙니다. 여러 상황과 실패, 절충의 결과를 겪으며 익힌 패턴 인식입니다.
작은 함수를 쓰라는 규칙은 몇 분이면 가르칠 수 있지만, 함수가 언제 지나치게 큰지, 왜 문제가 되는지, 나눴을 때 오히려 코드가 나빠지는 경우는 언제인지를 짧게 가르치기는 어렵습니다. 린터가 어떤 원칙을 우선해야 하는지 알려 주지도 않습니다. 단순함, 중복 방지, 성급한 추상화 회피, 변경되는 부분의 캡슐화는 모두 유효한 원칙이지만, 한 원칙을 따르면 다른 원칙을 지키기 어려운 상황에서는 맥락을 따져야 합니다. 따라서 경험 많은 개발자들이 같은 코드를 보고도 합리적으로 의견이 갈릴 수 있습니다. 도메인이나 변경 비용, 미래에 대한 예상이 다를 수 있기 때문입니다.
프레임워크를 따르는 것과 원칙을 이해하는 것
저자는 이 차이를 Scrum과 애자일 선언문(Agile Manifesto)에도 적용합니다. Scrum은 역할, 이벤트, 산출물, 규칙을 제시하므로 팀이 비교적 빠르게 도입하고 실행 여부를 확인할 수 있습니다. 반면 애자일 선언문은 개인과 상호작용, 변화에 대한 대응 같은 가치와 원칙을 제시하지만 조직 운영을 위한 완전한 설명서를 제공하지 않습니다. 개인과 상호작용을 중시한다고 절차가 쓸모없다는 뜻은 아니며, 변화에 대응한다고 계획이 불필요하다는 뜻도 아닙니다. 중요한 질문은 어느 하나를 고르는 것이 아니라, 특정 상황에서 원칙을 어떻게 적용할지입니다. Scrum의 의식과 도구를 갖추더라도 애자일의 원칙을 이해하지 못할 수 있습니다.
규칙에서 원칙으로
조직은 측정하고 가르치고 검토하고 확장하기 쉬운 실용적 조언을 선호합니다. “함수는 작아야 합니다”는 표준으로 만들기 쉽지만, 도메인과 예상되는 변경을 고려해 적절한 추상화 수준을 판단하라는 규칙은 만들기 어렵습니다. 문제는 실용적인 규칙을 많이 모으면 판단력도 자동으로 생긴다고 믿는 데서 시작합니다. 규칙을 더 아는 것만으로는 상황에 맞는 절충을 익힐 수 없습니다.
소프트웨어는 팀, 도메인, 제약, 사람, 불확실성이 서로 다른 맥락에서 만들어집니다. 그래서 모든 상황에 통하는 아키텍처나 추상화 시점을 요구하기보다, “이렇게 하라고 배웠습니다”에서 “왜 대체로 유용한지 이해합니다”로, 다시 “절충점을 이해하고 여기서 적용할지 결정합니다”로 나아가야 합니다. 규칙을 버리는 것이 아니라 언제 따르고, 규칙끼리 충돌할 때 무엇을 선택하며, 언제 따르지 않을지 판단하는 능력을 기르는 일입니다.
dev.to 반응
- @francistrdev — 좋은 글입니다, Remo! 시간이 지나며 배운 점은 초반에는 규칙을 따르기 쉽지만, 가능한 한 유연해야 한다는 것입니다. 모범 사례를 막 배우는 사람은 비교적 단순한 일을 하므로 적용하기 쉽습니다. 하지만 경험이 쌓이면 말씀하신 중복 사례처럼 상황이 복잡해집니다. 때로는 궤도를 벗어나더라도 궤도 가까이에 머물면 괜찮습니다 :)
- @remojansen — 맞습니다. 경험이 쌓이면 체스를 두는 것과 비슷해집니다. 앞으로 몇 수를 생각하고 여러 절충점을 함께 따져 가장 나은 길을 선택하게 됩니다.
- @unitbuilds — 한 단어로 말하면 제약입니다. 전구를 갈려면 개발자가 몇 명 필요할까요? 한 명은 작업하고 한 명은 테스트를 작성합니다? 틀렸습니다. 하드웨어 문제입니다. 개발자는 종종 일을 지나치게 벌입니다. ‘X를 구현하라’는 요청을 받고 Y가 고장 난 것을 발견하면, Y에 의존하고 있으니 그냥 고칠까요? Y를 바꾸기 전에 모든 의존성을 고려했나요? 얼마나 확신하나요? 우리 모두 그런 상황을 겪었고 실패도 했습니다.
성숙한 개발자에게 필요한 교훈은 자제력입니다. 저는 아직 미숙하지만, 맡은 일에 명시적으로 집중하는 일은 점점 더 어렵습니다. 특히 AI를 쓰면 ‘이것도 고쳐야 합니다’, ‘잠깐만 고치면 안 될까요?’라고 계속 말합니다. AI가 먼저 고쳐 놓고 나중에 알리거나, 고치라고 반복해서 권하는 일을 다들 보셨을 겁니다. 퍼즐을 맞출 때 그림을 다 완성하고 마지막 세 조각만 남겨 두지는 않듯, 개발에서도 문제를 발견했다고 바로 범위를 넓히기 쉽습니다. 하지만 개발에서는 그게 늘 좋은 선택은 아닙니다.
문제를 기록하고 그대로 두세요. 이슈를 만들고 현재 일을 끝낸 뒤 돌아오거나, Slack 채널에 올려 먼저 허가를 받으세요. 허가를 받았다면 의존성을 추적하고 회귀가 없는지 테스트를 작성하세요. 자제력은 손을 떼는 일이 아니라, 적절한 때에 시간을 들여 제대로 처리하는 일입니다. 메서드 하나에 테스트 50개가 필요한 것은 아닙니다. 버튼을 추가해 달라고 하면 버튼을 추가하세요. 처음부터 과하게 설계하지 마세요. 나중에 덧붙이는 편이 처음부터 지나치게 만든 것을 걷어 내는 것보다 쉽습니다. 과한 설계를 되돌리려면 문서와 테스트, 코드를 정리하고 컴파일 오류까지 고쳐야 합니다. 반면 문제를 기록하고 허가를 받은 뒤 조금씩 작업하면 수정 범위를 분리할 수 있고 작업 트리에 자잘한 변경을 쌓지 않아도 됩니다.
최근 채용 과제로 ‘추상 파일 시스템(abstract filesystem)의 POC를 만들라’는 과제를 받았습니다. 구현 조건을 엄격하게 제한해 과도한 설계를 잡아내려는 과제였습니다. 가능한 한 빠르고 단순하게 POC를 만든 뒤, 가치가 있다고 판단되면 확장하는 것이 목적입니다. 덧붙이는 일은 처음부터 과하게 만든 것을 되돌리는 일보다 쉽습니다. 5시간이 걸리고 그중 절반을 되돌리는 데 쓴다면, 3시간짜리 일에 7시간을 쓴 셈입니다. 특히 AI는 무엇을 더 개선할지 물으면 쉽게 범위를 넓히므로, 자제력을 의식적으로 발휘해야 합니다. 구현할 때 KISS 원칙을 지켰는지, 과하게 설계해 확장하기 어렵고 유지보수가 불안정해지지는 않았는지, 추가한 요소를 하나하나 정당화할 수 있는지 물어보세요. 추가 요소 없이도 요구사항을 충족하지 못한다고 확신할 수 있나요?
- @ben — 좋은 글입니다.
- @remojansen — 감사합니다!
원문: dev.to / 번역·요약: Trawling