ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 설계 트레이드오프
    설계 이야기 2024. 10. 23. 11:04
    728x90

    제 글이나 강의를 보신 분들은 잘 아시겠지만 설계에 있어 가장 중요하게 생각하는 개념은 트레이드오프(trade-off)입니다. 일반적으로 트레이드오프는 한 가지를 얻기 위해 다른 것을 포기해야 하는 긴장 상황을 의미합니다.

     

    트레이드오프라는 용어를 가장 쉽게 이해할 수 있는 방법은 돈과 시간을 배분하는 경우를 상상하는 것입니다. 돈을 투자할 때는 항상 리스크와 수익 사이에서 트레이드오프를 하게 됩니다. 제 손에 쥐어진 꼬깃꼬깃한 지폐로 아이스크림을 사 먹으려면 과자는 포기해야 합니다. 지금처럼 긴 글을 쓰기 위해서는 게임을 플레이할 수 있는 시간을 포기해야 합니다.

     

    제가 가장 좋아하는 예는 침팬지와 인간의 진화에 관한 이야기입니다. 아래 그림을 보면 인간에 비해 침팬지의 순간 기억력이 인간보다 훨씬 뛰어나다는 사실을 알 수 있습니다. 침팬지는 어디에 음식이 존재하고 어디에서 적이 접근하는 지를 빠르게 판단해야만 생존 가능성이 높아지기 때문에 진화 과정에서 눈에 보이는 모든 것을 사진처럼 뇌 속에 저장하는 순간 기억력을 발달시켰습니다. 반면 인간은 침팬지와 다른 환경에 적응하면서 순간 기억력은 퇴화했지만, 대신 장기 기억력이 발달하게 되었습니다.

    인간보다 뛰어난 침팬지의 순간 기억력

     

    제가 인간과 침팬지의 이야기를 좋아하는 이유는 설계의 진화가 생물의 진화와 유사한 측면이 많기 때문입니다. 설계도 환경에 맞춰 진화해야 합니다. 시장 상황, 요구사항, 기술 발전, 팀 구성 등 설계에 영향을 주는 다양한 여러 요소들은 항상 변하기 때문에, 이런 변화에 적응하기 위해서는 어떤 부분을 발전시키고 어떤 부분을 포기할지 주의 깊게 결정해야 합니다.

     

    이것이 바로 트레이드오프의 핵심입니다. 설계를 선택할 때, 얻는 것이 있으면 잃는 것도 있다는 사실을 받아들이는 것이 트레이드오프를 이해하는 첫걸음입니다.

     

    많은 사람들이 설계에서 트레이드오프를 해야 한다고 말하면 주로 얻는 것에만 집중하는 경향을 보입니다. 반면에 잃는 것에 대해서는 충분히 고민하지 않는 것으로 보입니다. 예를 들어, "이 설계를 하면 유연성이 좋아진다"라는 말을 들으면, 그 유연성이 시스템의 다른 특성을 약화시킬 수 있다는 사실을 놓치기 쉽습니다. 코드 리뷰를 할 때면 너무 복잡하게 설계된 코드와 마주할 때가 있는데, 유연성을 높여서 얻는 이익에만 집중하고 코드의 단순함이나 가독성은 신경 쓰지 않은 결과물인 경우가 많습니다.

     

    개인적으로 설계란 트레이드오프 과정이며 현재의 상황에 가장 적합한 이익과 손해를 저울질하는 의사결정의 과정이라고 생각합니다. 비용과 지출을 저울질해 보고 가장 큰 이익을 남길 수 있는 안을 선택해야 합니다. 설계를 트레이드오프할 때는 이익보다는 손해에 집중하는 것이 현명합니다. 손해가 너무 크다면 이익이 매력적으로 보이더라도 그 설계를 선택해서는 안됩니다. 

     

    설계를 트레이드오프하는 기준은 환경에 따라 바뀌어야 한다는 점도 중요합니다. 시간이 지나면 환경도 그에 맞춰 함께 변하기 때문에, 1년 전의 이익과 손해가 오늘의 이익과 손해와 같을 수는 없습니다. 새로운 환경에 맞춰 설계를 재평가하고 적합하지 않다면 변경해야 합니다.

     

    동일한 시간대라고 하더라도 설계 중인 문맥에 따라서도 기준이 변경됩니다. 전체가 하나의 세계를 구성하는 애플리케이션 코드에서는 중복을 제거하는 것이 좋지만 각 테스트 케이스별로 하나의 세계를 구성하는 단위 테스트에서는 각 테스트별로 중복을 가져가는 것이 효과적인 경우가 있습니다. public 메서드에 전달된 파라미터의 상태를 변경해서는 안되지만 private 메서드에 전달된 파라미터의 상태를 변경하는 것은 선택할 수 있는 합리적인 옵션 중 하나입니다.

     

    많은 설계 원칙들은 좋은 설계를 만들 확률을 높일 수 있는 가이드일 뿐이지 반드시 따라야 하는 법칙은 아닙니다. 설계 원칙을 따르지 않는 경우가 유리한 경우도 있고 설계 원칙들이 서로 충돌하는 경우도 있습니다. 이 경우에도 원칙들을 트레이드오프하고 이익과 손해를 비교해 보고 손해가 가장 적은 원칙을 적용해야 합니다.

     

    설계에는 답이 없다는 이야기를 들으면 불편해하는 분들이 종종 있습니다. 아마 모든 상황에 적용할 수 있는 설계 법칙이 있다고 기대하셨기 때문일 겁니다. "이 기능은 무조건 이렇게 설계해야 한다"는 확실한 답을 원하셨을 수도 있죠. 하지만 설계에 관한 질문을 받으면 저는 먼저 그분의 코드가 어떤 상황에 놓여 있는지, 요구사항은 어떻게 변하는지, 때로는 조직 간의 관계까지도 묻습니다. 그런 자세한 내용을 알지 못한 상태에서는 설계를 트레이드오프하기 어렵기 때문입니다.

     

    설계에 답이 없다는 말은 상황에 따라 적합한 설계가 다르다는 뜻으로 이해하셔야 합니다. 정말로 답이 없다는 의미가 아니라, 상황에 맞는 설계가 존재한다는 이야기입니다. 그렇기 때문에 설계를 잘하려면 다양한 설계 옵션을 알아야 합니다. 이론을 공부하는 것도 중요하지만, 변화하는 환경에서 코드를 유지보수해 본 경험이 중요한 이유가 바로 여기에 있습니다(제가 관리자가 되면서 가장 아쉬웠던 부분인데 코드 레벨에서의 진화를 직접적으로 느낄 수 없어졌기 때문입니다. 대신 다른 부분이 성장했으니 괜찮다고 생각해야 겠죠).

     

    종종 "이 방법이 맞고, 다른 방법은 틀렸다"고 확신하는 분들과 마주하게 됩니다. 코드가 어떤 상황에서, 어떤 트레이드오프를 거쳤는지 생각하지 않고, 최종 결과만 보고 성급하게 비판하는 분들도 많이 봐왔습니다. 하지만 설계를 이해하기 위해서는 설계 당시의 환경과 그 시점에 어떤 이익과 손해를 고려해서 결정했는지를 함께 이해하는 것이 중요합니다.

     

    침팬지와 인간의 예처럼, 설계를 할 때도 현재 환경에 맞춰 발전시킬 부분과 포기할 부분을 신중히 선택해야 합니다. 모든 것을 동시에 발전시키는 것은 불가능하다는 사실을 받아들여야 합니다. 잘못된 선택을 하면, 장기 기억력은 약해지고 순간 기억력만 발달한 침팬지처럼 특정 상황에서는 적합하지만 다른 상황에서는 적응하지 못하는 시스템이 만들어지게 됩니다. 그리고 그런 시스템은 밀림에서는 생존할 수 있겠지만, 인간 사회에는 적응하지 못하고 도태되고 말 것입니다.

    728x90
Designed by Tistory.