서문
소프트웨어 아키텍처의 규칙이란 프로그램의 구성요소를 정렬하고 조립하는 방법에 관한 규칙이다.
모든 아키텍쳐 규칙은 동일하다.
근 50년간 도구는 발전했지만 컴퓨터 프로그래밍을 이루는 기본 구성요소는 조금도 변하지 않았다.
프로그램을 동작하게 만들기는 그리 어려운 일이 아니다. 하지만 프로그램을 제대로 만드는 일은 전혀 다르다. 소프트웨어를 올바르게 만드는 일은 어렵다. 소프트웨어를 제대로 만들려면 적정 수준의 지식과 기술을 겸비해야 하지만, 대다수 젊은 프로그래머는 이 수준에 도달하지 못했다.
소프트웨어를 제대로 만들게 되면 마법과도 같은 일이 벌어진다. 소수의 프로그래머 만으로 프로그램이 지속적으로 동작하도록 만들 수 있다. 거대한 요구사항 문서와 이슈가 수없이 등록된 이슈 추적 시스템도 필요가 없다.
제대로 된 소프트웨어를 만들면 아주 적은 인력만으로도 새로운 기능을 추가하거나 유지보수할 수 있다. 변경은 단순해지고 빠르게 반영할 수 있다. 결함은 적어지고 잦아든다. 최소한의 노력으로 기능과 유연성을 최대화할 수 있다.
1. 설계와 아키텍처란?
설계와 아키텍처에 어떤 차이가 있는가? 사실 둘 사이에는 차이가 없다.
아키텍처는 저수준의 세부사항과는 분리된 고수준의 무언가를 가리킬 때 흔히 사용되는 반면, 설계는 저수준의 구조 또는 결정사항 등을 의미할 때가 많다. 하지만 아키텍트가 실제로 하는 일을 살펴보면 이러한 구분은 무의미하다.
저수준의 세부사항과 고수준의 구조는 모두 소프트웨어 전체 설계의 구성요소다. 이 둘은 단절 없이 이어진 직물과 같으며, 이를 통해 대상 시스템의 구조를 정의한다.
소프트웨어 아키텍처의 목표는 필요한 시스템을 만들고 유지보수하는 데 투입되는 인력을 최소화하는 데 있다.
설계 품질을 재는 척도는 고객의 요구를 만족시키는 데 드는 비용을 재는 척도와 다름없다. 이 비용이 낮을 뿐만 아니라 시스템이 수명이 다할 때까지 낮게 유지할 수 있다면 좋은 설계라고 말할 수 있다. 새로운 기능을 출시할 때마다 비용이 증가한다면 나쁜 설계다.
시스템을 급하게 만들거나, 결과물의 총량을 순전히 프로그래머 수만으로 결정하거나, 코드와 설계의 구조를 깔끔하게 만들려는 생각을 전혀 하지 않으면, 파국으로 치닫는 비용 곡선에 올라타게 된다.
개발자는 ‘코드는 나중에 정리하면 돼. 당장은 시장에 출시하는 게 먼저야!’ 라는 흔해 빠진 거짓말에 속는다. 이렇게 속아 넘어간 개발자라면 나중에 코드를 정리하는 경우는 한 번도 없는데, 시장의 압박은 절대로 수그러들지 않기 때문이다. ‘시장 출시가 먼저’라는 생각을 하는 이유는 바로 뒤에 여러 무리의 경쟁자가 뒤쫓고 있고, 경쟁자보다 앞서 가려면 가능한 한 빠르게 달려야 하기 때문이다.
결국 개발자는 절대 태세를 전환하지 않는다. 이전에 작성한 코드로 돌아가 정리하는 일은 일어나지 않는데, 바로 다음에 만들어야 할 새로운 기능이 기다리고 있고, 다음 기능, 또 다음 기능이 계속 기다리고 있기 때문이다.
토끼가 자신의 빠르기를 과신한 것과 마찬가지로, 개발자도 생산성을 유지할 수 있다고 자신의 능력을 과신한다. 하지만 엉망진창인 코드가 서서히 쌓이면 개발자의 생산성은 차츰 낮아지고, 코드가 엉망이 되는 추세는 절대 멈추거나 수그러들지 않는다.
개발자가 속는 더 잘못된 거짓말은 ‘지저분한 코드를 작성하면 단기간에는 빠르게 갈 수 있고, 장기적으로 볼 때만 생산성이 낮아진다’는 견해다. 엉망으로 만들면 깔끔하게 유지할 때보다 항상 더 느리다. 어느 시간척도에서도.
빨리 가는 유일한 방법은 제대로 가는 것이다.
개발자는 처음부터 다시 시작하여 전체 시스템을 재설계하는 것이 해답이라고 생각할지도 모른다. 하지만 이 생각 또한 토끼의 말과 다름없다. 엉망으로 내몰았던 바로 그 과신이 경주를 다시 시작한다면 더 나은 코드를 만들 수 있다고 말하고 있는 것이다. 현실은 장밋빛 기대와는 거리가 멀다.
자신을 과신한다면 재설계하더라도 원래의 프로젝트와 똑같이 엉망으로 내몰린다.
결론
개발 조직이 할 수 있는 최고의 선택지는 조직에 스며든 과신을 인지하여 방지하고, 소프트웨어 아키텍처의 품질을 심각하게 고민하기 시작하는 것이다.
소프트웨어 아키텍처를 심각하게 고려할 수 있으려면 좋은 소프트웨어 아키텍처가 무엇인지 이해해야 한다. 비용은 최소화하고 생산성은 최대화할 수 있는 설계와 아키텍처를 가진 시스템을 만들려면, 이러한 결과로 이끌어 줄 시스템 아키텍처가 지닌 속성을 알고 있어야 한다.
2. 두가지 가치에 대한 이야기
모든 소프트웨어 시스템은 이해관계자에게 서로 다른 두 가지 가치를 제공하는데, 행위와 구조이다. 소프트웨어 개발자는 두 가치 모두 반드시 높게 유지해야 하는 책임을 진다.
행위
프로그래머를 고용하는 이유는 이해관계자를 위해 기계가 수익을 창출하거나 비용을 절약하도록 만들기 위해서다.
이들은 요구사항을 기계에 구현하고 버그를 수정하는 일이 자신의 직업이라고 믿는다. 슬프지만 그들은 틀렸다.
아키텍처
소프트웨어는 ‘부드러움을 지니도록’ 만들어졌다. 소프트웨어를 만든 이유는 기계의 행위를 쉽게 변경할 수 있도록 하기 위해서다.
이해관계자가 기능에 대한 생각을 바꾸면, 이러한 변경사항을 간단하고 쉽게 적용할 수 있어야 한다. 이러한 변경사항을 적용하는 데 드는 어려움은 변경되는 법위에 비례해야하며, 변경사항의 형태와는 관련이 없어야 한다.
소프트웨어 개발 비용의 증가를 결정짓는 주된 요인은 바로 이 변경사항의 범위와 형태의 차이에 있다. 바로 이 때문에 개발 비용은 요청된 변경사항의 크기에 비례한다. 또한 개발 첫 해가 다음 해보다 비용이 덜 들고, 다음 해에는 그 다음 해보다 비용이 적게 드는 이유도 이 때문이다.
이해관계자는 범위가 비슷한 일련의 변경사항을 제시하지만, 개발자 입장에서는 복잡도가 지속적으로 증가하는 퍼즐 판 위에서 이해관계자가 계속해서 퍼즐 조각을 맞추라는 지시를 하는 것처럼 느껴진다.
여기에서 ‘형태’라는 단어를 색다른 방식으로 사용하지만, 이 메타포는 적절하다. 흔히 소프트웨어 개발자는 사각형 마개를 둥그란 구멍에 밀어 넣도록 강요받는 느낌을 받기 때문이다.
문제는 당연히 아키텍처이다. 아키텍처가 특정 형태를 다른 형태보다 선호하면 할수록, 새로운 기능을 이 구조에 맞추는 게 더 힘들어진다. 따라서 아키텍처는 형태에 독립적이어야 하고, 그럴수록 더 실용적이다.
더 높은 가치
기능인가 아키텍처인가? 소프트웨어 시스템이 동작하도록 만드는 것이 중요한가? 아니면 소프트웨어 시스템을 더 쉽게 변경할 수 있도록 하는 것이 중요한가?
- 완벽하게 동작하지만 수정이 불가능한 프로그램을 내게 준다면, 이 프로그램은 요구사항이 변경될 때 동작하지 않게된다. 이러한 프로그램은 거의 쓸모가 없다.
- 동작은 하지 않지만 변경이 쉬운 프로그램을 내게 준다면, 나는 프로그램을 돌아가도록 만들 수 있고, 변경사항이 발생하더라도 여전히 동작하도록 유지보수할 수 있다. 따라서 이러한 프로그램은 앞으로도 계속 유용한채로 남는다.
아이젠하워 매트릭스
내겐 두 가지 유형의 문제가 있습니다. 하나는 긴급하며, 다른 하나는 중요합니다. 긴급한 문제는 중요하지 않으며, 중요한 문제는 절대 긴급하지 않습니다.
소프트웨어의 첫 번째 가치인 행위는 긴급하지만 매번 높은 중요도를 가지는 것은 아니다.
소프트웨어의 두 번째 가치인 아키텍처는 중요하지만 즉각적인 긴급성을 필요로 하는 경우는 절대 없다.
개발자가 흔하게 저지르는 실수는 긴급하지만 중요하지 않은 기능과 진짜로 긴급하면서 중요한 기능을 구분하지 못한다. 이러한 실패로 인해 시스템에서 중요도가 높은 아키텍처를 무시한 채 중요도가 떨어지는 기능을 선택하게 된다.
때문에 개발자는 딜레마에 빠진다. 소프트웨어 개발자를 고용하는 이유는 바로 이 딜레마를 해결하기 위해서다. 따라서 기능의 긴급성이 아닌 아키텍처의 중요성을 설득하는 일은 소프트웨어 개발팀이 마땅히 책임져야 한다.
아키텍처를 위해 투쟁하라
이러한 책임을 다하려면 싸움판에 뛰어들어야 하며, 더 정확히는 투쟁해야한다.
당신은 소프트웨어를 안전하게 보호해야 할 책임이 있으므로 당신 역시 이해관계가 있다. 이것이 당신을 고용한 중요한 이유 중 하나이기도 하다.
아키텍처가 후순위가 되면 시스템을 개발하는 비용이 더 많이 들고, 일부 또는 전체 시스템에 변경을 가하는 일이 현실적으로 불가능해진다. 이러한 상황이 발생하도록 용납했다면, 이는 결국 소프트웨어 개발팀이 스스로 옳다고 믿는 가치를 위해 충분히 투쟁하지 않았다는 뜻이다.
Loading Comments...