구성 플래그는 유연성을 제공하는 대신 유지보수 비용, 테스트 복잡성, 설계 문제를 숨기는 방식으로 소프트웨어를 서서히 망가뜨릴 수 있다.
2026년 4월 11일
사람들은 구성 가능한 소프트웨어를 좋아한다.
사람들은 유연성은 언제나 좋다고 말한다. 더 많은 플래그, 더 많은 조절 항목, 더 많은 환경 변수, 그리고 가능한 모든 사용 사례에 소프트웨어를 맞출 수 있는 더 많은 방법을 원한다.
하지만 실제로는 구성 플래그는 종종 불확실성을 정중하게 출하하는 방식일 뿐이다.
기능 하나가 추가되었지만, 그것을 기본적으로 활성화해야 하는지 아무도 완전히 확신하지 못한다. 그래서 플래그가 붙는다.
동작 하나가 바뀌었지만, 하위 호환성은 두렵다. 그래서 플래그가 붙는다.
상반된 것을 원하는 사용자가 둘 있다. 그래서 두 경로 모두 플래그 뒤에 숨겨진 채 코드 안에 영원히 남는다. 얼핏 보면 이것은 합리적으로 보인다.
물론 플래그가 유용할 수는 있다. 실험적 기능은 테스트할 방법이 필요하다. 마이그레이션에는 때때로 임시 탈출구가 필요하다. 그리고 어떤 소프트웨어는 실제로 충분히 다른 환경에서 사용되기 때문에 몇 개 정도의 스위치를 정당화할 수 있다.
하지만 임시 플래그는 좀처럼 임시로 남지 않는다. 플래그가 한 번 존재하기 시작하면, 곧 의존성을 끌어모으기 시작한다.
문서는 그것을 언급해야 한다. 지원 담당자는 그것이 활성화되어 있는지 물어봐야 한다. 버그 보고에는 그것이 포함되어야 한다. 테스트는 두 상태를 모두 다뤄야 한다. 새 기능은 어느 쪽과 호환되는지 결정해야 한다. 그리고 그 플래그가 파일 형식, 프로토콜, 또는 영속되는 어떤 것에 영향을 준다면, 나중에 그것을 제거하는 일은 고통스러워진다. 그것이 진짜 비용이다.
플래그 뒤에 있는 코드는 기능 하나가 아니다. 그것은 이제 유지관리자들이 계속 살려 두어야 하는 두 개의 가능한 세계다.
플래그들이 서로 독립적이지 않을 때 상황은 더 나빠진다. 한 플래그는 타임아웃을 바꾼다. 다른 하나는 버퍼링을 바꾼다. 또 다른 하나는 동시성을 바꾼다. 각각만 보면 무해해 보인다. 하지만 함께 놓이면 아무도 실제로 테스트하지 않은 구성 공간이 만들어진다.
그러면 사용자들은 기술적으로는 지원되어야 하지만 실제로는
FAST_MODE=0
,
LEGACY_IO=1
, 구형 파서, 그리고 투표할 수 있을 만큼 오래된 커널에서만 되는 설정에서 “작동하지 않는다”라고 보고한다.
그 조합은 누구도 설계한 적이 없다. 그냥 그렇게 되어 버린 것이다. 그리고 이제 그것은 당신의 문제가 된다.
많은 소프트웨어 팀은 불리언 하나를 추가하는 일이 싸게 보인다는 이유로 플래그를 공짜처럼 취급한다. 하지만 그렇지 않다.
인터페이스에 있는 불리언은 보통 유지보수에서의 분기 요인을 뜻한다.
이 점은 오픈 소스에서 특히 분명하다. 사용자가 틈새 기능을 요청하면, 플래그를 추가하는 것은 타협처럼 느껴진다. 유지관리자는 그 동작을 새로운 표준으로 승인할 필요가 없고, 사용자는 원하는 것을 얻게 된다.
하지만 실제로 일어난 일은 유지관리자가 자신은 아마 결코 직접 쓰지 않을 동작에 대해 장기적인 책임을 떠안았다는 것이다.
기여자는 사라질 것이다. 플래그는 남을 것이다.
그리고 5년 뒤, 어떤 불쌍한 영혼이 왜
--compat-relaxed-fsync
가 FreeBSD의 새 백엔드와 함께 사용할 수 없는지 물을 것이다. 소프트웨어에는 기억이 있기 때문이다.
무서운 부분은 플래그가 종종 설계 문제를 숨긴다는 점이다.
사용자들이 어떤 서브시스템을 비활성화하기 위해 정기적으로 플래그를 필요로 한다면, 어쩌면 그 서브시스템이 너무 성급한 것일지 모른다.
성능을 위해 반다스의 조정 변수가 필요하다면, 아마 기본값이 나쁘거나 아키텍처가 취약한 것일지 모른다.
마이그레이션에 세 세대에 걸친 호환성 토글이 필요하다면, 아마도 오래된 동작이 새로운 동작으로부터 애초에 명확하게 분리된 적이 없었던 것일지 모른다.
플래그는 실제 문제를 해결할 수 있다. 하지만 동시에 누군가가 “이 동작은 잘못되었고, 이제 사라져야 한다”라고 말해야 하는 순간을 막음으로써 나쁜 설계를 계속 살려 둘 수도 있다.
물론 옵션을 제거하면 사람들을 화나게 할 수 있다. 하지만 모든 것을 영원히 유지하는 일은 대신 유지관리자들을 조용히 지치게 만든다.
그 비용은 눈에 덜 띈다. 왜냐하면 그것은 망설임, 더 느린 릴리스, 방어적인 코딩, 이상한 버그, 그리고 법률 약관처럼 읽히는 문서로 나타나기 때문이다.
그렇다면 소프트웨어에는 플래그가 전혀 없어야 할까? 당연히 아니다.
하지만 플래그는 부채와 같은 지위를 가져야 한다. 때로는 필요하지만, 결코 공짜가 아니며, 언제나 의심스럽다.
모든 새 플래그에는 만료에 대한 이야기가 함께 따라와야 한다.
왜 이것이 존재하는가? 누가 이것을 필요로 하는가? 이것이 사라지면 무엇이 깨지는가? 언제 그것이 받아들일 만해지는가? 아무도 이런 질문들에 답할 수 없다면, 그 플래그는 아마 기능이 아닐 것이다.
그것은 진행 중인 화석이다.