본문으로 건너뛰기

YAGNI 원칙

개념

실제로 필요하다고 확인되기 전까지는 기능이나 코드를 미리 구현하지 말아야 한다는 익스트림 프로그래밍의 소프트웨어 설계 원칙

YAGNI(You Aren’t Gonna Need It의 약자)는 소프트웨어 개발에서 프로그래머가 실제로 필요하다고 확인되기 전까지는 어떤 기능이나 코드도 미리 구현해서는 안 된다는 원칙이다. You Ain’t Gonna Need It, You Aren’t Going to Need It 등의 변형된 표기도 함께 쓰이며, 익스트림 프로그래밍(XP, Extreme Programming)이 채택한 단순 설계(Simple Design) 관행을 요약하는 격언으로 통용된다.

이 표현은 1990년대 중반 미국 크라이슬러사의 급여 시스템 통합 프로젝트인 크라이슬러 종합 보상 시스템(C3) 현장에서 등장했다. 이 프로젝트의 리더였던 켄트 벡은 동료 쳇 헨드릭슨이 향후 필요할 것으로 예상되는 기능을 미리 제안할 때마다 그건 필요하지 않을 것이라고 답했으며, 이 일화는 훗날 마틴 파울러에 의해 용어의 기원으로 소개되었다. C3 프로젝트는 벡과 론 제프리스, 워드 커닝엄이 익스트림 프로그래밍의 실천 방법을 정립한 현장으로 평가되며, 이후 벡이 1999년 펴낸 저서와 제프리스 등이 2001년 펴낸 저서를 통해 YAGNI가 XP의 공식 어휘로 자리 잡았다.

원칙을 뒷받침하는 논거는 2015년 마틴 파울러가 자신의 블리키에 게재한 글에서 체계적으로 정리되었다. 그는 아직 쓰이지 않는 미래 대비 기능을 예측성 기능(presumptive feature)이라 부르고, 이를 미리 구현할 경우 구축 비용과 지연 비용, 유지 비용, 수선 비용이라는 네 가지 비용이 발생한다고 설명했다. 이 비용 구조는 요구사항을 정확히 예측하는 일이 어렵다는 전제와 결합해, 실제로 필요해질 때까지 구현을 미루는 편이 대체로 더 경제적이라는 주장으로 이어진다.

YAGNI는 코드 품질을 낮추거나 확장성을 포기해도 된다는 뜻으로 종종 오해되지만, 파울러를 비롯한 XP 실천가들은 이 원칙이 소프트웨어를 변경하기 쉽게 유지하는 활동, 곧 리팩터링이나 자동화된 테스트, 지속적 통합에는 적용되지 않는다고 구분한다. 이 원칙은 코드 기반이 유연하게 유지된다는 전제 위에서만 성립하며, 두 요소는 서로를 강화하는 관계로 설명된다.

YAGNI는 단순함을 추구하는 KISS나 DRY 원칙과 함께 언급되며, 구현에 앞서 설계를 상세히 완성해 두는 빅 디자인 업프론트(BDUF)와 대비되는 개념으로 다루어진다. 다만 원칙의 적용 범위를 둘러싸고는 견해차가 있다. 일부 논자는 코드 수준의 설계와 되돌리기 어려운 아키텍처 수준의 의사결정에 이 원칙을 동일하게 적용할 수 있는지에 의문을 제기하며, 이는 익스트림 프로그래밍 진영 내부에서도 논쟁이 되어 온 주제다.

정의와 어원

YAGNI는 원래 두문자어로 출발했으나, 파울러는 2015년 글에서 이 표현이 이미 일반 어휘로 자리 잡았다고 보아 대문자 대신 소문자로 표기하는 방식을 택하기도 했다. 파울러는 아직 사용을 위해 제공되지 않은 기능을 지원하는 코드를 예측성 기능이라는 용어로 지칭했으며, YAGNI는 바로 이러한 예측성 기능을 지금 만들지 말라는 조언으로 정의된다.

YAGNI는 익스트림 프로그래밍의 실천 방법 가운데 하나인 단순 설계를 가리키는 표현으로 통용된다. 벡의 저서 초판에서는 이를 단순 설계라 불렀고, 개정판에서는 점증적 설계(incremental design)라는 관련 개념으로 다시 설명했다. XP 문헌에서는 YAGNI와 함께 그 순간 가능한 가장 단순한 일을 하라는 의미의 DTSTTCPW(Do The Simplest Thing That Could Possibly Work)라는 표현도 함께 쓰인다.

역사적 배경

익스트림 프로그래밍과 C3 프로젝트

크라이슬러 종합 보상 시스템(C3, Chrysler Comprehensive Compensation System)은 여러 갈래로 나뉘어 있던 크라이슬러의 급여 처리 시스템을 스몰토크와 젬스톤 기반의 단일 시스템으로 통합하려던 프로젝트로, 1993년 급여 시스템 담당 이사 톰 해드필드의 주도로 시작되었다. 1996년 켄트 벡이 프로젝트 리더로 합류해 개발 방식을 재정비했고, 그는 론 제프리스를 프로젝트에 끌어들였다. 시스템은 1997년 가동되어 약 1만 명의 급여를 처리했으며, 이후 처리 대상을 확대하려 했으나 1999년 신규 개발이 중단되었고 크라이슬러는 2000년 프로젝트를 최종적으로 종료했다.

YAGNI라는 표현의 기원은 이 프로젝트에서 벡과 쳇 헨드릭슨이 나눈 대화로 전해진다. 헨드릭슨이 시스템에 곧 필요할 것으로 예상되는 여러 기능을 잇달아 제안할 때마다 벡은 그때마다 필요하지 않을 것이라고 답했으며, 헨드릭슨은 이후 YAGNI를 적용할 기회를 포착하는 데 능숙해진 인물로 묘사된다. 이 원칙은 1998년 론 제프리스가 게재한 글을 통해 처음 문서로 정리되었으며, 벡이 1999년 펴낸 익스트림 프로그래밍 설명과 제프리스, 앤 앤더슨, 헨드릭슨이 2001년 함께 쓴 익스트림 프로그래밍 인스톨드를 거치며 XP의 정식 어휘로 자리 잡았다. 이 개념은 워드 커닝엄이 운영하던 위키(c2.com)에서도 초기부터 논의된 것으로 알려져 있다.

개념의 정립과 확산

용어가 정립된 이후에도 이를 뒷받침하는 경제적 논거를 체계적으로 정리한 글은 한동안 드물었다. 파울러는 2000년 XP 2000 학회에 발표한 글 “Is Design Dead?“에서 YAGNI와 설계의 관계를 다루었으며, 2015년에는 자신의 블리키에 “Yagni”라는 별도의 글을 게재해 원칙이 성립하는 근거를 비용 구조로 정리했다. 이 두 글은 이후 YAGNI를 설명할 때 가장 널리 인용되는 자료로 꼽힌다.

핵심 논거

예측성 기능과 네 가지 비용

파울러는 미래에 필요할 것으로 예상되는 기능을 미리 구현할 때 발생하는 비용을 다음과 같이 네 가지로 구분했다.

비용 유형 설명
구축 비용(cost of build) 아직 쓰이지 않는 기능을 분석하고 구현하고 테스트하는 데 드는 비용
지연 비용(cost of delay) 같은 노력을 실제로 필요한 다른 기능에 투입했다면 얻었을 가치를 얻지 못해 발생하는 기회비용
유지 비용(cost of carry) 사용되지 않는 기능이 코드 기반의 복잡도를 높여, 그 기능이 실제로 쓰이기 전까지 다른 기능의 개발과 유지보수를 어렵게 만드는 비용
수선 비용(cost of repair) 기능이 실제로 필요하기는 했으나 당시의 예측이 실제 요구사항과 어긋나, 나중에 다시 고쳐야 할 때 발생하는 비용

파울러는 이 가운데 구축 비용과 지연 비용은 예측성 기능이 나중에 실제로 필요해진 경우에도 그대로 발생하며, 유지 비용은 기능이 쓰이기 전까지, 수선 비용은 예측이 틀렸을 경우에 추가로 발생한다고 설명했다. 그는 이러한 논거를 마이너스에서 폭풍 위험 가격 책정 기능을 개발 중이던 보험회사가 6개월 뒤 필요해질 해적 위험 가격 책정 기능을 미리 만들지 여부를 판단하는 가상의 사례로 설명했다.

파울러는 마이크로소프트의 실험 데이터를 분석한 코하비 등의 연구를 인용해, 세심한 사전 분석을 거치더라도 실제로 배포된 기능 가운데 목표한 지표를 개선한 비율은 약 3분의 1에 그쳤다고 지적하며, 이를 예측성 기능이 불필요한 것으로 판명될 가능성이 낮지 않다는 근거로 제시했다. 그는 또한 개발자가 예측성 기능을 지금 구현할지 판단할 때, 그 기능이 실제로 필요해진 시점에 리팩터링으로 추가하는 데 드는 노력을 미리 상상해 보라고 권했으며, 이러한 사고 실험이 나중에 추가해도 크게 비싸지 않다는 점을 확인시켜 주는 경우가 많다고 설명했다.

적용 범위와 전제 조건

변경이 쉬운 코드 기반이라는 전제

파울러는 YAGNI가 예측성 기능을 지원하기 위해 소프트웨어에 들여오는 능력에만 적용되며, 소프트웨어를 변경하기 쉽게 만드는 활동에는 적용되지 않는다고 구분했다. 이 구분에 따르면 리팩터링에 들이는 노력은 YAGNI 위반이 아닌데, 리팩터링은 코드를 더 유연하게 만드는 활동이기 때문이다. 같은 논리가 자동화된 테스트, 지속적 통합, 지속적 배포와 같은 관행에도 적용된다. 파울러는 이러한 관행들을 XP에서 진화적 설계를 가능하게 하는 활성화 관행(enabling practice)이라 불렀으며, 이러한 관행이 뒷받침되지 않는 환경에서는 YAGNI가 유익한 실천이 아니라 코드 기반을 훼손하는 결과로 이어질 수 있다고 설명했다.

이러한 관행들의 관계는 다음과 같이 정리할 수 있다.

flowchart LR
    A[테스트 자동화] --> D((변경이 쉬운 코드 기반))
    B[지속적 통합] --> D
    C[리팩터링] --> D
    D --> E[YAGNI 적용]
    E --> C

단순 설계의 네 가지 규칙

YAGNI는 벡이 익스트림 프로그래밍 설명에서 제시한 단순 설계의 네 가지 규칙과도 연결된다. 파울러가 정리한 바에 따르면 벡은 이 규칙들을 다음과 같이 우선순위 순서로 제시했다.

우선순위 규칙 설명
1 모든 테스트를 통과한다 코드가 의도한 대로 동작함을 자동화된 테스트로 검증한다
2 중복이 없다 동일한 지식이 시스템 안에서 한 곳에서만 표현되도록 한다
3 의도를 드러낸다 코드를 읽는 사람이 작성자의 의도를 이해할 수 있어야 한다
4 클래스와 메서드 수를 최소화한다 YAGNI에 해당하는 규칙으로, 앞의 세 규칙을 해치지 않는 범위에서만 적용된다

이 네 규칙은 우선순위 순서로 제시되며, YAGNI에 해당하는 마지막 규칙은 앞의 세 규칙에 이바지하지 않는 요소를 제거하라는 지침으로 설명된다.

관련 논쟁

아키텍처 수준의 적용을 둘러싼 이견

YAGNI를 아키텍처 수준의 의사결정에도 동일하게 적용할 수 있는지를 두고는 익스트림 프로그래밍 내부에서도 견해가 갈렸다. 파울러는 2000년 발표한 글에서, 벡과 제프리스, 로버트 마틴 등 이른바 적극적인 XP 실천가들은 데이터베이스 도입처럼 되돌리기 어려운 구조적 결정조차 실제로 필요해질 때까지 미뤄야 한다는 입장을 취했다고 소개했다. 반면 파울러 자신은 스스로를 소극적인 XP 실천가라 부르며, 애플리케이션을 어떻게 계층화할지, 데이터베이스와 어떻게 연동할지와 같은 폭넓은 출발점 아키텍처는 초기에 정해 둘 필요가 있다는 입장을 밝혔다. 그는 대량의 데이터를 다루거나 여러 사용자가 접근하는 시스템이라면 처음부터 데이터베이스를 사용하는 편이 낫다고 보았으며, 다만 판단이 서지 않는 경우에는 YAGNI에 따라 더 단순한 쪽을 택해야 한다고 덧붙였다.

파울러는 같은 글에서 국제화 지원처럼 나중에 추가하기 유난히 번거로운 요소가 YAGNI의 예외에 해당하는지에 대해서도 의문을 제기했다. 그는 이러한 예외가 존재할 가능성을 인정하면서도, 개발자는 어떤 기능을 나중에 추가할 때 드는 수고는 생생하게 체감하는 반면 그 기능을 미리 구현하고 유지하는 데 드는 비용은 상대적으로 체감하기 어렵고, 미리 구현하더라도 실제 요구사항과 어긋나 다시 고쳐야 할 가능성이 있다는 점을 들어, 이러한 예외가 흔하지는 않을 것으로 보았다.

기술 부채 및 스킴핑과의 구분

YAGNI를 둘러싼 또 다른 논쟁은 이 원칙이 이른바 기술 부채나 코드 품질을 의도적으로 낮추는 스킴핑(skimping)과 어떻게 구분되는가를 두고 벌어진다. 익스트림 프로그래밍의 공동 창시자인 론 제프리스는 2019년 게재한 글에서, 실제로는 품질을 낮추는 관행에 YAGNI라는 이름을 붙이는 경우가 있다고 지적했다. 그는 단순 설계의 규칙을 지키며 개발하는 팀이라면 이후 기능을 추가할 때 코드 전반을 광범위하게 고쳐야 하는 상황 자체가 잘 발생하지 않는다고 주장하며, YAGNI를 따르는 것과 기술 부채를 떠안는 것은 서로 다른 문제라고 구분했다.

관련 개념과의 비교

YAGNI는 소프트웨어 개발의 여러 단순성 관련 원칙, 그리고 이와 대비되는 접근과 함께 논의된다.

개념 핵심 주장 YAGNI와의 관계
KISS(Keep It Simple, Stupid) 코드는 가능한 한 단순하고 이해하기 쉽게 작성되어야 한다 단순성이라는 목표를 공유하지만, KISS는 이미 작성하기로 한 코드를 어떻게 만들지에 관한 조언이고 YAGNI는 애초에 무엇을 만들지에 관한 조언이라는 점에서 구분된다
DRY(Don’t Repeat Yourself) 동일한 지식이나 로직은 시스템 안에서 한 곳에만 존재해야 한다 벡의 단순 설계 네 규칙 안에서 YAGNI(요소 최소화)와 나란히 제시되는 별개의 규칙이다
빅 디자인 업프론트(Big Design Up Front, BDUF) 구현에 앞서 설계를 최대한 상세하게 완성해 둔다 애자일 진영에서 안티패턴으로 지목되며, 미래의 요구사항을 미리 구현해 둔다는 점에서 YAGNI와 반대되는 접근으로 대비된다
조기 최적화(premature optimization) 성능이 실제로 문제가 되기 전에 최적화에 시간을 들이는 것을 경계해야 한다 도널드 커누스가 제시한 개념으로, 아직 필요가 확인되지 않은 작업을 뒤로 미루라는 논리 구조는 유사하지만 적용 대상이 성능 최적화라는 점에서 다르다

같이 보기

관련 개념으로는 이 원칙이 유래한 익스트림 프로그래밍과 그 상위 범주인 애자일 소프트웨어 개발, 함께 단순 설계를 구성하는 KISS 원칙과 DRY 원칙, YAGNI가 전제로 삼는 리팩터링과 지속적 통합, 이 원칙과 자주 함께 논의되는 기술 부채, 대비되는 접근인 빅 디자인 업프론트, 그리고 애자일 진영에서 비슷한 문제의식으로 다루어지는 진화적 설계와 최소 기능 제품 등이 있다.


참고 자료