최고의 아키텍처는 무엇일까?

Silver Bullet이 있을까

설계를 하고 코드를 짜다보면 항상 드는 생각이 있다. 이 문제에 대한 최고의 답이 존재할까? 개발자로서 처음으로 일을 시작할 때에도 그리고 지금도 계속해서 하는 생각이다. 이 일을 오래하게 된다면 언젠가는 알게되지 않을까 어렴풋이 생각했던 것 같다. 코드 한줄의 레벨에서도 무엇이 정답일지 고민했고 설계 레벨에서도 마찬가지의 고민을 이어갔다. 그렇게 짧다면 짧고 길다면 긴 3년의 시간이 흘렀고, 이제와 돌아보니 소프트웨어 개발도 결국에는 공학이라는 생각이 들었다. 나에게 공학은 진리를 찾기보단 주어진 제약 상황에서 최적을 찾는 것에 가까웠다. 물론 소프트웨어를 진리에 대한 탐구로서 접근할 수도 있지만 현업에서 계속 일을 하다보면 어쩔 수 없이 멈춰야하는 부분을 만나게 된다. 내가 만났던 그 수많은 정지선들이 생각난다. 매번 더 할 수 있을 것 같았고 더 좋은 것이 있을 것 같았지만 이내 아쉬운 마음으로 돌아섰던 기억들이 떠올랐다.

돌아가는 코드 혹은 돌아버리게 만드는 코드

특정 상황에 대한 답을 찾는 것은 어렵지 않았다. 함수 하나를 완벽하게 짰다고 생각하는 것은 어려운 일이 아니었다. 자바의 equals를 처음에 overwrite하던 기억이 난다. 간단히 값만 비교만 하면 될줄 알았던 당시의 나는 오브젝트의 같음을 알기 위해 그렇게 많은 것들이 체크되어야 하는지 몰랐었다. 그렇게 하나둘씩 배우고 익혀가며 개발하는 것에 큰 재미를 붙였다. 이렇게 쭉 배워나가면 모든 것을 알게될 것 같은 느낌이었다. 모든 것엔 정답이 있고 설계 조차도 특정 상황에 대해서는 이런 패턴을 쓴다는 정답이 있다고 생각했다. 아직 기존에 개발된 코드에 덧붙여서 기능 몇 개를 더하던 시절이었기 때문에 항상 더 좋게 더 뛰어나게 개발할 수 있을 것이라고 생각했다.

하지만 간과한 것이 있었으니, 이곳은 스타트업이었다. 첫 직장도, 두 번째 직장도, 그리고 현 직장도 모두 스타트업이었다. 스타트업에서 가장 중요한 것은 생존이고 그 생존은 타이밍과 직결된다. 스타트업의 개발은 코드 자체의 퀄리티도 중요하지만 기능의 배포 속도가 더 중요하다. 그렇게 나도 어느샌가 정신을 차리고나니 돌아가기에 급급한 코드들을 양산하고 있었다. 신입 개발자분들이 오시면 그저 부끄럽기 그지 없었다. 내 코드를 보며 얼마나 구린내를 맡을까 얼굴이 빨개졌다. 내가 주니어 개발자로 있던 시절에 느꼈던 것이었다. 더 잘할 수 있지만 그렇게 하지 못해 어느 지점에서 멈춰선 코드들. 변명처럼 들릴 수도 있다. 사실 맞다. 내가 더 뛰어났다면 시간 핑계를 대지 않고 좋은 코드를 짤 수 있었을 것이다. 그래서 항상 나는 변명 삼아 내게 말을 했다. 그래 시간이 부족해서 그렇지 더 잘 할 수 있다고.

종속성과 변경가능성

돌아가는 것이 전부가 아니라 코드를 깨끗이 보기 좋게 짜는 것이 중요한 이유는 내가 천년만년 해당 코드를 유지보수할 것이 아니기 때문이다. 그보다 한 단계 더 나아가 내가 짠건지 다른 사람이 짠건지 알 수 없을 정도로 스타일과 로직이 거의 유사한 수준까지 발전할 수도 있다. 개발자들 간의 수많은 코드리뷰와 소통이 그런 것을 가능하게 할 것이다. 그저 부럽기만 하다. 어쨌든 중요한 것은 개발자들은 항상 내가 작성한 코드가 언젠가는 변해야 되는 순간이 온다는 것을 알고 있어야 한다. 그런데 악마는 바로 이곳에만 머물지 않고 소프트웨어 전체로 퍼져나간다. 바로 종속성이라는 지하 열차를 통해서.

클린 아키텍처라는 책은 바로 이 변경가능성이라는 악마가 퍼져나가는 다리들을 어떻게 만들어야 유지보수가 가능한, 즉 개발자의 야근을 방지할 수 있는 설계가 가능한지에 대한 방법론을 제시한다. 핵심은 가장 중요한 로직, 즉 서비스의 비즈니스 룰은 종속성의 영향에서 거리가 아주 멀어야 된다는 것이다. 극단적으로 말하면 버튼 문구의 변경이 구매 로직에 영향을 주어서는 안된다는 말이다.

종속성을 달리 표현하자면 누가 알아야 하는가?에 대한 문제로 볼 수 있다. 비즈니스 룰과 같이 서비스의 핵심 동작들은 그들만 알면 되며, 이를 뒷받침해주는 DB, 웹, UI 등은 모두 세부사항으로서 핵심 동작의 일부에 종속성을 갖고 현실 세계에서 사건들을 만들어준다. 두 그룹 간에는 인터페이스가 있고, 이 인터페이스를 누가 내장할지, 누가 상속할지를 통해 종속성의 화살표 방향을 조절한다. 종속성이 한 방향으로 너무 길어지거나, 변경 가능성이 많은 컴포넌트에 종속된 경우 종속성을 끊어준다.

이렇게 변경가능성으로부터 중요한 로직들을 지켜내고, 종속성 자체를 유지보수함으로서 스프트웨어의 복잡성을 관리한다. 마술 같은 일이다.

수많은 이터레이션, 진화 그리고 성장

클린 아키텍처의 필자가 강조하는 것 중에 가장 와닿았던 것은 아키텍처조차 계속해서 개선되고 진화한다는 것이었다. 소프트웨어 또한 결국에는 사용자들의 효용을 위한 것이기에 가장 중요한 전제들과 동작들은 종속성과 변경가능성으로부터 지키되, 처음부터 너무 완벽하게 시스템을 가져가는 것은 경계해야 한다. 이유는 간단한데, 서비스의 제공 타이밍이 중요하기 때문이다. 또한 변경가능성에 대한 예측이 사실상 어렵다는 것에 있다. 모든 종속성을 완벽히 조절해놨지만 해당 부분이 변경가능성과는 거리가 멀다면 개발자로서는 훌륭했지만 서비스를 하는 회사 입장에서는 필요없는 일을 한 것일 수도 있기 때문이다. 따라서 가장 바람직한 것은 진화되어가는 사용자의 요구에 맞추어 아키텍처는 변화시키는 것이다. 그리고 항상 어느부분이든 변화할 것이라고 생각하는 것이다. 마지막으로 그 변화의 시기가 왔을 때에 다시 또 새로운 미래를 준비하는 것이다. 시스템은 그렇게 계속 진화해가며 그 시스템을 만드는 개발자 또한 성장한다.

결론

따라서 나는 정답은 없다고 결론내렸다. 아키텍처는 어떤 문제에 대한 답이 아니기 때문이다. 소프트웨어 설계는 끊임 없는 스무고개이다. 답은 유저도 모르고 서비스하는 사람도 모른다. 그저 서로 많이 가까워졌다가 살짝 멀어졌다가 할 뿐이다. 그런 유동적인 상황에서 아키텍처는 진화의 속도를 유지할 수 있는 형태를 갖춰야한다. 지금 내가 개발한 시스템이 그런 방식으로 진화하고 있다면 지금 나쁘지 않게 하고 있다는 증거라고 생각한다. 대체적으로 시스템은 점점 더 복잡해지고 더 많은 것들을 제공할 수 있도록 변하기 때문에 개발자들은 서비스의 성장에 걸맞는 새로운 도전 과제들을 항상 맞닥뜨리게 된다. 그런 것들을 하나씩 풀어가며 버터고 견디어내고 있다면, 그래 그걸로 충분하다. 나는 내 서비스가 내주는 도전들을 통해 성장할 것이다. 코드 천재나 개발 천재의 느낌은 아니지만, 사용자들에게 끊임 없이 효용을 줄 수 있는 개발자로 성장하는 것도 이제는 내게 자랑스러운 일이 되었다.

최고의 아키텍처는 아직 오지 않았다. 정지선에 멈춰선 이유는 직진 신호가 아직 오지 않았기 때문이다.