OCP vs YAGNI(You Aren’t Gonna Need It)
단위 테스트의 저자인 블라디미르 코리코프가 작성한 YAGNI에 대한 글을 정리한 포스팅입니다.
베르트랑 메이어의 OCP
- API 호환성에 초점을 맞춘다.
- 한 모듈이 외부에 공개된 후에는 해당 API(메서드 시그니처, 전제조건, 결과 보장 등)를 변경해서는 안 된다는 원칙이다.
- 버그 수정이나 비호환성을 일으키지 않는 변경은 가능하지만, 외부와 약속된 부분(메서드명, 파라미터, 반환 타입 등)은 닫혀 있어야 한다.
- 여러 팀이 각자 다른 모듈을 개발하는 환경에서 유용하다.
밥 마틴의 OCP
- 코드 베이스의 변경 파급 효과 최소화가 핵심이다.
- 새로운 기능을 추가할 때 기존 코드를 수정하지 않고도 확장할 수 있도록, 미리 확장 포인트를 열어두는 방식이다.
YAGNI(You Aren’t Gonna Need It) 정리
핵심 개념
- 지금 필요하지 않은 메서드나 일반화 로직을 나중에 쓸 수 있을 것이란 이유만으로 추가하지 않는다.
- 비즈니스 요구사항은 계속 변하며, 미리 만들어둔 기능이 실제로 활용되지 않을 가능성이 크다.
- 불필요한 코드는 유지보수 비용, 버그 발생 가능성, 테스트 범위 등을 늘려 결과적으로 전체 프로젝트 비용을 증가시킨다.
예외 상황
- 미래에 변경하기 어려운 부분(예: 공개 API, 3rd 파티 라이브러리, UI 등)에서는 어느 정도 앞을 내다보고 설계할 수 있다.
- 공개 API는 한번 배포하면 되돌리기 어렵고, 사용자는 새 버전을 수용해야 하므로 신중해야 한다.
- 그 외 대부분의 코드(내부 구현, 사내에서만 쓰이는 코드 등)는 필요할 때만 확장하는 게 낫다.
OCP vs. YAGNI 충돌 지점
밥 마틴 OCP vs. YAGNI
- 밥 마틴의 OCP 해석은 미래 확장을 대비해 코드에 미리 확장 포인트를 두자는 방향을 제시한다.
- YAGNI는 지금 당장 필요하지 않은 확장 포인트까지 만들지 말자고 한다.
- 두 원칙이 동시에 적용될 때, “코드를 간단하게 유지 vs. 확장성 있게 유지” 라는 충돌이 생긴다.
해결 방법
- 내부적으로만 사용하는 코드라면, 언제든 리팩터링해도 문제가 없으므로 YAGNI를 우선한다.
- 필요해졌을 때 리팩터링하여 확장 포인트를 마련하는 편이 낫다.
- 외부 팀이 사용하는 라이브러리나 API라면, 변경이 어려우므로 OCP에 더 신경 써야 한다.
- 버저닝을 의미하는것 같다. v1의 변경 없이 v2를 만들면 변경에는 닫혀있고 확장에는 열려있다.
베르트랑 메이어 OCP vs. YAGNI
- 메이어의 OCP는 API 호환성(배포된 모듈을 바꾸지 않는 것)에 국한되므로 YAGNI와 직접 충돌하지 않는다.
- 단순히 내부 코드 구조를 바꾸는 문제라면, 필요 시점에 재구조화하면 되기 때문에 YAGNI와도 충분히 조화가 가능하다.
정리
두 가지 OCP 해석
- (메이어) 외부에 공개된 API는 깨지지 않도록 닫아두고, 필요한 기능은 새 버전의 API로 추가한다.
- (밥 마틴) 미래 확장을 고려해 내부 구조를 최대한 유연하게 설계한다.
YAGNI
- 불필요한 미래 예측으로 지금 당장은 안 써도 될 기능을 만들지 말자.
- 다만, API나 UI처럼 변경이 어려운 부분에는 예외적으로 미래를 대비할 수도 있다.
우선순위
- 내부용 코드: YAGNI 우선. 필요하지 않은 곳까지 미리 추상화하지 않는다.
- 외부용 코드: OCP 우선. 배포 후 되돌릴 수 없는 변경으로 이어질 수 있으므로, 어느 정도 확장성을 고려한다.
래퍼런스
- https://enterprisecraftsmanship.com/posts/yagni-revisited/
- https://enterprisecraftsmanship.com/posts/ocp-vs-yagni