Eternity's Chit-Chat

aeternum.egloos.com



진화적인 설계-2.소프트웨어 아키텍처와 메타포 3부 Evolutionary Design

청사진으로서의 소프트웨어 아키텍처

소프트웨어 공학의 선구자들은 소프트웨어 개발이라는 미숙아의 양육에 필요한 위한 정신적 모델을 구축하기 위해 상대적으로 성숙한 공학 분야로부터 다양한 용어와 개념을 차용해 왔다. 이 중 소프트웨어 공학에 가장 중요한 메타포를 제공한 분야는 건축학이다. 불확실성과 가정의 늪에서 허우적거려야 하는 소프트웨어 개발자들은 주어진 일정과 예산을 준수하면서도 신의 권위에 도전하듯 하늘을 향해 거대한 마천루를 쌓아가는 건축학에 대해 일종의 콤플렉스와 동경을 동시에 느끼고 있었는지도 모른다.

<그림 2> 소프트웨어 개발에 큰 영향을 미친 건축학의 아키텍처 메타포

건축학으로부터 유래된 용어 중 가장 많은 사람들에 의해 재정의된 용어를 하나 선정하자면 바로 ‘소프트웨어 아키텍처(Software Architecture)’일 것이다. 다양한 정의가 존재한다는 것은 역설적으로 용어를 사용하는 사람들 사이에 공감대가 거의 형성되지 못하고 있다는 이야기와 같다. 소프트웨어 아키텍처에 대한 수 많은 정의 중에서 비교적 널리 알려진 것은 Len Bass, Paul Clements, Rick Kazman의 것이다.

프로그램이나 컴퓨팅 시스템의 소프트웨어 아키텍처는 소프트웨어 구성요소와 그들이 지니고 있는 특성 중에 외부에 드러나는 특성, 그리고 구성요소들의 관계를 표현하는 시스템의 구조나 구조체를 말한다.

- Paul Clements, 소프트웨어 아키텍처 이론과 실제

간단한 정의를 통해 소프트웨어 아키텍처의 실체를 파악하는 것은 사실상 불가능하다. 따라서 소프트웨어 아키텍처란 무엇인가에 대한 격한 논쟁의 소용돌이에 휘말리는 것 보다는 소프트웨어 아키텍처라는 말에서 풍겨지는 은은한 향기와 뉘앙스를 음미하는 것이 올바른 길이라고 생각한다.

소프트웨어 아키텍처를 설명하는 많은 자료들을 찾아 보면 공통적으로 다음과 같은 특징을 언급하고 있음을 알 수 있다.
 

  • 소프트웨어 아키텍처는 상위 수준의 설계이며 시스템을 부분으로 분할한 것이다.

  • 소프트웨어 아키텍처는 생명주기 초기의 설계 결정사항을 반영하며 상세 설계, 구현, 통합, 테스트 작업의 기반을 마련한다.

  • 소프트웨어 아키텍처는 변경이 어려우며 변경 시 큰 비용이 수반된다.

  •  소프트웨어 아키텍처는 모든 이해관계자들이 동의하고 받아들여야 하는 공통적인 비전으로 모든 이해관계자들이 이해할 수 있도록 공유되어야 하며 의사소통의 수단으로 사용되어야 한다.

  • 소프트웨어 아키텍처는 주로 기능적 요구사항 보다는 비기능적 요구사항(예를 들면 품질)에 영향을 받는다.

  • 소프트웨어 아키텍처는 한 가지 방식으로만 표현할 수 없으며 다양한 이해관계자의 요구사항을 수용할 수 있도록 (적어도 정적인 구조와 동적인 구조를 포함하는) 다수의 아키텍처 뷰(view)를 사용해서 표현한다.

  • 소프트웨어 아키텍처는 조직 구조로부터 영향을 받기도 하고 조직 구조에 영향을 미치기도 한다.

  • 최고(the best)의 소프트웨어 아키텍처가 아니라 우수한(the good) 소프트웨어 아키텍처를 얻기 위해 노력해야 한다. 모든 요구사항을 만족시키려 하지 말고 우선순위 수립 후 이를 트레이드오프 해야 한다.

위에 열거한 내용으로부터 소프트웨어 아키텍처의 세 가지 중요한 용도를 알 수 있다. 소프트웨어 아키텍처는 시스템 전반에 대한 설계 계획서(Design Plan)이며, 복잡도를 제어하기 위한 추상화(Abstraction)일 뿐만 아니라, 이해당사자들의 공통 비전(Vision)인 동시에 의사소통 수단(Vehicle for Communication)이다.프트웨어 아키텍처는 소프트웨어 개발을 위한 청사진을 제공한다. 소프트웨어 아키텍처는 설계 계획서(Design Plan)와 같다. 소프트웨어를 구성하는 요소의 종류와 요소 간의 관계, 요소 간의 상호작용은 설계 계획서로서 소프트웨어 아키텍처가 갖춰야 하는 기본적인 항목들이다. 이후의 상세 설계, 구현, 통합, 테스트와 같은 일련의 작업들은 소프트웨어 아키텍처라는 거대한 틀과 어그러짐 없도록 수행되어야 한다. 설계, 구현 등의 세부적인 작업이 소프트웨어 아키텍처를 기반으로 이루어지기 때문에 프로젝트 중, 후반에 소프트웨어 아키텍처를 변경하기가 매우 어렵다. 소프트웨어 아키텍처는 소프트웨어의 구조뿐만 아니라 개발 조직의 구조에도 영향을 미치며 여러 가지 품질 속성을 협의하고 정의할 수 있는 기반을 제공한다.

소프트웨어 아키텍처의 중요한 측면은 세부적인 사항에 대한 이해 없이도 시스템을 이해할 수 있는 추상화(Abstraction)를 제공한다는 점이다. 추상화는 복잡성을 해결하기 위한 핵심 도구다. 따라서 아키텍트는 세부적인 복잡성에 압도되지 않으면서도 시스템의 전반적인 구조와 상호작용을 효과적으로 서술할 수 있을 정도로 적절한 큰 규모의(coarse-grained) 요소들을 사용하여 소프트웨어 아키텍처를 표현해야 한다. 추상화의 이점은 그것이 재사용성을 촉진시킨다는 점이다. 프로젝트 후반의 코드 레벨 재사용보다 프로젝트 초기에 요구사항이 유사한 시스템 간에 아키텍처 또는 아키텍처 개발 경험을 재사용하는 것이 더 효과적이다. 추상화가 직관적이고 이해하기 용이할수록 복잡성은 감소하고 재사용성은 증가한다.

이해관계자들은 자신에게 중요한 요구사항을 기준으로 아키텍처를 바라본다. 아키텍트는 다양한 이해관계자들의 요구사항을 모두 취합한 후 요구사항의 우선순위를 협의하고 모든 이해관계자들이 납득할 수 있는 최적의 아키텍처를 설계해야 한다. 아키텍처는 이처럼 다양한 관심사항을 지닌 사람들이 서로 의논하고 토의해 결론을 도출할 수 있는 컨텍스트를 제공하므로 이를 의사소통의 수단(Vehicle for Communication)으로 사용할 수 있다. 다양한 이해관계자들의 관점은 각각의 아키텍처 뷰(View)로 표현되며 이러한 여러 뷰가 모여 완전한 하나의 아키텍처를 구성한다. 따라서 소프트웨어 아키텍처는 여러 이해당사자들의 시스템을 바라보는 관점의 집합인 동시에 모든 이해관계자들이 동의하고 받아들여야 하는 공통적인 비전(Vision)이라고 할 수 있다.

그러나 불행하게도 위와 같은 정형화된 정의만으로는 소프트웨어 아키텍처의 본질을 파악하고 이해하기는 쉽지 않다. 아키텍처가 단순한 설계가 아닌 고차원의 무엇이라는 관점이 우리의 사고 반경을 학문적인 영역 안으로 제한하는 것은 아닌지 의심스러울 정도다. 아키텍처는 이론이 아닌 실무다. 아키텍처는 단순한 그림이 아닌 실제 소프트웨어의 구조다.

소프트웨어 아키텍처에 대한 만족스러운 정의를 찾지 못하던 도중 Martin Fowler의 또 다른 아티클에서 Ralph Johnson이 아키텍처에 관해 메일링 리스트에 올린 글에 대해 알게 되었다. 개인적인 생각으로는 대다수의 실무 개발자 입장에서 가장 합리적이고 실용적이라고 느낄 수 있는 정의가 바로 Ralph Johnson의 것이 아닐까 생각한다.

Ralph Johnson이 Extreme Programming 메일링 리스트에 올린 글을 읽고 나서야 [아키텍처에 대해] 이해하게 되었다. 그의 글이 워낙 훌륭하기 때문에 여기에 전문을 인용하고자 한다.
처음의 포스트는 다음과 같다.

IEEE의 정의를 해석한 RUP에서는 아키텍처를 “자체적인 환경 내에서 시스템의 최상위 레벨 개념. (특정 시점에 있어) 소프트웨어 시스템의 아키텍처란 인터페이스를 통해 상호작용하는 중요한 컴포넌트의 조직 또는 구조이며, 컴포넌트들은 연속적으로 더 작은 컴포넌트와 인터페이스를 조합하여 구성된다.”라고 정의한다.

이에 대한 Ralph Johnson의 답변은 다음과 같다.

나는 IEEE 표준에 대한 검토자였으며, 명백하게 [아키텍처에 대한] IEEE의 정의가 완전히 잘못된 것이라고 주장했지만 허사였다. 시스템의 최상위 레벨이라는 것은 존재하지 않는다. 고객은 개발자와는 다른 개념을 가진다. 고객은 중요한 컴포넌트의 구조에는 아예 관심이 없다. 따라서, 아마도 아키텍처는 개발자들이 시스템에 대해 가지고 있는 최상위 레벨의 개념일 것이다. 국소적인 부분에 대해서만 이해하는 개발자들은 잠시 접어두기로 하자. 아키텍처는 숙련된 개발자가 바라보는 최상위 레벨 개념이다. 무엇이 컴포넌트를 중요하게 만드는가? 숙련된 개발자가 중요하다고 이야기하기 때문에 중요한 것이다.
따라서 [아키텍처에 대한] 좀 더 나은 정의는 다음과 같다. "대부분의 성공적인 소프트웨어 프로젝트에서 프로젝트에 종사하는 숙련 개발자들은 시스템 설계에 대한 이해를 공유하고 있다. 이 공유된 이해를 ‘아키텍처’라고 부른다. 여기에는 시스템이 컴포넌트로 분할되는 방법, 컴포넌트가 인터페이스를 통해 상호작용하는 방법이 포함된다. 컴포넌트들은 일반적으로 더 작은 컴포넌트로 구성되지만, 아키텍처는 오직 모든 개발자들이 이해하는 컴포넌트와 인터페이스만을 포함한다.”
이 정의가 보다 훌륭하다고 할 수 있는데, 아키텍처가 사회적 산물이라는 점을 명확하게 하기 때문이다(물론, 소프트웨어 역시 사회적 산물이기는 하지만, 상대적으로 아키텍처가 좀 더 사회적이라고 할 수 있다). 아키텍처는 그룹이 소프트웨어의 어떤 부분을 중요하다고 생각하는 지에 달려있다.
“아키텍처란 프로젝트 초기에 내려져야 하는 설계 결정사항”이라는 다른 스타일의 아키텍처 정의가 존재한다. 나는 이 정의 역시 반대하는데 아키텍처란 프로젝트 초기에 올바르게 결정하기를 바라는 사항이 맞기는 하지만 그렇다고 해서 반드시 다른 어떤 것보다 더 올바르게 결정해야 하는 것은 아니라고 생각하기 때문이다.
어쨌든, 이 두 번째 정의에 의하면 프로그램 언어는 대부분의 프로젝트에서 아키텍처에 속할 것이다. 첫 번째 정의에 의하면 그렇지 않다.
어떤 부분이 아키텍처에 속하는가의 여부는 전적으로 개발자들이 그 부분이 중요하다고 생각하는 지 여부에 달려있다. “엔터프라이즈 애플리케이션”을 개발하는 사람들은 영속성이 중요하다고 생각한다. 이 경우 아키텍처를 그리기 시작할 때, 3개의 레이어를 가지고 시작한다. “우리는 데이터베이스로 Oracle을 사용하고 객체를 데이터베이스에 맵핑하기 위해 자체적인 퍼시스턴스 레이어를 가지게 될 것입니다.” 그러나 의료용 영산진단장치(medical imaging) 분야의 애플리케이션이라면 Oracle을 사용하더라도 이를 아키텍처의 일부로 간주하지는 않을 것이다. 이 분야에서 대부분의 복잡성은 이미지를 분석하는 데에서 기인하는 것이지 이를 저장하는 것과 관련된 것은 아니다. 이미지를 조회하고 저장하는 작업은 애플리케이션의 매우 작은 부분이며 대부분의 개발자는 이를 무시한다.
따라서 이런 특성으로 인해 사람들에게 아키텍처를 서술하는 방법을 설명하기란 어렵다. “중요한 것을 이야기하라.” 아키텍처는 중요한 것에 대한 것이다. 그것이 무엇이건 말이다.

- Martin Fowler, Who Needs An Architect?

지금까지 살펴본 소프트웨어 아키텍처에 대한 다양한 관점을 종합해 보면 소프트웨어 아키텍처의 중요한 특징을 알 수 있다. 소프트웨어 아키텍처란 숙련된 개발자들이 동의하는 중요한 어떤 것이며 모든 이해관계자들이 공유해야 하는 지식으로 프로젝트 초기의 설계 결정을 의미하기 때문에 상대적으로 변경이 어렵다.


덧글

  • 밀리네스 2011/08/16 09:46 #

    Ralph 의 정의가 참 맘에 들기는하지만, 고객에게 말하기는 좀 그렇군요. ^^
  • 이터너티 2011/08/16 22:34 #

    Ralph Johnson의 정의가 너무 현실적이라서 미사여구가 필요한 상황에는 부적합할지 몰라도 제가 보기에는 아키텍처에 관한 가장 실용적이고도 정곡을 찌르는 정의가 아닐까 하는 생각에 소개해 봤습니다.
    그리고 고객과의 커뮤니케이션 대상은 시스템에 대한 '아키텍처'여야지 '아키텍처라는 용어의 정의'가 되어서는 안되겠지요.
    방문 감사드립니다. ^^
※ 로그인 사용자만 덧글을 남길 수 있습니다.