KISS·YAGNI·DRY: 덜 만들고, 늦게 만들고, 지식을 한곳에 두는 법
KISS는 현재 해법의 복잡성을, YAGNI는 아직 필요 없는 미래 기능을, DRY는 여러 곳에 복제된 지식을 줄인다. 세 원칙의 차이와 오용을 실전 예제로 정리한다.
KISS, YAGNI, DRY는 모두 코드를 줄이는 구호처럼 보이지만 서로 다른 질문에 답한다. KISS는 지금 만든 해법이 필요 이상으로 복잡한지 묻고, YAGNI는 아직 확인되지 않은 미래 기능을 미리 만들고 있는지 묻는다. DRY는 하나의 지식이 여러 곳에 복제돼 함께 바뀌지 못하는지 묻는다.
세 원칙을 같은 뜻으로 취급하면 오히려 설계가 나빠진다. KISS를 핑계로 검증과 오류 처리를 빼거나, YAGNI를 핑계로 테스트와 리팩터링을 미루거나, DRY를 핑계로 우연히 닮은 코드를 거대한 공용 함수에 묶는 식이다. 중요한 것은 문구를 외우는 일이 아니라 각 원칙이 제거하려는 비용을 구분하는 것이다.
KISS: 현재 문제를 푸는 가장 이해하기 쉬운 경로
KISS는 ‘Keep It Simple, Stupid’의 약자다. 록히드의 항공기 설계자 켈리 존슨이 즐겨 쓴 격언으로 알려졌고, 복잡한 시스템도 현장에서 이해하고 수리할 수 있을 만큼 단순해야 한다는 공학적 태도를 담는다.
소프트웨어에서 단순함은 줄 수가 가장 적거나 고급 문법을 쓰지 않는다는 뜻이 아니다. 새로운 사람이 제어 흐름을 따라가기 쉽고, 상태와 의존성이 드러나며, 수정의 영향 범위를 예측할 수 있다는 뜻에 가깝다. 요구가 ‘회원 등급에 따라 배송비를 계산한다’라면 첫 구현부터 전략 패턴·플러그인 레지스트리·동적 규칙 엔진을 모두 만들 필요는 없다. 명확한 조건과 테스트로 시작해 변화가 실제로 생길 때 구조를 확장할 수 있다.

KISS를 잘못 적용하는 신호
- 짧지만 숨겨진 코드: 한 줄 표현이 상태 변경과 예외를 감춰 읽는 사람이 더 오래 해석한다.
- 필수 안전장치 삭제: 입력 검증·권한 확인·테스트를 ‘복잡하다’며 제거한다.
- 단순함의 전가: 한 함수는 짧아졌지만 호출 순서와 전역 상태가 더 복잡해진다.
YAGNI: 미래의 가능성에 오늘의 복잡성을 지불하지 않기
YAGNI는 ‘You Aren’t Gonna Need It’의 약자로, 익스트림 프로그래밍의 단순 설계와 연결된다. 마틴 파울러의 설명처럼 아직 필요하다고 확인되지 않은 기능을 미래에 쓸 것이라는 예상만으로 지금 넣지 말자는 원칙이다.
핵심은 구현 시점이다. ‘언젠가 여러 국가의 세금 체계를 지원할 수 있다’는 가능성만으로 첫날부터 범용 규칙 언어를 만드는 대신, 현재 계약된 국가와 확인된 요구를 구현한다. 다음 국가가 들어오면 그때 두 사례의 차이와 공통점을 보고 구조를 바꾼다. 나중의 정보가 더 정확하므로 잘못된 추상화에 묶일 가능성도 줄어든다.

YAGNI가 미루라는 뜻이 아닌 것
YAGNI는 코드베이스를 바꾸기 쉽게 만드는 리팩터링, 자동화된 테스트, 지속적 배포를 미루라는 원칙이 아니다. 오히려 이런 기반이 있어야 미래 요구가 생겼을 때 안전하게 추가할 수 있다. 보안 경계, 데이터 손실, 규제 준수처럼 늦게 고치기 매우 비싼 위험도 단순한 ‘미래 기능’과 구분해야 한다.
DRY: 같은 지식에는 하나의 권위 있는 표현
DRY는 ‘Don’t Repeat Yourself’의 약자다. 앤드루 헌트와 데이비드 토머스는 The Pragmatic Programmer에서 시스템 안의 모든 지식은 하나의 명확하고 권위 있는 표현을 가져야 한다고 정의했다. 여기서 중요한 단어는 코드가 아니라 지식이다.
웹, 모바일 앱, 야간 배치가 할인율을 각각 숫자로 갖고 있다면 ‘할인 정책’이라는 하나의 지식이 세 번 복제된 것이다. 정책이 바뀔 때 세 곳을 함께 고쳐야 하고 하나를 놓치면 고객마다 다른 가격이 나온다. 반대로 모양이 비슷한 두 함수가 서로 다른 업무 규칙 때문에 독립적으로 변한다면, 억지로 합치는 것이 오히려 결합도를 높일 수 있다.

DRY를 너무 일찍 적용하는 문제
첫 번째 중복만 보고 곧바로 공용 추상화를 만들면 아직 드러나지 않은 차이를 매개변수와 분기로 숨기게 된다. 같은 지식인지 확신하기 전에는 작은 중복을 잠시 허용하는 편이 더 단순할 수 있다. 두세 사례가 쌓여 함께 변하는 축이 보일 때 추출하면 추상화의 이름과 경계도 더 정확해진다.
세 원칙이 충돌할 때의 우선순위
실전에서는 KISS와 YAGNI가 작은 중복을 허용하고, DRY는 그 중복을 없애라고 말하는 것처럼 보일 수 있다. 이때는 다음 순서로 판단하면 된다.
- 지금 필요한가? 확인된 사용자 요구나 운영 위험이 없다면 YAGNI로 보류한다.
- 가장 단순한 동작 경로는 무엇인가? KISS로 현재 해법의 계층·상태·의존성을 줄인다.
- 같이 바뀌어야 하는 지식이 복제됐는가? 그렇다면 DRY로 권위 있는 표현을 한곳에 둔다.
- 추상화가 변경 지점을 실제로 줄이는가? 매개변수와 분기만 늘어난다면 아직 합칠 때가 아니다.
코드 리뷰에서 바로 쓰는 다섯 질문
- 이 기능을 지금 요구하는 사용자·계약·운영 근거가 있는가?
- 새 계층이나 패턴 없이도 요구를 명확하게 충족할 수 있는가?
- 이 두 코드는 모양만 같은가, 아니면 같은 업무 지식을 표현하는가?
- 변경이 생기면 몇 곳을 함께 고쳐야 하는가?
- 오늘의 단순함을 지키면서 내일 안전하게 바꿀 테스트와 경계가 있는가?
KISS는 현재 해법의 복잡성을 줄이고, YAGNI는 불확실한 미래에 쓰는 비용을 줄이며, DRY는 지식이 어긋나는 유지보수 비용을 줄인다. 세 원칙의 공통 목적은 코드를 무조건 짧게 만드는 것이 아니라 필요한 변화를 더 싸고 안전하게 만드는 데 있다.