오버엔지니어링과 언더엔지니어링의 경계

산 정상 호수에 남자가 혼자 서 있는 사진

YAGNI(You Aren’t Gonna Need it)란 약어에는 오버 엔지니어링에 대한 경계심이 담겨 있다. XP(eXtrem Programming)는 설계 결정의 순간을 최대한 미루는 것을 설계 원칙으로 제시한다. 당장에 필요한 것에만 집중함으로써 지금 하지 않아도 될 일을 하지 말라는 뜻이다. 낭비를 경계하는 일은 실용주의 개발자의 미덕이다.

잠깐, 실용주의 개발자가 알아야 할 것이 하나 더 있다. 설계 결정을 미루기 위해서는 개발자가, 변화를 수용하는 시스템을 설계할 수 있는 능력을 가져야 한다는 점이다.

최소한의 설계로만 시스템을 개발하면서 아직은 때가 아니라고 여겨지는 설계 결정을 뒤로 미뤘다. 더 이상 결정을 미룰 수 없는 순간이 왔다. 고치려고 보니 이미 너무 먼 길을 와버렸다. 들어가는 수정 비용이 너무 커서 아무 것도 할 수 없다. 이런 경험을 누구나 한 번쯤은 해 보았으리라. 한 번 데이고 나면 모든 게 설계 문제로 보인다. 이때부터는 오버엔지니어링으로 흐르기 쉽다.

딜레마에 빠진다. 무작정 미루기에는 내일이 걱정이고, 오늘 하자니 이게 정말 필요한 건지 모르겠다. 오버엔지니어링과 언더엔지니어링. 둘 사이의 경계는 어디인 걸까? 둘 사이의 어디쯤에 우리는 자리를 잡아야 할까?

시소의 균형을 잡는 이런 문제를 두고 흔히 답이 없다고들 한다. 답은 없다. 하지만 전략은 있어야 한다. 어떤 전략을 가지고 전쟁에 임할 것인가. 몇 번의 삽질을 거치며 내가 선택한 전략은 이렇다.

문제를 해결하는 최소한의 설계를 하되, 퇴로는 열어두자. - 내 머릿속

지금 눈 앞에 닥친 문제를 해결하는 데에 필요한 최소한의 수준으로만 설계를 한다. 다만 상황이 바뀌었을 때 발생할 변경 비용은 결정을 내리는 시점에 함께 검토를 한다. 나중에 설계를 변경했을 때, 시스템의 안전성을 보장할 만큼의 테스트 커버리지를 확보하여 퇴로를 항상 열어둔다.

자, 바로 이것이다. 오! 소프트웨어 아키텍트여, 당신은 미래를 내다봐야만 한다. 당신은 현명하게 추측해야만 한다. 당신은 비용을 산정하고, 어디에 아키텍처 경계를 둬야 할지, 그리고 완벽하게 구현할 경계는 무엇인지 와 부분적으로 구현할 경계와 무시할 경계는 무엇인지를 결정해야만 한다. - Clean Archictecture, 243 P

미래는 아무도 모른다. 희대의 예언자라는 노스트라다무스의 예언도 틀리지 않던가. 어쩔 수 없다. 수긍하자. 미래는 불확실하고 변경은 상수라는 사실을. 위험을 감지하는 촉을 기르는 수밖에 없다.

개발을 진행하면서 설계에 잠재적 위험이 없는지 계속 들여다봐야 한다. 조금의 위험이라도 감지를 했다면, 지금 해결해야 할 문제인지, 더 미뤄도 될 일인지 살펴보고 판단해야 한다. 좋은 아키텍트는 오늘과 내일의 경계 위에서 춤을 춰야 한다.

설계의 촉을 예민하게 세워야 한다. 촉을 세우려면 설계를 알아야 하고 엔지니어링을 알아야 한다. 아는 만큼 본다. 알아야 촉이 생기고, 퇴로를 만들고, 기회를 잡을 수 있다.