로버트 마틴의 <클린 아키텍처>를 처음 읽었을 때 이게 뭔 소리인가 싶었습니다. 책의 중반부인 22장 '클린 아키텍처' 부분을 읽은 순간부터 조금이나마 마틴의 철학에 공감하기 시작했습니다.
근데, 공감만 하고, 이해는 못했기에 톰 홈버그가 지은 <만들면서 배우는 클린 아키텍처>를 샀습니다. 자바랑 웹 작업은 잘 모르지만, 뭐 특정 언어나 작업을 위한 책은 아니니까 읽을 수 있다는 믿음으로 구매했습니다.
하지만, 코드의 흐름을 따라갈 수 없었습니다. 특히 도메인 중심의 얘기를 많이 하는데 게임 개발자인 저는 도저히 이해를 못하고, "아니 리뷰에는 쉽다매!! 초급자용이라매!!" 를 외치며 읽었습니다. 그럼에도 불구하고 육각형 아키텍처에 대한 부분은 확실히 유용하다고 생각하였고, 다시 읽으고, 노트에 정리하면서 결국, 이해란 것을 하게 되었습니다.
하지만, 여전히 의심이 있었습니다. 정말 아키텍처를 견고히 만드는 것이 그걸 만드는 데 드는 비용 대비 더 많은 것을 가져다줄까? 이거 정말 실무에서도 도움이 될까? 라는 생각이 들기 시작했습니다.
그러던 중, 생각치도 못한 곳에서 인사이트를 얻었습니다. 당시 읽고 있었던 책인 <넛지 : 파이널 에디션>이였습니다. 읽다보니 클린 아키텍처가 넛지에서 말한 선택 설계와 거의 유사하다는 깨달음을 얻었고 이러한 관점으로 바라봤을 때 왜 클린 아키텍처를 사용해야 하는지에 대한 통찰을 얻을 수 있었습니다.
넛지는 '(특히 팔꿈치로) 슬쩍 찌르다' 라는 뜻으로, 내비게이션 길 추천, 식당의 메뉴 순서와 같은 부드러운 개입을 의미합니다.
의미를 보시면, 굉장히 다양한 곳에서 사용될 수 있는 단어입니다. 그냥 특정 행동을 유도하는 선택 설계니까요.
그리고 앞으로 알아보겠지만, 클린 아키텍처도 이러한 선택 설계 중 하나라고 볼 수 있습니다.
계층 간 의존성을 관리하고, 리팩터링을 자주 하도록 유도해 단단한 아키텍처를 쌓아 나가도록 하는 것이죠.
이 글에서는 클린 아키텍처와 관련된 이론적인 얘기를 하지 않습니다. 클린 아키텍처를 쓰면 개발적으로 어떻게 좋은지에 대한 얘기도 디테일하게 하지 않습니다. 그 이야기는 아예 글을 따로 쓸 생각입니다.
대신, 잘 짜여진 아키텍처가 우리를 어느 방향으로 어떻게 유도하는지를 <넛지 : 파이널 에디션> 에서 나온 방법을 이용해서 제가 나름대로 분석한 내용이 핵심입니다.
클린 아키텍처에서의 넛지를 설명하기 전에, 그런 것들이 없다고 가정하면 우리가 코드를 망치는 게 이유에 대한 얘기를 먼저 하도록 하겠습니다.
사실 인류는 꼭 코드가 아니더라도 특정 시스템 없이 무언가를 깨끗하게 유지하는 건 불가능하다는 것을 엄청나게 큰 사이즈로 긴 역사를 통해 증명했습니다. 바로, 환경이죠.
잠시 세상 돌아가는 이야기를 해보죠. 최근 기후변화가 아주 심각한 수준으로 체감이 되고 있습니다. 유럽은 역대 최고 기온을 해마다 갱신하는 기염을 토하고 있고, 강남은 침수되고, 더 강한 태풍이 더 자주 생기고, 산불은 너무 자주 일어나서 저게 원래 저랬나~ 싶습니다.
말 그대로 인류의 대위기입니다. 그리고, 이는 인류의 업보라고 할 수 있죠. 기후변화가 중대한 문제라는 건 너도알고 나도알지만, 열심히 석탄을 때고, 탄소를 배출했죠.
마치 조별과제 미루기처럼 폭탄을 돌리다가 결국 지구 교수님의 F폭탄이 터지기 직전까지 와버렸습니다. 심지어, 재수강도 못하죠.
왜 이랬을까요? 그 이유를 알아보겠습니다. 그리고 결론적으로 이 전 세계적 현상이 우리 프로젝트에서 일어나는 일하고 크게 다르지 않다는 것도 알아보겠습니다.
사람은 나중보다 지금을 더 중요하게 여기는 경향이 있습니다. 당연히 2개월 뒤 기말고사보다 눈앞에 중간고사가 중요하지 않겠습니까?
기후변화는 미래 세대가 해결할 문제고 우리는 지금 당장의 문제를 해결하느라 바빴죠. 하지만 눈떠보니 지금 당장 결제해야할 청구서가 눈앞에 있습니다.
시중에는 여러 친환경 제품들이 있습니다. 근데 그 제품들이 친환경적이라고 느낄 수 있습니까? 정부에서 인증했다는 친환경 딱지 하나 붙었다고 우리가 그걸 사는 이유가 되지는 않습니다.
만약 게임을 한다고 생각할 때 더 비싼 아이템을 사는 이유는 무엇입니까? 게임사에서 "이 제품은 짱짱 좋음" 도장이라도 찍어줘야 삽니까? 아니요. 답은 훨씬 더 간단한 이유죠. '스탯 증가'.
만약 우리가 어떤 선택을 했을 때 얼마만큼의 탄소 배출량을 아끼는지 나타내는 앱이 있다면 어떨까요? 친환경 제품을 고를 때마다 다른 제품과 비교해 얼마나 친환경적인지 인증 마크가 아니라 숫자로 알려주는 겁니다. 그리고, 내가 하루에 얼마나 탄소를 배출했는지도 알려주는 거죠. 마치, 일일 핸드폰 이용시간처럼 말이죠. 그럼 하루가 지날때마다 점점 줄어가는 탄소 배출량을 보면서 나름의 재미를 느끼지 않을까요? 친구랑 내기도 하고요. SNS에서 '탄소 무배출 챌린지' 같은 걸 할 수도 있습니다.
하지만 그건 꿈입니다. 현실적으로 불가능하죠. 그래서 우리는 손해를 보고 친환경 제품을 구매할 때 이게 얼마나 환경을 위한 선택인지 알 수 없습니다. 하지만 타 제품에 비해 얼마나 비싼지는 명확한 수치로 나오죠. 그렇다면 저희는 현저성을 기준으로 더 눈에 띄고 와닿는 '합리적인' 선택을 하게 됩니다. 문제는 그 선택이 환경에 안 좋다는 것이죠.
기후 변화는 특정 인물의 테러가 아닙니다. 전 인류가 함께한 테러죠. 그렇기에 특정 인물, 단체를 탄압할 때보다 단합이 쉽지 않고 대중의 관심을 불러일으키고 문제 해결을 위한 자원을 동원하는 것이 어렵습니다.
"다이어트 실패하면 100만원 잃기 VS 다이어트 성공하면 100만원 얻기" 어떤 내기가 더 마음에 와닿나요? 많은 연구로 밝혀져서 이제는 너무나 많은 사람이 알고 있지만 사람은 동일한 크기의 이익과 손실 사이에서 손실에 더 민감하게 반응합니다.
그리고 기후 변화에 대처한다는 건 손실을 감수하는 것과 비슷합니다. '기후세'라는 세금이 붙어서 친환경적이지 않은 상품의 가격이 오른다고 생각하면 편합니다. 기후세가 안 붙은 상품만 사면 된다고 생각할 수도 있지만, 신재생 에너지로 바꾸면서 생산 비용이 올라갈 것이기 때문에 사실상 모든 제품의 가격이 올라갈 것입니다.
기후변화에 특성 상 이득에 대한 피드백은 거의 느껴지지 않는데 그 대가로 저희의 지갑을 요구한다면 반발감은 거셀 겁니다.
위에서 언급한 모든 어려움을 이겨내고 우리나라에서는 새로운 삶이 노말이 됐다고 칩시다. 전기세는 거의 2배 올랐고, 옷이나 식료품같은 가격도 엄청 오르고, 월급이나 용돈은 그대로고... 그래도! 지구가 없으면 우리도 없으니까! 일단 했다고 칩시다! 근데...... 그게 뭐요?
기후 변화는 전 세계적 문제입니다. 우리나라가 고생고생해서 바뀐다고 해도 다른 곳에서 그대로라면 달라지는 거라고는 원래도 얇았는데 더 초라해진 저희의 지갑 뿐입니다. 정말 슬프겠군요.
근데 관점을 바꿔서 반대로도 생각할 수 있습니다. 우리가 안하고 다른 몇몇 국가가 해주면 되는거 아닌가?
이런 생각을 전부 하다보니, 다같이 힘을 합쳐도 될까말까인걸 서로 "누가 먼저 안해주나~" 하고 눈치만 보고 미루고 있으니, 기후 변화 문제가 해결되면 그게 더 놀라운 수준일 겁니다.
이렇게 수많은 이유로 기후변화는 현재진행형입니다. 그럼 기후변화가 특성을 한 줄 요약해보죠.
특이점을 넘으면 되돌릴 수 없는 손실이 미래에 발생한다.
손실이 미래에 발생한다는 것은 최악의 특성입니다. 미래를 대비하기 위한 손실은 당연히 현재에 발생하는데 지금 내가 고생하는 이유가 미래에 무언가를 얻기 위해서도 아니고, 그저 현상유지를 하기 위함이기 때문입니다.
이는 마치 팔팔한 학생들에게 치매가 언제 올지 모르니 독서를 생활화하라는 것과 비슷합니다. 심지어 산업혁명은 1760대에 일어났으니 기후변화는 그것보다 심한 수준이라고 할 수 있겠군요.
이 이야기는 저희의 프로젝트에도 그대로 적용할 수 있습니다. 지금도 잘 작동하는데 굳이 리팩터링하기도 귀찮고, 도중에 버그가 나오는 게 무서워서 피하죠. 이렇게 해서 얻는 거라고는 코드가 깨끗해졌다는 '느낌'입니다.
열심히 한다 해도 수치적인 피드백은 없고, 내가 해봤자 다른 팀원들이 안 하면 아무 의미 없고, 지금 당장 뭘 얻는 것도 아니고 다른 해야 할 일도 많으니 일단 하던 일부터 하게 됩니다
그렇게 계속 방치하다 보면은 생산성이 떨어질 겁니다. 당장은 느끼지 못해도 꾸준히 내려갑니다. 이런 일들이 반복되면, 어느 순간 예상보다 훨씬 더 큰 비용을 감당해야 하는 순간이 올 겁니다.
지금까지 말한 거에 핵심은 특별한 장치 없이는 코드가 망가지는게 딱히 이상한 일이 아니고, 오히려 당연하다는 것입니다. 인간이 현재의 일을 과대평가하고 미래의 손실은 과소평가 한다는 것은 전 세계가 역대 최고 온도를 매년 갱신하고, 지구를 뜨겁게 달구며 증명했습니다.
지구의 축소판이라고 할 수 있는 개발 팀도 크게 다르지 않겠죠. 그럼 어떻게 해야 할까요? 역시 기후변화에서 아이디어를 따 오자면 정책을 만들고 시행하는 겁니다.
이때 저희 프로젝트에서 정책의 역할을 해주는 것이 바로 클린 아키텍처 입니다.
좋은 아키텍처는 소프트웨어 계층을 분리함으로써 관심사의 분리를 이뤄냅니다. 동시에 이러한 구조가 계속 유지될 수 있도록 사람들의 코딩 방식을 넛지(유도)하는 면도 있습니다. 지금부터는 이 부분에 대해서 알아보겠습니다.
앞서 언급한 현상 유지 편향과 비슷한 맥락인데, 사람들은 디폴트 옵션을 꽤나 선호합니다. 물론 게임을 좀 하시는 분들이라면 "아닌데? 난 맨날 마우스 감도 바꾸는데?" 하실 수도 있습니다.
하지만 객관적으로 돌아봅시다. 게임에는 수십개의 단축키와 그래픽 옵션이 있습니다. 그 중에 감도나 단축키 한 두개 바꿨다고 디폴트 옵션을 싫어한다고 하실 수 있나요? 몇 년동안 한 게임일지라도 80% 넘게 디폴트 옵션을 쓰고 있지 않나요? 그런 느낌입니다.
그렇다면 클린 아키텍처의 디폴트 옵션을 뭘까요? 여러 가지가 있지만 가장 핵심적인 규칙은 의존성의 방향입니다.
위 그림과 같이 안으로 들어가는 의존성 구조를 가집니다. 지금은 그냥 계층 간 분리가 되어있고 안으로 들어가면 들어갈수록 애플리케이션의 핵심 정책이라는 것만 알면 됩니다.
핵심은 아키텍처에서 특정 기능의 계층과 의존성 방향이 정해져있다는 것입니다. 특정 기능이 위치하는 계층이 어디인지, 어떤 계층을 의존하고 있는지, 어느 계층이 이것을 의존할지가 한 눈에 보이죠. 즉 의존성을 어떻게 관리해야 하는지가 디폴트로 정해져 있습니다.
어떤 일을 할 때 걸림돌이 있으면 그 일을 실행할 확률은 현저히 떨어집니다.
누군가가 헬스장을 가지 않는 이유가 의지력 부족일 수도 있지만, 안 그대로 방금 일어나서 피곤한 상태에서 다시 잠들고 싶은 유혹을 이겨내고, 핸드폰하고 싶은 마음도 물리치고, 샤워도 하고, 옷도 고르고, 짐도 싼 다음에 헬스장을 가야해서 그런 걸 수도 있습니다.
어떻게 개선할 수 있을까요? 핸드폰 잠금 앱을 이용해서 일어날 시간 즈음에 폰을 잠궈 놓고, 옷 고르는 거랑 짐 싸는 건 전날에 끝내고, 샤워는 헬스장에 가서 하면 어떨까요? 원래 가던 것보다 일주일에 2번 정도는 더 가지 않을까요?
이는 리팩터링에도 적용됩니다. 리팩터링이 절실히 필요한 코드는 사실 그 어떤 코드보다 리팩터링하기 어렵습니다. 어디부터 고쳐야할지 감도 안오고, 열심히 고쳐도 버그가 펑펑 터지기 때문입니다. 특히 어떤 기능에 의존하느냐에 따라서 생각지도 못한 곳에서 버그가 생길 확률이 있습니다.
이런 환경에서는 리팩터링을 할 의욕이 1도 나지 않습니다. 만약 심각성을 인지하고 코드를 살짝 변경해 볼지라도, 예상치 못한 버그가 생겨서 화들짝 놀라며 bash를 연 다음 git reset 으로 변경사항을 되돌린 다음에 "휴~ 큰일날뻔~ git 짱짱!!" 을 외치겠죠.
git 덕분에 버그를 없앤 건 다행이지만 계속 그 코드를 놔둔다면 더 많은 버그가 생기고, 더 큰일이 날 것입니다.
하지만, 클린 아키텍처는 계층 간 의존성이 명확하기 때문에 이런 위험성이 덜합니다. 만약 버그가 생긴다고 해도 어느 곳에서 문제가 발생했는지 빠르게 알 수 있습니다.
피드백은 사람이 특정 행동을 하도록 유도하는 역할을 합니다. 사실 TDD라는 방법론이 나온 배경 중에 '명확한 피드백'도 나름 지분이 있을 겁니다.
물론 테스팅은 성공과 실패라는 단순한 피드백을 하지만, 잘 짜여진 아키텍처에서의 테스팅 코드는 탄광에서 나오는 유독 가스에 민감해 광부들이 갱도에 데려간 카나리아처럼 프로젝트에 위험을 알리는 역할을 합니다.
테스팅을 작성하는데 너무 많은 의존성이 존재해 목킹이 버거워지거나, 리팩터링을 할 때마다 테스트 코드도 바꿔야 한다면 이는 경고입니다.
광부들이 카나리아가 새장 바닥으로 떨어지면 바로 갱도에서 도망친 것처럼 이러한 위험을 감지하면 바로 코드의 의존성을 확인해봐야 합니다.
지금까지 아키텍처가 어떻게 우리를 유도하는지에 대해 알아봤습니다. 맨 처음 언급한 대로 정작 클린 아키텍처에 대한 내용은 거의 없었는데요.
그래도 마지막이니만큼 이러한 유도를 통해 아키텍처가 어떤 가치를 이루고자 하는지 정도는 언급하고 끝내겠습니다.
마틴이 말하기를 모든 개발자는 전력을 다합니다. 하지만, 그럼에도 불구하고 어느 순간 기능 개발보다는 엉망이 된 상황에 대처하는 데 더 많은 시간을 쓰는 순간이 오게 됩니다. 결국 그동안의 노력이 보잘 것 없는 것처럼 느껴지죠.
이렇게 되는 것에는 여러가지 요인이 있겠지만 저에게 가장 와닿았던건 어떤 가치를 추구하느냐입니다. 저희는 'software'를 개발하는 사람들입니다. 기능을 구현하고, 제품이 동작하도록 만드는 행위에 관련된 것, 이건 ware(제품)의 영역입니다.
그럼 soft(부드러운)는 뭘까요? 이건 변경과 관련이 있습니다. 제품의 행위를 부드럽게 바꿀 수 있어야 한다는 것이죠. 만약 이게 어려웠다면 저희는 하드웨어 개발자라고 불렸을 겁니다.
둘 다 너무나 중요한 가치입니다. 하지만 저희는 soft의 가치를 마치 수면을 대하듯이 다루는 면이 있습니다.
사람에게 잠은 정말 중요하고, 하루에 8시간씩은 자는게 좋다고 합니다. 이 사실을 모르는 사람은 거의 없습니다. 하지만 평일에는 바쁘기에 8시간 자는 건 환생을 2번 정도는 해야 가능해 보입니다.
그래서 묘수를 두죠. 평일에는 6시간을 자고 주말에 12시간씩 자면 하루 평균이 얼추 8시간이 되니 주말에 밀린 잠을 해결하겠다는 생각을 합니다. 그리고, 이런 생각은 유지보수 쪽에서도 똑같이 합니다. 일단 당장 급한 게 있으니 리팩터링은 나중에 몰아서 하고, 기능 구현부터 하는 것이죠.
정말 그럴듯해 보입니다. 둘 다 안된다는 것만 빼고요. 막상 하루에 12시간을 자려면 못 자는 것처럼 지금까지 미룬 리팩터링을 한 번에 해결하는 건 거의 불가능합니다.
시장의 압박은 절대로 수그라들지 않을 겁이기 때문이죠. 결국 개발 중에 태세를 전환하지 않고, 이전에 작성한 코드로 돌아가는 일은 없고, 다음 기능, 또 다음 기능, 또 다음 기능을 계속해서 만들게 됩니다.
결국 엉망진창이 되고 생산성은 0을 향해 수렴합니다. 어디서부터 잘못됐는지 감도 안오고, 결국 처음부터 전체 시스템을 재설계하는 게 답이라고 생각하는 수준까지 옵니다.
이렇게 최선을 다했지만 프로젝트가 망가졌다면, 자신의 역량을 탓할 게 아니라 내가 걸었던 길이 맞는지 돌아볼 필요가 있습니다. 자신이 중요한 가치를 놓치고 있는 것은 아닌지 말이죠.
만약 이 글을 읽고, 아키텍처에 관심이 생기셨다면, 몇몇 자료를 찾아보며 개인 프로젝트에 적용해보시는 걸 권장드립니다. 여러 가지를 경험해보고 자신만의 아키텍처 스타일을 찾을 수 있을 겁니다. 그리고, 그 과정에서 새로운 가치를 발견하시길 바랍니다.
빨리 가는 유일한 방법은 제대로 가는 것이다.
- 로버트 C. 마틴
클린 아키텍처 - 로버트 C.마틴
http://www.yes24.com/Product/Goods/77283734
만들면서 배우는 클린 아키텍처 - 톰 홈버그
http://www.yes24.com/Product/Goods/105138479
넛지 : 파이널 에디션 - 리처드 탈러, 캐스 선스타인
http://www.yes24.com/Product/Goods/110222823
글 읽으면서 여러번 소름돋았습니다...
되게 재밌게 읽었습니다!!