이 연재글은 Clean Architecture(클린아키텍처)의 1번째 글입니다.

저자소개

로버트C 마틴

“밥 아저씨(Uncle Bob)”로 불리기도 한다. 1970년부터 프로그래머로 활동했다. 전 세계 콘퍼런스에서 호평받는 연사이며, 《클린 코드》, 《UML 실전에서는 이것만 쓴다》, 《클린 코더》, 《클린 소프트웨어》의 저자다. ‘엉클 밥 컨설팅(Uncle Bob Consulting, LLC)’의 창립자이자 ‘클린 코더(Clean Coders, LLC)’의 공동 창립자다. 또한 ‘애자일 얼라이언스(Agile Alliance)’의 초대 회장과 《The C++ Report》의 편집장을 지냈으며 ‘오브젝트 멘토(Object Mentor)’의 공동 창립자이자 리더다.

개요

클린아키텍처에서는 소프트웨어 아키텍트가 해내야 할 일과 그 일을 해내기 위한 규율과 실천법을 설명하고 있다. 기능, 구성요소 분리, 데이터 관리를 위한 소프트웨어 설계 핵심 원칙을 배우고, 프로그래밍 패러다임이 규율을 강제하기 위해 개발자의 자유를 어떻게 제약하는지 알아본다. 또한, 웹, 데이터베이스, 리치 클라이언트, 콘솔, 임베디드 애플리케이션의 고수준 구조를 최적화하고, 아키텍처가 잘못되는 이유와 잘못된 결과가 나오지 않게 예방하거나 고치는 방법에 대하여 설명한다.

변함없는 프로그래밍 규칙

새로운 언어, 새로운 프레임워크의 등장에도 불구 앨런 튜링이 최초로 기계어 코드를 작성한 1946년 이후 규칙은 달라지지 않았다. 언어가 발전하고 도구가 환상적으로 좋아졌지만 코드는 여전히 순차, 분기, 반복 등의 집합체일 뿐이다. 소프트웨어 아키텍처의 규칙이란 프로그램의 구성요소를 정렬하고 조립하는 방법에 관한 규칙이다. 그리고 이 구성요소가 보편적이며 변하지 않았으므로, 이들을 정렬하는 규칙 역시도 보편적이며 변한 게 없다. 이 책은 세월이 흘러도 변치않는 규칙에 관한 것이다.

1-1장. 설계와 아키텍처

프로그램을 동작하게 만드는 데는 엄청난 수준의 지식과 기술을 필요로하지 않는다. 프로그램을 동작하게 만드는 건 그리 어려운 일이 아니기 때문이다. 그러나 프로그램을 제대로 만들어내는것은 전혀 다르다. 소프트웨어를 제대로 만들려면 적정 수준의 지식과 기술을 겸비하고 사고력과 통찰력을 갖춰야 한다. 하지만 대다수의 프로그래머는 시간을 들여 이러한 능력을 개발하지 않는다.

소프트웨어를 제대로 만들면…

  • 소수의 프로그래머 만으로 프로그램이 지속적으로 동작하도록 만들 수 있다.
  • 거대한 요구사항 문서와 이슈가 수없이 등록된 이슈 추적 시스템이 필요없다.
  • 아주 적은 인력만으로 새로운 기술을 추가하거나 유지보수 할수 있고, 변경은 단순해지고 빠르게 반영할 수 있다.
  • 최소한의 노력으로 기능과 유연성을 최대화 할 수 있다. 즉 작은 사무실에서 휴일없이 일해야 하는 프로그래머가 없어도 된다.

내가 만든 시스템 되돌아 보기

  • 서로 강하게 연관되어있고 복잡하게 결합되어서 아주 사소한 변경에도 오래걸릴 뿐만 아니라 수정에도 큰 위험을 감수해야 하지는 않는가?
  • 잘못된 코드와 끔찍한 설계로 인해 방해를 받지는 않는가?
  • 시스템의 설계가 팀의 사기를 떨어뜨리거나 고객의 신뢰를 잃고 관리자의 인내심을 시험하는 부정적인 영향을 끼치지 않았나?
  • 형편없는 소프트웨어 구조로 인해 실패한 적은 없나? 프로그래밍 지옥을 경험하지 않았나?

대부분의 개발자들은 훌륭한 소프트웨어 설계를 바탕으로 작업하면서 즐거움을 느끼기보다는 형편없는 소프트웨어 설계와 맞서 싸우는 일을 훨씬 더 자주 맞닥뜨리게 된다.

소프트웨어 아키텍처의 목표는 필요한 시스템을 만들고 유지 보수하는데 투입되는 인력을 최소화하는데 있다.

설계와 아키텍처란?

아키텍처는 저수준의 세부사항과는 분리된 ‘고수준의 무언가’를 가리킬 때가 많다. 그에반해 설계는 저수준의 세부 구조 또는 결정사항을 의미할 때가 많다.

아키텍트 입장에서 저수준의 세부사항과 고수준의 구조를 분리해서 생각하는 것은 무의미하다. 두 가지 사항은 모두 개별로는 존재할 수 없고 실제로 구분 짓는 경계도 뚜렷하지 않기 때문이다. 다만 고수준에서 저수준으로 향하는 의사결정의 연속성만이 있을 뿐이다.

설계 품질을 재는 척도

고객의 요구를 만족시키는데 드는 비용이 낮고 시스템의 수명이 다할 때까지 낮게 유지할 수 있으면 좋은 설계이다. 하지만 새로운 기능을 출시할 때마다 비용이 증가한다면 나쁜 설계다.

사례1

지속적으로 엔지니어수가 늘어나는 회사는 겉으로는 굉장히 성공을 이룬 것처럼 보인다. 하지만 깊게 들여다 봤을 때 동일한 기간의 생산성이 낮아지고 출시할 때마다 발생하는 개인 당 비용이 점점 늘어나 충원으로 이어지는 것이라면 회사는 성장을 멈췄거나 완전히 망하는 길고 가고 있다는 신호이다.

엉망진창이 되어가는 신호

개발자의 생산성은 100%에서 시작했지만 새로운 제품을 출시할 때마다 생산성이 하락한다. 네 번째 출시에 다다르면 확실히 생산성은 거의 바닥을 치고 결국에는 0으로 수렴한다. 개발자 입장에서 이러한 현상은 지독한 절망감을 안겨주는데 모두가 열심히 일하고 있기 때문이다. 전력을 기울이지 않는 개발자는 없다.

개발자는 노력을 하고 잔업을 하고 헌신함에도 불구 더 이상 진척이 없는 상황에 처하게 된다. 개발자의 노력은 기능 개발보다는 엉망이 된 상황에 대처하는데 소모되기 시작한다. 심지어 사소한 기능을 추가하는 일도 그저 엉망이 된 코드를 이곳에서 저곳으로 다시 다음 곳으로 이동하는 반복 작업으로 변질된다. 결국 개발자들이 쏟은 노력의 가치는 결국 보잘것없는 것이 된다.

경영자의 딜레마

개발이 늦어지니 점점 더 많은 인력을 투입하게 되며 월별 인건비가 계속 상승하는 것을 경험할 수 있다. 더구나 마지막 출시에는 많은 돈을 들이고도 얻은 게 거의 없는 상태가 된다.

무엇이 잘못되었는가?

생산성이 믿을 수없이 낮아진 원인은 무엇인가. 개발자에게 고함치는 일 외에 경영자는 무슨 일을 할 수 있을 것인가?

토끼와 거북이 이야기

교훈

– 느려도 꾸준하면 이긴다.
– 발 빠른 자가 경주에 이기는 것도 아니며, 힘센 자가 싸움에서 이기는 것도 아니다. 급할수록 돌아가라

지나친 과신이 가진 어리석음

현대의 개발자도 토끼와 유사한 과신을 드러낸다. 다만 현실의 개발자는 잠을 자지 않고 뼈 빠지게 일한다. 그러나 그들의 뇌는 잠에 취해있다. 훌륭하고 깔끔하게 잘 설계된 코드가 중요하다는 사실을 알고 있는 그 뇌가 잠자고 있다.

개발자가 속는 더 잘못된 거짓말1

“코드는 나중에 정리하면 돼, 당장은 시장에 출시하는 게 먼저야”라는 흔한 거짓말에 속는다. 이렇게 속아 넘어간 개발자는 나중에 코드를 정리하는 경우는 한 번도 없는데, 왜냐하면 시장의 압박은 절대로 수 그러 들지 않기 때문이다.(말 그대로 일이 많다) 경쟁자보다 앞서 가려면 가능한 한 빠르게 달려야 하기 때문이다.

토끼가 자신의 빠르기를 과신한 것처럼, 개발자도 생산성을 유지할 수 있다고 능력을 과신한다. 하지만 좋지 않은 코드가 서서히 쌓이면 개발자 생산성은 점차 낮아지고, 코드가 엉망이 되는 추세는 절때 멈추거나 수그러들지 않는다.

개발자가 속는 더 잘못된 거짓말2

개발자가 속는 더 잘못된 거짓말은 지저분한 코드를 작성하면 단기간에는 빠르게 갈 수 있고, 장기적으로 볼 때만 생산성이 낮아진다는 견해다. 엉망으로 만들면 깔끔하게 유지할 때보다 항상 더 느리다.

제이스 고먼의 테스트

일주일간의 테스트. 간단한 프로그램을 작성하고 완성하는데 걸리는 시간을 측정

  • TDD를 적용하지 않은 채 1,3,5일에 작성
  • TDD를 적용한 채 2,4,6일에 작성
  • 날이 갈수록 TDD를 적용한 날이 적용 안 한 날 보다 10%빠르게 작업이 완성이 되었다.
  • 더구나 TDD를 적용하고 가장 느렸던 날이 TDD를 적용하지 않고 가장 빨랐던 날보다도 빨랐다

결론

빨리 가는 유일한 방법은 제대로 가는 것이다.

생산성이 감소되고 비용이 증가하는 현상을 되돌릴 수 있는 유일한 방법은 개발자로 하여금 토끼처럼 과신하려는 믿음을 버리고, 만들어낸 엉망진창인 코드를 개발자가 책임지도록 하는 것뿐이다.

개발자의 잘못된 생각 – 처음부터 다시 시작하여 전체 시스템을 재 설계하는 것이 해답이다.

이것조차 토끼의 말과 다름없다. 엉망으로 내몰았던 그 과신이 경주를 다시 시작한다면 더 나은 코드를 만들 수 있다고 말하는 것이다. 현실은 장밋빛과는 거리가 멀다. 자신을 과신한다면 재설계하더라도 원래의 프로젝트와 똑같이 엉망으로 내몰릴 것이다.

개발조직이 할수 있는 최고의 선택지

조직에 스며든 과신을 인지하여 방지하고 소프트웨어 아키텍처의 품질을 심각하게 고민하기 시작하는 것이다. 심각하게 고민하려면 좋은 소프트웨어 아키텍처가 무엇인지 이해해야 한다.

1-2장. 두가지 가치에 대한 이야기

소프트웨어 시스템은 이해관계자에게 행위와 아키텍처라는 서로 다른 두 가지 가치를 제공한다.

행위

프로그래머는 이해관계자가 수익을 창출하거나 비용을 절약할 수 있도록 하기 위해 기능 명세서나 요구사항 문서를 구체화할 수 있도록 돕는다. 그리고 이러한 요구사항을 만족하도록 코드를 작성한다. 요구사항에 위배되면 프로그래머는 디버거를 열고 문제를 고친다. 많은 프로그래머가 이러한 활동이 자신이 해야 할 일의 전부라고 생각한다. 요구사항을 기계에 구현하고 버그를 수정하는 일이 자신의 직업이라고 믿는다.

아키텍처

소프트웨어는 부드러운 제품이라는 단어의 합성어이다. 소프트웨어는 부드러움을 지니도록 만들어졌고, 소프트웨어를 만든 이유는 기계의 행위를 쉽게 변경할 수 있도록 하기 위해서다. 소프트웨어가 가진 본연의 목적을 추구하려면, 부드러워야 한다. 다시 말해 변경하기 쉬어야 한다. 이해관계자가 기능에 대한 생각을 바꾸면 이러한 변경사항을 간단하고 쉽게 적용할 수 있어야 한다.

이해관계자는 비슷한 일련의 변경사항을 제시할 뿐이지만, 개발자 입장에서는 복잡도가 지속적으로 증가하는 퍼즐판 위에서 계속해서 퍼즐을 맞추라는 지시를 하는 것처럼 느껴진다. 따라서 새로운 요청사항이 발생할 때마다 이전의 변경사항을 적용하는 것보다 조금 더 힘들어진다. 아키텍처가 특정 형태를 다른 형태보다 선호하면 할수록 , 새로운 기능을 이 구조에 맞추는 게 더 힘들어진다. 따라서 아키텍처는 형태에 독립적이어야 하고 그럴수록 더 실용적이다.

더 높은 가치

행위인가 아키텍처인가? 둘 중 어느 것의 가치가 더 높은가? 소프트웨어 시스템을 동작하도록 만드는 것이 더 중요한가? 아니면 소프트웨어 시스템을 더 쉽게 변경할 수 있도록 하는 것이 더 중요한가?

완벽하게 동작하지만 수정이 불가능한 프로그램은 요구사항이 변경될 때 동작하지 않게 되고 거의 쓸모없는 프로그램이 된다. 동작은 하지 않지만 변경이 가능한 시스템은 돌아가게 만들고 변경사항이 발생하더라도 여전히 동작하도록 유지보수할 수 있다.

수정이 불가능한 시스템은 존재하지 않지만 변경에 드는 비용이 변경으로 창출되는 비용보다 초과될 경우 수정이 현실적으로 불가능한 상황에 놓이게 된다. 추 후 업무자의 변경 요청에 비용이 너무 커서 적용이 힘들다고 하면 변경이 불가능한 상태까지 시스템을 방치했다며 화를 낼 것이다.

소프트웨어의 가치인 행위는 긴급하지만 매번 높은 중요도를 가지진 않는다. 소프트웨어의 두 번째 가치인 아키텍처는 중요하지만 즉각적인 긴급성을 요하는 경우는 거의 없다.

아이젠하워 미국 대통령이 고안한 중요성과 긴급성에 대한 메트릭스

1. 긴급하고 중요한
2. 긴급하지는 않지만 중요한
3. 긴급하지만 중요하지 않은
4. 긴급하지도 않고 중요하지도 않은

아키텍처, 즉 중요한 일은 이 항목의 가장 높은 두 순위를 차지하는 반면 행위는 첫 번째와 세 번째에 위치한다는 점을 주목하자.

업무관리자와 개발자가 저지르는 가장 큰 실수는 3번째 내용을 첫 번째로 격상하는 것이다. 긴급하지만 중요하지 않은 기능과 진짜 긴급하면서 중요한 기능을 구분하지 못한다. 업무관리자는 보통 아키텍처의 중요성을 평가할 만한 능력을 지니고 있지 않기 때문에 개발자는 딜레마에 빠진다.

아키텍처를 위해 투쟁하라.

효율적인 소프트웨어 개발팀은 뻔뻔함을 무릅쓰고 다른 이해관계자들과 동등하게 논쟁해야 한다. 소프트웨어 개발자는 소프트웨어를 안전하게 보호해야 할 책임이 있으며 또 하나의 이해관계자에 속하므로 이러한 투쟁은 역할이며 책무 중 하나이다.

만약 당신이 소프트웨어 아키텍트라면 이러한 도전은 2배로 중요해진다. 시스템이 제공하는 특성이나 기능보다는 시스템의 구조에 더 중점을 둬야 한다.

아키텍트는 이러한 특성이나 기능을 개발하기 쉽고 간편하게 수정할 수 있으며 확장하기 쉬운 아키텍처를 만들어야 한다. 아키텍처가 후순위가 되면 개발하는 비용이 상승하고 전체 시스템에 변경을 가하는 일이 현실적으로 불가능해진다. 이러한 상황이 발생하도록 용납했다면 소프트 웨어 개발팀이 스스로 옳다고 믿는 가치를 위해 충분히 투쟁하지 않았다는 뜻이다.

연재글 이동
[다음글] Clean architecture 2부 – programming-paradigm