1P by GN⁺ | ★ favorite | 댓글 1개
  • YAGNI는 “아직 필요 없는 코드를 쓰지 말라”는 단순 절약 규칙이 아니라, 필요가 확정되기 전에 추측으로 구조를 선점하는 일의 비용을 다루는 원칙임
  • 문제의 중심은 설계 자체가 아니라 언제 설계할 것인가이며, 너무 이른 구조화는 너무 늦은 구조화만큼 위험할 수 있음
  • 선행 구조는 정보가 오기 전에 선택지를 닫는 선택권 비용과, 비용을 앞당기고 수익을 늦추는 NPV 비용을 함께 만듦
  • 코드 생성 비용이 거의 0에 가까워져도 YAGNI는 사라지지 않으며, 오히려 값싼 생성이 추측 기반 프레임워크를 더 쉽게 만들 수 있음
  • 필요한 때 만들라는 결론은 코드 작성 비용 때문이 아니라, 쓰지 않은 선택권과 쓰지 않은 의 가치가 여전히 남아 있기 때문임

YAGNI는 설계를 금지하지 않음

  • YAGNI는 “You Aren’t Gonna Need It”의 약자로, 필요 없는 것을 절대 설계하지 말라는 변명이 아님
  • 필요한 것이 있으면 만들면 되지만, 핵심은 타이밍
  • 프로젝트 중 “3주 뒤에는 단순한 구현이 부족할 테니 지금 더 복잡한 것을 만들고 싶다”는 상황에서, “You aren’t going to need it”이라는 응답이 반복된 일화가 출발점임
  • 이 원칙은 구조를 너무 일찍 만드는 일과 너무 늦게 만드는 일을 모두 위험하게 봄

문제는 코드 작성 비용이 아니라 추측 기반 구조임

  • 흔한 해석은 YAGNI를 “아직 필요 없는 코드는 비싸니 쓰지 말라”는 절약 규칙으로 봄
  • 하지만 YAGNI가 겨냥하는 대상은 코드 생산 비용이 아니라, 실제 기능이 필요로 하기 전에 미리 만든 투기적 구조(speculative structure)
  • 이런 구조는 서로 다른 시점과 이유로 두 종류의 비용을 발생시킴

첫 번째 비용: 선택권

  • 기능이 도착하기 전에 구조를 만들면, 아직 모르는 요구에 대해 추측으로 커밋하게 됨
  • 미리 대비한 기능은 실제로 도착하는 기능과 보통 다르며, 그 결과 두 번 비용을 냄
    • 잘못된 모양의 구조를 우회하는 비용
    • 그 구조를 다시 뜯어내는 비용
  • 이 문제는 단순히 “예측이 어렵다”는 말에 그치지 않음
  • 추측이 맞더라도, 미리 커밋하지 않고 나중에 올바른 구조를 만들 수 있는 선택권을 잃는다는 점에서 손해가 남음
  • 기다리는 것은 게으름이 아니라, 선택권이라는 자산을 보유하는 일임

두 번째 비용: NPV

  • 돈에 시간 가치가 있듯이 기능에도 시간 가치가 있음
  • 3개월 뒤 필요한 기능을 위해 지금 구조를 만들면, 비용은 앞당겨지고 실제로 돈을 버는 기능의 출시는 늦어짐
  • 이 비용은 추측이 맞아도 발생함
  • 완벽한 예측도 비용과 수익의 순서를 바꾸지 못하며, 손실은 비용을 수익보다 먼저 배치한 간격에서 생김
  • 선택권 비용은 “정보가 오기 전에 커밋하지 말라”는 문제이고, NPV 비용은 “필요하기 전에 지불하지 말라”는 문제임
  • “나중에 고치면 너무 비싸다”는 반론이 있어도, 그 비싼 개조 자체가 다시 하나의 예측일 수 있음

코드 생성이 싸져도 YAGNI는 남음

  • 두 비용 어디에도 코드를 타이핑하는 비용은 포함되지 않음
  • 코드 작성 비용이 거의 0에 가까워지면, “코드가 싸졌으니 미리 만들어도 되지 않나”라는 절약형 YAGNI 해석은 무너짐
  • 그러나 YAGNI가 절약 규칙이 아니므로, 값싼 코드 생성은 YAGNI를 폐기하지 않음
  • 선택권 비용은 노력의 양이 아니라 미래 선택지를 닫는 커밋에서 생김
  • NPV 비용은 생산 가격이 아니라 현금흐름의 타이밍에서 생김
  • 무료 생성은 YAGNI를 약화하지 않고, 오히려 추측 기반 프레임워크를 더 쉽게 만들게 함
  • 생성된 구조는 여전히 두 비용을 만들며, 직접 쓰지 않았기 때문에 이해도는 더 낮을 수 있음
  • 결론은 “코드가 비싸서 기다리라”가 아니라, 선택권과 돈은 쓰지 않았을 때 더 가치가 있으므로 필요할 때 만들라는 것임

댓글과 토론

Hacker News 의견들
  • 구조 변경 비용도 낮아졌다고 봄
    AI 덕분에 구조 변경 전에 동작을 테스트로 보강하는 비용이 줄었고, 무중단 마이그레이션 구현 비용도 내려감
    Rust가 주목받은 큰 이유 중 하나도 AI 이전부터 애플리케이션 내부 구조 변경 비용이 낮다는 점이었고, 이제는 더 그렇다
    안전하게 구조를 바꾸지 못하는 데 따른 기회비용은 크게 올라갔고, 지금은 코드와 제품의 큰 부분을 빠르고 안전하게 바꿀 수 있는 능력을 최우선으로 최적화함

    • 코드와 제품의 큰 부분을 빠르고 안전하게 바꿀 수 있는 능력은 원래도 좋은 것이었고, AI 코딩의 등장과 무관하게 가치가 있었음
      다만 AI 이전에는 구조 변경에 훨씬 오래 걸렸으니, 지금 최적화하려는 대상의 가치는 오히려 내려갔다고 볼 수도 있음
      여전히 가치 있지만 예전보다 조금 덜할 수 있음
    • 동의하기 어려움
      깨지기 쉬운 AI 생성 테스트가 늘어나면서 구조 변경 비용은 예전보다 더 커짐
      테스트 묶음을 정리해서 문제의 본질을 검증하고 우연한 설계 결정을 검증하지 않게 만드는 일은 아직 AI가 잘하지 못함
    • 맞음
      하지만 그렇게 하지 않고 대충 75%쯤 익은 취약한 테스트 묶음을 얻는 것도 너무 쉬움
      “사람이 쓴 몇 개의 평범하고 취약한 테스트”에서 “AI가 쓴 많은 평범하고 취약한 테스트”로 가는 것을 객관적 개선으로 여기며 만족하는 사람이 많음
      도구를 이렇게 활용하자는 데는 완전히 동의하지만, 그래서 너무 이른 시점에 잘못된 공중누각을 쌓는 걱정을 안 해도 된다고 보기는 어려움
      리팩터링에 견디는 완벽한 테스트 계약은 여전히 설계하기 꽤 어렵다
    • 이건 “확장에는 열려 있고, 수정에는 닫혀 있다”는 개방-폐쇄 원칙을 떠올리게 함
      오래된 것이 다시 새것처럼 돌아온 셈
      DDD나 클린 아키텍처 같은 접근의 문맥 효율부터 이런 항목까지, AI는 새로운 절충을 만드는 게 아니라 증폭기처럼 작동함
      제대로 하는 팀의 생산성은 키우고, 설계와 아키텍처 품질 기준이 낮은 팀의 부채도 키움
    • AI가 대신 고쳐줄 것이라고 베팅하면서 점점 더 헛손질을 늘리는 것처럼 보임
      얻는 건 깊이 생각하지 않아도 된다는 점뿐임
      깊게 생각하는 데 그렇게 많은 시간이나 노력이 들지는 않으니, AI를 똑같이 활용하면서도 헛손질이 되지 않을 만큼 생각하는 사람들에게 밀릴 것임
  • Kent Beck은 아직 작성하지 않은 코드를 특정 가격에 살 수 있는 금융 옵션에 비유함
    하지만 그건 어디까지나 비유이고, 너무 멀리 끌고 가면 이상해짐
    코드를 하나도 쓰지 않았다면 선택지가 무한한가? 아직 시간을 쓰지 않았더라도 그건 맞지 않아 보임
    아무것도 확정하지 않기 위해 계획 단계에 머물며 코드 작성을 무기한 미루는 근거가 될 수도 있음
    그래도 이 비유가 작동한다면 비용은 코드를 읽는 데 있을 수 있음
    작성되지 않은 코드는 읽을 필요가 없고, 코딩 에이전트를 쓴다면 관련 없는 세부사항으로 문맥을 어지럽히지도 않음
    아직 작성하지 않은 코드는 테스트할 필요도 없고, 아직 작성하지 않은 테스트는 실행 시간도 들지 않음
    그래서 프로젝트를 가능한 한 작게 유지하는 게 좋고, 기능을 미루면 코드베이스 성장을 최대한 늦출 수 있음
    남의 코드를 실행하면 많은 비용을 피할 수 있다는 뜻이기도 함
    표준 API를 쓸 수 있다면 구현을 자세히 이해하거나 그 테스트를 실행할 필요가 없지만, 의존성을 추가하는 데는 위험이 있음

    • Kent의 “Tidy, First?”에서는 소프트웨어가 두 가지 방식으로 가치를 만든다고 봄: 오늘 하는 일, 그리고 내일 새로 하게 만들 수 있는 가능성
      작성되지 않은 코드에는 가치가 없음
      오늘 작성되는 코드가 가치를 만들려면, 오늘의 요청이나 이슈를 해결하거나 내일 무언가를 더 쉽게 만들도록 기울어져 있어야 함
      해키한 해결책으로 기술 부채를 지거나 YAGNI에 어긋나는 것에 시간을 낭비하면 가치를 만들지 못함
      중요한 건 작성되지 않은 코드가 아니라 앞으로 작성할 코드와 그 목적임
      오늘의 티켓·할 일을 해결하는 것과 미래의 자기 발등을 쏘지 않는 것 사이에서 올바른 절충을 해야 함
      코드를 쓰는 건 약속이고, 오늘의 가치는 보이지만 내일의 가치는 추정에 가깝다
      그래도 나중에 치를 비용은 항상 있으니, 무엇이 필요해질지 예상해 비용을 최소화하려고 추정하게 됨
  • AI 시대의 모범 사례를 충분히 강조하지 않는다고 생각하지만, Kent가 완전히 놓치는 부분이 있음
    필요한 기능이 무엇인지 더 빨리 알아내는 데는 상당한 가치가 있음
    추측성 구조를 만드는 것이 요구사항을 확정하게 만드는 강제 장치가 될 수 있고, 적어도 실패 양상을 드러내기 시작함
    기다리는 것보다 비쌀 수 있으니 대부분의 요구사항에 그렇게 해서는 안 되지만, 때로는 최선의 선택일 수 있음
    잘못된 것을 만드는 비용이 이제 훨씬 낮아졌고, 그래서 YAGNI를 둘러싼 계산도 달라짐
    그래도 여전히 계산이 필요하며, 지금은 각 팀이 자신들에게 어떻게 달라졌는지 직접 파악해야 함

    • 추측성 구조를 스파이크로 만들고 버린다면 괜찮음
      버리지 않는다면 그건 지저분한 결과물을 만드는 강제 장치가 됨
    • 필요한 기능은 이미 요구사항과 그 요구사항을 충족할 시스템 설계에서 나온다고 봄
      YAGNI는 현재 요구사항에 없는 것을, 나중에 요구사항이 바뀔 것이라 예상해서 만드는 문제임
      현재 요구사항과 제약을 구체화하는 것과는 다름
      그런 것들은 주로 이해관계자·사용자·고객과의 대화, 자원, 공학적 제약과 역량에서 나옴
      프로토타입은 이해관계자와 대화하거나 프로젝트 관리 모델을 만들거나 공학 연구를 할 때 가치가 있음
      그 외에는 앞뒤가 바뀐 것임
  • 실행 중인 소프트웨어를 자산으로 보는 접근은 맞음
    다만 실행하고 다시 만드는 비용은 크게 내려감
    내려가지 않은 비용은 예측 가능한 결과에 대한 신뢰 사슬을 깨는 비용임
    실행 중인 소프트웨어의 특정 버전은 신뢰를 축적해 왔고, 처음부터 다시 쓰면 릴리스 시 그 자본이 초기화됨

  • 어느 순간부터 생각이 바뀜
    구체물을 YAGNI로 미루고, 가능한 한 추상적인 버전을 작성함
    UserStore를 만들까? 그게 가장 단순해 보이지만, 특정한 User라는 형태가 필요 없을 수도 있음
    그래서 저장 가능한 무엇이든 담는 Store를 만듦
    익숙하지 않으면 과설계와 제네릭 범벅처럼 보이지만, 역설적으로 어떤 구체 구현에도 가장 적게 약속하는 방식임

    • 정확히 과설계와 제네릭 범벅처럼 보임
      아마 필요 없었을 UserStore 인터페이스를 만든 것뿐 아니라, 확실히 필요 없었던 일반화된 Store 추상화까지 만든 셈임
      구체 구현에 약속하지 않으려고 필요 없고 앞으로도 필요 없을 가능성이 큰 끈적한 계층들을 구현한 것임
      실제 필요에 기반하지 않은 추상화라면, 나중에 필요해지더라도 거의 틀리게 만들었을 가능성이 큼
      결국 UserStore는 필요할 테니 그걸 먼저 만들었어야 함
  • “더 날카로운 아키텍트라면 피할 수 있다는 식으로 예측이 어렵다는 주장이 아니다”에는 동의하지 않음
    이 주장은 예측이 어렵다는 전제가 있어야만 성립함

    • “정확한 추측을 해도 약속하지 않은 것보다 나빠진다”도 혼란스러움
      가능성이 매우 높은 기능을 미리 발판으로 만들어두고 모든 게 맞아떨어지면 더 빨리 출시함
      팀이 반드시 커지거나 인원이 유지된다는 보장도 없으니, 마감 직전에 YAGNI를 맞추려고 허둥대는 것보다 절제를 자축하는 쪽이 더 나쁘게 느껴짐
  • 최근 YAGNI가 잔뜩 쌓인 코드베이스에서 기능적으로 벗어나야 했는데, 에이전트가 있어도 엄청난 작업이었음
    분산 시스템에서 어떤 것이 정말 사용 중인지 어떻게 알 수 있나? 내가 놓친 것도 있고 에이전트가 놓친 것도 있었고, 전체가 필요 이상으로 오래 걸림
    단순히 1:1 포팅을 한 것도 아니고, 단순화할 기회로 삼았기 때문에 옛 시스템이 어떻게 동작하는지 완전히 이해해야 했음
    실제로 전혀 쓰이지 않던 것들도, 그렇게 식별하지 못하면 이해 대상에 포함됐음

  • 결국 문제를 탐색하고 해법을 구현하는 일로 귀결된다고 봄
    잘못된 문제를 푸는 데는 항상 비용이 있고, 필요하지도 않은 것에 나쁜 해법을 구현하는 비용도 있음
    소프트웨어 개발이 때로는 탐색할 전략과 문제 집합을 생각하는 대신 단순한 시행착오로 흘러갈 수 있음
    필요한 것보다 특정 방향으로 문제를 더 깊게 탐색하는 게 장기적으로 도움이 되는 경우는 있지만, 목적 없이 해법을 구현하는 건 결코 좋지 않음
    Kent Beck이 정말 비판하는 건 미래에 필요할지 모른다는 이유로 “혹시 몰라” 무언가를 구현하는 태도라고 봄

  • “기능이 오기 전에 구조를 만들면 추측에 약속하는 것이다”라고 했지만, 어느 쪽이든 추측은 한다고 봄
    기능이 올 가능성은 높을 수 있지만 확실하지는 않음
    지금 구조를 만들지 않으면 리팩터링 비용이 있고, 너무 일찍 만들었는데 기능이 오지 않으면 노력을 낭비함
    그 가능성들 사이의 비용, 확률, 절충은 무엇인가? 당연히 상황에 따라 다름
    YAGNI 전체가 의도적으로 큰 일반화임
    결국 사정에 달려 있음
    어느 쪽이든 추측과 손짓 설명이 가득한 경우가 많고, 신뢰할 만한 작업 추정과 같은 문제임
    불확실한 세계를 잘 견디지 못하는 일부 개발자는 모든 것에 흑백 규칙을 찾으려 함

  • Kent Beck의 글에서 칩 회사에 유용할 만한 내용은 본 적이 없음
    칩 회사에서는 많은 사람이 오랜 기간 일해야 하고, 고객은 완성될 때까지 아무것도 볼 수 없으며, 돈을 벌려면 수백만 개 단위로 팔아야 함

    • 그는 소프트웨어를 만들고 소프트웨어 개발에 대해 쓰는 사람 아닌가
      하드웨어에는 강한 제약이 있음
      애초에 소프트웨어가 발명된 이유도 바로 그런 제약에서 벗어나기 위해서였음
    • 고객이 완성 전에는 절대 볼 수 없다는 건 꼭 맞지는 않음
      많은 칩 회사가 진행 중인 작업을 공유하지 않는 건 맞겠지만, 시뮬레이션·프로토타입·엔지니어링 샘플을 공유하는 일은 가능하고 실제로도 일어남
      물론 보통은 큰 고객이어야 함
      변화 비용이 비교적 작은 산업의 통찰은 변화 비용이 큰 산업에 쉽게 적용되지 않고, 그 반대도 자주 마찬가지임
    • 흥미롭다
      칩 회사들은 그런 프로젝트를 어떻게 계획하나? 애자일, 폭포수, 아니면 소프트웨어 업계와 다른 프레임워크를 쓰나?