Juicycrunch Carrot Blog
목록으로
Engineering

Zawinski's Law

소프트웨어는 왜 점점 비대해지는가? Zawinski's Law 를 정리합니다.

세탁기는 세탁만 잘하면 되는데…

슈퍼 최첨단 세탁기

“이번 신제품은 AI 세탁 코스 추천, iot, 원격제어, 음성 비서, 세탁 이력 분석 기능을 지원합니다.”

최근 배우자와 함께 세탁기를 둘러본적이 있었습니다.

저는 여러 세탁기를 둘러보면서 문득 불만이 생겼습니다. 세탁기의 가격은 점점 비싸지는데 그 이유 중에는 그다지 중요하게 생각하지 않는 기능들도 많았기 때문입니다.

분명 편의 기능은 누군가에겐 유용하겠지만, 저에게 중요한 것은 세탁 성능을 좌우하는 모터와 관리 포인트가 적은가가 중요했습니다.

기능이 늘어나게 되면 필연적으로 관리 포인트가 늘어납니다. 물론 모든 부가 기능이 고장을 일으키는 것은 아니지만 복잡도는 올라가고 가격까지 올라가는 상황이 썩 반갑지는 않았습니다.

세탁기는 세탁만 잘하면 되는데…

소프트웨어 개발에서도 이 상황과 잘 맞는, 자주 언급되는 법칙이 하나 있습니다.

Zawinski’s Law

Every program attempts to expand until it can read mail. Those programs which cannot so expand are replaced by ones which can.

모든 프로그램은 이메일을 읽을 수 있을 때까지 확장하려고 한다. 그렇게 확장하지 못하는 프로그램은 이메일을 읽을 수 있는 프로그램으로 대체된다.

자윈스키의 법칙은 소프트웨어가 점점 더 많은 기능을 끌어안다가 결국 본래 목적을 넘어 이메일까지 처리하려는 현상을 풍자합니다.

Jamie Zawinski

Jamie Zawinski

제이미 자원스키는 Netscape 의 초기 직원이자 Mozilla 발전에 중요한 역할을한 프로그래머입니다.

자원스키는 단순히 경쟁 제품을 따라 하는 문제가 아니라 플랫폼화(Platformization) 에 관한 이야기라고 강조합니다.

왜 프로그램은 커지는가?

처음부터 쓸모없는 기능을 만들려는 개발자는 없습니다. 대부분의 기능은 나름의 이유를 가지고 추가됩니다.

사용자가 불편함을 이야기하여 이를 해결하기 위한 기능이 추가되거나 경쟁 제품에 새로운 기능이 등장하면 우리 제품에도 필요하지 않을지 고민합니다. 또는 기존 기능을 사용하는 사람들을 위해 편의 기능을 더하기도 합니다.

각각의 결정만 놓고 보면 합리적입니다.

하지만 이런 결정이 반복되다 보면 어느 순간 제품이 처음 해결하려던 문제보다 훨씬 많은 일을 하게 됩니다. 단순한 스크린샷 캡쳐 프로그램이 이미지 편집, 동영상 녹화 및 편집 스튜디오가 되는것 처럼 말입니다.

문제는 새로운 기능이 ‘유용한가 아닌가’ 로만 판단할 수 없다는데 있습니다. 기능이 추가되면 구현해야 할 코드가 늘어나고 기존 기능과의 상호작용도 고려해야 합니다. 테스트해야 할 범위가 넓어지고 문제가 발생했을 때 원인을 파악하기도 어려워질 수 있습니다.

기능을 추가하기전에 고민해보자

단순히 ‘기능을 추가하지 말자’ 라는 말을 하고자 하는것이 아닙니다. 오히려 새로운 기능을 추가하려 할 때 다음과 같은 질문을 던져볼 수 있습니다.

이 기능은 제품의 핵심 목적과 관련이 있는가?

제품에는 해결하고자 하는 핵심 문제가 있습니다. 새로운 기능이 이 문제를 더 잘 해결하는 데 기여하는지 먼저 생각해 봐야 합니다.

핵심 목적과 관련이 적은 기능은 제품의 방향성, 정체성을 흐릴 수 있습니다. 개별적으로는 유용해 보이더라도 이런 기능이 쌓이면 제품이 무엇을 위해 존재하는지 모호해지기 때문입니다.

제품이 성장하면서 새로운 요구사항이 생기는 것은 자연스러운 일입니다. 그리고 구현할 수 있다해서 구현해야만 하는것도 아닙니다.

새로운 기능을 추가할 때는 제품이 해결하려는 문제를 더 잘 해결하기 위한 추가 인지 아니면 단순히 제공할 수 있다는 이유로 추가하는 것인지 구분할 필요가 있습니다.

실제 문제를 해결하는가? 아니면 경쟁 제품을 따라가는 것인가?

경쟁 제품에 특정 기능이 있다는 사실만으로 우리 제품에도 그 기능이 필요한 것은 아닙니다.

중요한 것은 기능의 존재 여부가 아니라 그 기능이 사용자의 어떤 문제를 해결하는가입니다.

다른 제품이 제공한다는 이유만으로 기능을 추가하기보다 우리 사용자가 실제로 겪는 불편과 요구에서 출발해야 합니다.

복잡성과 유지보수 비용은 얼마나 증가하는가? 그리고 비용을 감수할 가치가 있는가?

기능의 비용은 처음 구현하는 데 필요한 시간만으로 결정되지 않습니다.

눈에 보이지 않는 테스트, 문서화, 기존 기능과의 상호작용, 이후의 변경과 장애 대응까지 고려해야 합니다. 특히 기능 간 의존성이 늘어나면 작은 변경 하나가 예상하지 못한 문제로 이어질 수 있습니다.

새로운 기능은 기존 기능과 독립적으로 존재하지 않는 경우가 많습니다. 기존 동작이 달라지거나 사용자 인터페이스가 복잡해질 수도 있습니다. 기능을 추가할 때는 의도한 효과뿐 아니라 예상하지 못한 결과까지 고려해야 합니다. 이는 The Law of Unintended Consequences 에서 다루는 관점과도 맞닿아 있습니다.

더 단순한 방법으로 해결할 수 있는가?

사용자의 문제를 해결하는 방법이 반드시 새로운 기능일 필요는 없습니다. 기존 기능의 개선, 워크플로우 변경, 안내 문구의 보완만으로도 충분할 수 있습니다.

문제를 해결하려다보면 새로운 기능을 구현하는 것 자체가 목표가 되기 쉽습니다. 만약 이미 존재하는 기능을 더 쉽게 사용할 수 있도록 개선하는 것만으로도 같은 효과를 얻을 수 있다면 굳이 새로운 기능을 추가할 필요는 없습니다.

또한 모든 문제를 제품 내부에서 해결해야 하는 것도 아닙니다. 외부 서비스에서 제공하는 기능을 활용하거나 기존 도구와의 연동을 통해 문제를 해결하는 편이 더 단순할 수도 있습니다.

따라서 여러 해결 방법을 비교하고 사용자의 문제를 충분히 해결하면서도 불필요한 복잡성을 가장 적게 추가하는 방법이 무엇인지 고민해야 합니다.

문제를 해결하는 방법은 다양하기 때문입니다.

실제로 이 기능을 필요로 하는 사용자는 있는가? 있다면 얼마나 되는가?

기능의 필요성은 개발자의 예상만으로 판단하기 어렵습니다. 실제 사용자의 요청, 사용 패턴, 반복적으로 발생하는 불편 등을 살펴볼 필요가 있습니다.

물론 소수의 사용자만 필요로 한다는 이유로 무조건 제외해야 한다는 뜻이 아닙니다. 그 문제가 얼마나 심각한지, 해당 사용자에게 얼마나 중요한지, 해결하지 않았을 때 어떤 현상이 발생하는지도 함께 고려해야 합니다.

반대로 몇몇 사용자가 강하게 요구한다는 이유만으로 기능을 추가하는것도 주의해야 합니다. 목소리를 적극적으로 내는 사용자가 전체 사용자의 요구를 대표한다고 볼 수는 없기 때문입니다. (다수의 침묵)

따라서 사용 패턴과 이탈률, 반복적인 수작업, 사용자 인터뷰 등 다양한 지표를 통해 드러나지 않은 문제까지 살펴볼 필요가 있습니다.

결론적으로 중요한 것은 목소리에 귀를 기울이는것은 맞지만 목소리의 크기만으로 판단해선 안된다 입니다.

나중에 이 기능을 제거할 수 있는가?

기능을 추가하는 결정은 비교적 쉽게 내릴 수 있지만, 이미 제공하기 시작한 기능을 제거하는 일은 훨씬 어렵습니다. 해당 기능에 의존하는 사용자와 다른 기능이 생기기 때문입니다.

기능을 제공하기 시작하면 사용자는 이를 제품의 일부로 받아들이고, 자신의 작업 방식이나 다른 도구와의 연동에 활용할 수 있습니다. 처음에는 부가적인 기능이었더라도 시간이 지나면 누군가에게는 반드시 필요한 기능(Hyrum’s Law) 이 될 수 있습니다. 따라서 기능을 제거하려면 단순히 코드를 삭제하는 것 이상의 고민이 필요합니다.

물론 제거하기 어렵다는 이유만으로 모든 기능을 계속 유지해야 하는 것은 아닙니다. 사용 빈도가 낮고 유지 비용이 크거나 제품의 핵심 목적과 맞지 않는 기능이라면 어려운 결정이지만 제거하는 편이 더 나을 수도 있습니다.

따라서 기능을 추가하기 전에 이 기능이 애물단지가 되었을때 쉽게 제거할 수 있을지 한 번쯤 생각해 볼 필요가 있습니다.

마치며

기능을 더하는 것과 문제를 더 잘 해결하는 것은 다르다고 생각합니다.

중요한 것은 새로운 기능이 해결하려는 문제와 그로 인해 발생하는 비용을 함께 살펴보는 일입니다. 때로는 새로운 기능을 만드는 것보다 기존 기능을 개선하거나 불필요한 기능을 제거하는 편이 더 나은 선택일 수 있습니다.

결국 좋은 소프트웨어는 단순히 많은 기능을 제공하는 소프트웨어가 아니라 필요한 문제를 잘 해결하면서도 불필요한 복잡성을 경계하는 소프트웨어라고 생각합니다.

세탁기를 고를 때도 소프트웨어를 설계할 때도 마찬가지라 생각합니다.