|
이
단원은 아키텍처의 정의 단계로 들어가기 전에 먼저, 소프트웨어
시스템의 성공적인 구축에 필요한 요소, 소프트웨어
아키텍처에 대해 이야기하고 있습니다
소프트웨어 아키텍처란 무엇일까요?
Len Bass저자의 Software Architecture in practice 에서는 이렇게 정의 하고 있습니다.
‘소프트웨어 아키텍처는 소프트웨어 요소와 이들 요소의 외부속성, 이들 사이의 관계를 구성하는 시스템의 구조이다’라고 말입니다.
이 외에도 ‘소프트웨어 아키텍처는 시스템의 전반적인 구조이다’라는 정의와
‘시스템의 컴포넌트와 이들 사이의 관계 그리고, 이들의 설계 및 변경에 대한 원리와 가이드라인을 정의한 구조이다’ 라는 정의가 있습니다.
위의 정의를 통하여 CBD,WHAT&HOW 책에서는 다음과 같은 사항들을 정리하고 있습니다.
첫 번째로 소프트웨어 아키텍처는 소프트웨어 시스템의 구조를 결정한다 는 점.
두 번째로 소프트웨어 아키텍처는 여러 소프트웨어 요소 또는 컴포넌트가 구성을 이루고 있다는 점.
세 번째로 요소 또는 컴포넌트는 인터페이스를 가지고 있고, 다른 소프트웨어 요소나 컴포넌트와 인터페이스를 통해 서로 커뮤니케이션을 한다는 점.
마지막으로 요소 ,컴포넌트를 설계하고 변경하는 것에 대한 원리와 가이드라인을 제공한다는 점. 입니다.
이로 미루어 볼 때 소프트웨어 시스템의 구조는 컴포넌트들과 컴포넌트 사이의 인터페이스 관계를 보여주며,
우리는 이것을 소프트웨어 아키텍처라고 정의하는 것을 알 수 있습니다.
다음으로 소프트웨어 아키텍처와 다른 작업 사이의 관계 입니다.
이 그림은 제목 그대로 아키텍처와 요구 파악, 하드웨어 아키텍처 설계 작업, 상세 설계 등의 다른 작업 사이의 관계를 그려놓은 것입니다.
소프트웨어 아키텍처 설계 작업은 요구 파악 작업에서 이끌어 낸 요구사항과 품질 속성과
하드웨어 아키텍처 설계 작업에서 정의한 하드웨어 아키텍처를 입력 받아 소프트웨어 아키텍처를 정의 합니다.
그리고 이 정의한 결과를 상세 설계, 구현, 통합 및 테스트 작업으로 전달합니다.
또한 소프트웨어 아키텍처 설계 작업에서 변경된 요구사항을 요구 파악 작업에 넘겨줌으로써 요구사항을 변경할 수 있으며,
하드웨어 아키텍처에 관한 변경도 같은 작업을 진행함으로써 하드웨어 아키텍처를 변경 할 수 있게 합니다.
변경된 정보들은 다시 상세 설계,구현 등의 작업으로 전달하여 반영하도록 합니다.
각각의 작업은 서로에게 영향을 주고 받으며 협력하여 프로젝트를 진행합니다.
프로젝트 진행 시, 소프트웨어 아키텍처 설계 작업에서는 소프트웨어 시스템을 설계하고 구현하는데 필요한 원리와 가이드 라인을 제공해야 합니다.
이처럼 소프트웨어 아키텍처는 소프트웨어 시스템 구축의 중심에 있습니다.
그렇다면 왜 소프트웨어 아키텍처는 시스템 구축의 중추 역할을 하는 것일까요?
그에 대한 설명은 Software Architecture in practice 에서 설명하고 있는 ‘소프트웨어 아키텍처의 중요성 ’을 보면 알 수 있을 것입니다.
이 책에서는 아키텍처의 중요성을 3가지로 설명하고 있습니다.
첫 번째로 이해당사자 사이의 의사 소통입니다.
여기서 이해당사자란 소프트웨어 시스템의 구축에 관여하는 사람들을 지칭하는 말입니다.
고객, 사용자, 개발자, 프로젝트 관리자 등이 모두 이해 대상자에 포함하고 있습니다.
이들은 소프트웨어 시스템에 대하여 서로 다른 과점과 조건들을 요구합니다.
예를 들어 어떠한 사람은 기본적인 기능을 원할 수도 있고, 또 다른 사람은 기본적인 기능과 함께 확장된 기능을 요구 할 수도 있습니다.
이때 소프트웨어 아키텍처를 이해당사자들 사이의 의사 소통 수단으로 이용할 수 있습니다
소프트웨어 아키텍처를 사용하여 서로 다른 관점을 이해 하여 협상하고, 합의를 이끌어내어
의사 소통하는데 기반으로서 사용할 수 있는 공통적인 언어로 시스템 추상화를 표현합니다.
두 번째로 초기 설계 결정 사항 입니다.
소프트웨어 아키텍처는 시스템의 초기 설계 결정 사항을 표현합니다.
아키텍처는 구현에 대한 제약 사항을 정의하며, 개발할 시스템에 대한 구조 뿐만 아니라 개발 조직의 구도도 정의합니다.
이 뿐만 아니라 시스템을 변경해야 할 필요성을 느낄 때 가장 적은 비용과 위험 부담을 갖는 변경 경로를 결정하는 데에도 사용 할 수 있습니다.
마지막으로 소프트웨어 아키텍처는 재사용이 가능합니다.
프로젝트 초기에 재사용 성을 적용할 수 있다면 요구사항을 갖는 시스템에 대하여 더 많은 이점을 얻을 수 있는 것 입니다.
이 경우 코드 뿐만이 아닌, 아키텍처를 결정하는 요구사항, 아키텍처 설계 경험까지 모두 재사용 할 수 있습니다.
4절에서는 비 기능 요구사항과 품질속성에 대해 이야기 하도록 하겠습니다.
여기서 비 기능 요구사항이란 시스템 속성이나 시스템에 의해 제공하는 서비스나 기능에 대한 제약 사항에 대한 정의 입니다.
신뢰도, 반응 시간, 저장소 요구사항 예로 볼 수 있습니다.
여기서 비기능적인 요구사항들 중에서 특별히 소프트웨어 아키텍처에 많은 영향을 미치는 요구사항들이 있습니다.
우리는 이것들을 품질 속성이라고 부릅니다.
품질 속성을 소프트웨어 시스템에 실현하는데 있어 소프트웨어 아키텍처는 중요한 역할을 담당합니다.
하지만 그렇다고 아키텍처 그 자체만으로 품질 속성을 실현 할 수는 없는 노릇입니다.
실현하기 위해서는 설계와 구현,테스트, 배포 등의 소프트웨어 시스템 개발의 전 작업에서 이루어져야 합니다.
Software Architecture in practice 에서는 품질 속성을 크게 3가지로 시스템 품질 속성, 비즈니스 품질속성, 아키텍처 품질 속성으로 분류합니다.
그 중 첫 번째인 시스템 품질 속성은 또 다시 6개의 품질 속성으로 정의합니다.
순서대로 보면 가장 먼저 가용성입니다.
가용성이란 시스템이 필요할 때 작동할 가능성의 정도를 의미합니다.
시스템의 실패는 시스템이 일괄적인 서비스를 제공하지 못할 때 발생합니다.
발생 후에는 사용자가 실패를 알 수 있으며, 이후 부터는 실패의 원인을 제거함으로써 시스템을 복구해야 재가동할 수 있습니다.
이 때 가용성의 정의는
평균 실패 시간
가용성 = ---------------------------------
평균 실패 시간 + 평균 복구 시간
두 번째로 변경 가능성은 시스템을 변경하는데 소요되는 시간과 노력 등의 비용과 관련이 있습니다.
세 번째는 보안으로 적법한 사용자에 대해서는 서비스를 제공하지만 권한이 없는 사용자라면 서비스를 거부하는 시스템의 능력을 측정합니다. 보안에서 고려할 자세한 사항은 사용자가 자신임을 증명하는 속성인 ‘인증’, 어떠한 리소스에 접근하게 할 지를 결정하는 속성인 ‘권한’, 권한이 없는 사용자에게 접근을 허용하지 않는 속성인 ‘기밀성’, 권한이 없는 사용자는 데이터를 변경하지 못하게 하는 속성인 ’무결 성’ 그리고 사용자 자신이 했다는 것을 부인하지 못하게 하는 속성인
‘부인방지’가 있습니다.
네 번째로 테스트 가능성입니다.
테스트 가능성이란 테스트를 통해 소프트웨어가 결함을 가지고 있음을 얼마나 쉽게 증명할 수 있는가 입니다.
다섯 번째, 사용 성 입니다.
사용성은 사용자가 얼마나 손쉽게 원하는 작업을 할 수 있는가에 관련하여 시스템 기능 학습, 효율적인 시스템 활용, 에러 영향의 최소화, 사용자 필요 충족, 신뢰와 만족의 증가를 포함하고 있습니다.
다음으로 비즈니스 품질 속성에는 서비스 개시일이 이미 공식적으로 발표하여 일정을 고정하였다면 개발 일정을 맞추는 일이 중요해지며,
이것은 아키텍처에 영향을 미치게 됩니다.
이러한 속성을 적시 성이라고 합니다.
그리고 아키텍처마다 서로 다른 개발 비용이 발생합니다.
일반적으로 유연성이 높은 아키텍처가 그렇지 않은 아키텍처보다 더 많은 예산을 필요로 합니다
이러한 속성을 비용과 예산이라고 합니다.
시스템 내구 연한 속성은 시스템을 얼마나 오랫동안 사용가능 하는가에 대한 품질 속성이며
목표 시장 속성은 기능 뿐만 아닌 시스템이 실행하는 플랫폼 도 잠재적인 시장의 크기를 결정하는 요소입니다.
첫 공개 일정은 첫 버전에서는 기본적인 기능만을 제공하고 다른 기능들은 이후 버전에서 업그레이드 해간다면 유연성과 확장 성이 이 시스템의 중요 품질 속성일 것입니다.
마지막으로 새로운 시스템과 기존 시스템의 통합 속성에서는 새로운 시스템이 기존 시스템과 통합해야 할 경우, 적절한 통합 메커니즘을 정의하는데 신경을 기울여야 하며, 이것은 아키텍처를 결정하는데 있어 제약사항으로 작용할 수 있습니다.
이제 Software Architecture in practice 에서 분류한 마지막 품질 속성인 아키텍처 품질 속성입니다.
이 속성은 다른 품질 속성 또한 마찬가지이겠지만 특히 아키텍처 그 자체에만 직접 관련된 품질 속성도 존재합니다.
아키텍처 품질 속성은 세 가지로 분류할 수 있는데 첫 번째로 개념적 무결 성으로 모든 레벨에서 시스템의 설계를 단일화하는 주제나 비전을 의미합니다.
두 번째는 정확성과 완료 성으로 아키텍처가 시스템의 모든 요구사항과 런타임 자원 제약을 충족시키는 것은 모든 아키텍트가 가지고 있는 최선 바람임을 의미합니다.
세 번째 빌드 가능성 속성은 알맞은 때에 가용 팀에 의해 시스템을 완료 하고 개발 진행에 따라 일정한 변경을 허용하는 것을 의미합니다.
이제 마지막 5절입니다.
5절에서는 소프트웨어 아키텍처의 구조를 이야기 해보겠습니다.
먼저 아키텍처의 구조로는 뷰 타입, 뷰 타입에 속한 스타일, 그리고 뷰 가 있습니다.
그리고 뷰 타입은 5-2를 보면 알 수 있듯이 모듈 뷰 타입, 컴포넌트-커넥터 뷰 타입, 할당 뷰 타입 3가지로 분류할 수 있습니다.
이들 3가지 뷰 타입은 각각 요소 타입과 관계 타입을 제합니다.
요소 타입과 관계타입을 제한 안에서도 요소가 제한 방법 그리고 요소 사이의 관계 설정 방법 등에 따라 여러 선택이 가능하다.
이러한 제한을 갖는 뷰 타입의 특수한 형식을 아키텍처 스타일 이라고 부른다.
스타일이 특정한 시스템을 묶어 표현한다면 이러한 표현을 뷰 라고 한다.
뷰 타입의 첫 번째로 모듈 뷰 타입입니다.
모듈 뷰 타입의 요소는 구현 단위인 모듈이며 각각의 모듈에는 기능적인 책임을 할당합니다.
효과적으로 모듈을 분리하기 위해서는 모듈 안에서 모듈 요소 사이에 발생하는 커뮤니케이션의 정도인 응집력을 최대화하고 모듈이 다른 모듈과 직접적인 종속 성을 갖는 정도인 결합 도를 최소화 해야 한다.
그림 1,2,3은 모듈 사이의 관계를 표현 한 것이다.
그림 1 의 Is-part-of관계는 전체(복합 모듈 A)와 서브모듈 B사이의 전체/부분 관계를 정의하는 것 입니다.
그리고 그림2의 defends-on관계는 종속성 관계를 정의 합니다.
일반적으로 defends-on관계는 초기 설계 과정에서 종속 관계의 정확한 형식을 결정하지 않았을 때 사용합니다.
마지막으로 그림3의 is-a관계는 좀 더 일반적인 모듈 E(부모)와 좀 더 특정한 모듈F(자식)사이의 일반화 관계를 정의한 것 입니다.
그렇다면 모듈 뷰 타입을 사용하는 목적은 무엇일까요.
첫 번째로 소스코드의 청사진을 제공하기 때문입니다.
두 번째로는 추적성과 영향도 분석의 도구로 사용할 수 있기 때문입니다.
모듈은 시스템을 분할하기 때문에 시스템의 기능적인 요구사항이 어떤 모듈에서 지원받게 할 것인가를 결정할 수 있게 하므로 추적성 분석을 도와줍니다. 또한 모듈 사이의 관계를 다이어그램을 통해 표현 할 수 있어 영향도 또한 분석할 수 있습니다.
세 번째로 처음 시스템을 접하는 사람들에게는 시스템의 기능성을 설명하기 위한 도구로 사용 할 수 있습니다.
네 번째는 성능, 신뢰성 또는 다른 런 타임 품질 속성의 분석을 위한 도구로는 적당하지 않다는 것입니다.
모듈 뷰 타입은 4가지 스타일을 포함하고 있습니다.
첫 번째로 분할 스타일이 있습니다.
분할 스타일은 is-part-of관계에 초점을 맞추고 있습니다.
그리고 시스템의 책임을 모듈 사이에서 어떻게 분할 할 것인가와 모듈을 서브 모듈로 어떻게 분할 할 것이 가를 보여주는데 유용합니다.
다른 스타일과는 달리 제약사항이 별로 없다는 것이 특징입니다.
분할 스타일은 UML에서 두 가지 방법으로 표현 할 수 있습니다.
예로 그림A와 그림B를 들어보도록 하겠습니다.
그림A의 경우 패키지로 표현한 집합 모듈에 중첩적인 형식으로 표현 할 수 있으며,
그림 B의 경우 복합관계로도 표현 할 수 있습니다.
두 번째로 레이어 스타일은 다른 모듈 스타일과 마찬가지로 소프트웨어를 단위로 분할한다.
그리고 보다 상위 계층의 코드가 사전에 정의한 규칙에 따라 보다 하위 계층을 사용하도록 허락한다.
레이어 스타일의 이점은 대형 시스템에서 모듈의 개수가 급격히 증가하여 이들 사이의 종속성 또한 확장 할 수 있게 한다.
또한 시스템을 변경할 필요성이 있을 경우, 변경할 영역을 결정하게 함으로써 분석 도구로도 활용할 수 있다.
세 번째, 사용 스타일은 두 모듈 사이의 관계에서 하나의 모듈이 정확하게 기능을 발휘하기 위해서는 다른 모듈을 정확히 구현하는 것을 요구합니다.
네 번째로 일반화 스타일이 있습니다.
이 스타일은 모듈이 일반화 관계에 있을 때 공통성과 가변성을 정의 할 수 있습니다.
부모 모듈은 공통성을 포함하게 하며 자식 모듈은 가변성을 정의하게 합니다.
또한 일반화 관계를 통해 자식 모듈을 추가,삭제,변경함으로써 아키텍처의 확장을 지원 할 수 있고 부모 모듈을 변경할 때에 모든 자식 모듈을 변경함으로 진화 또한 지원 할 수 있습니다.
일반화 스타일의 경우 상속은 구현 상속과 인터페이스 상속으로 나눌 수 있습니다.
구현상속은 클래스로부터 행위를 상속받아 그것을 수정함으로써 좀 더 특수한 행위를 정의 하는 것을 말합니다.
따라서 이것은 UML의 일반화 관계로 표현합니다. 그림 1에 해당하는 것입니다.
인터페이스 상속은 자식 클래스가 인터페이스에 지정된 행위를 구현하겠다는 것을 의미합니다.
이것은 UML의 실현 관계로 표현이 가능합니다. 이것은 그림 2에 해당합니다.
두 번째 타입으로 넘어와서 컴포넌트-커넥터 뷰 타입은 프로세스, 객체, 클라이언트, 서버, 데이터 저장소 와 같이 런타임 행위와 상호작용을 갖는 요소로 구성하고 있는 모델을 정의 합니다.
이 뷰 타입의 요소는 컴포넌트와 커넥터입니다.
여기서 컴포넌트는 시스템 안에서 실행하는 본질적인 연산 요소와 데이터 저장소이며,
커넥터는 둘 이상의 컴포넌트 사이의 상호작용의 실행 경로입니다.
이 뷰 타입은 성능, 신뢰성, 가용성 등과 같은 런 타임 시스템 품질 속성의 실현을 결정하는데 사용 할 수 있습니다.
컴포넌트-커넥터 뷰 타입 또한 모듈 뷰 타입처럼 스타일을 포함하고 있습니다.
파이트-필터 스타일에서 컴포넌트의 타입은 필터이고 커넥터는 파이프입니다.
따라서 필터(컴포넌트)는 파이프(커넥터)를 통해 받은 데이터를 변형하고 그 결과를 파이프로 전송합니다.
두 번째로, 공유 데이터 스타일에서 상호작용의 패턴은 지속성을 갖는 데이터의 교환이 지배적입니다.
이 스타일의 전형적인 예로는 데이터베이스 시스템을 얘기할 수 있습니다.
세 번째 스타일로는, 출반-구독 스타일이 있습니다.
이 스타일에서 컴포넌트는 발생하는 이벤트를 통해 서로 커뮤니케이션 합니다.
이때 이벤트를 발생하게 만드는 컴포넌트를 출판자라 하고, 이벤트를 받는 컴포넌트를 구독자라고 합니다.
구독자 컴포넌트는 출판-구독 런타임 시 이벤트에 대해 구독을 신청하고 출판 자 컴포넌트가 이벤트를 발생하게 할 때 출반-구독 런타임은 구독신청을 한 모든 구독자 컴포넌트에게 이벤트를 전달합니다.
이 스타일의 커넥터는 일종의 버스역할을 하는 것입니다.
출판-구독 스타일은 컴포넌트를 분리 시킴으로써, 시스템의 다른 부분에 영향을 주지 않고 한 부분을 수정 할 수 있다는 이점을 제공합니다.
네 번째 스타일인 클라이언트-서버 스타일 입니다.
이 스타일의 컴포넌트는 다른 컴포넌트에게 서비스를 요청함으로써 서로 커뮤니케이션을 합니다.
컴포넌트 사이의 커뮤니케이션은 항상 쌍으로 이루어지며, 클라이언트에 의해서 시작합니다.
서버 컴포넌트는 항상 하나 이상의 인터페이스를 통해 서비스를 제공하며, 클라이언트는 서버가 제공하는 서비스를 사용합니다.
다섯
번째 스타일로, 피어-투-피어
스타일이 존재합니다.
피어는
상대방과 서비스를 교환함으로써 직접 커뮤니케이션을 진행 합니다.
이 스타일의 컴포넌트는 클라이언트의 역할과 서버의 역할을 모두 수행합니다.
따라서 이 스타일의 커넥터는 양방향 프로토콜을 지원하여 양방향 커뮤니케이션을 가능하도록 해야 합니다.
여섯 번째로, 커뮤니케이트-프로세스 스타일에서는 데이터 교환, 메시지 전달, 동기화 등의 다양한 커넥터 메커니즘을 통해서
컴포넌트가 동시에 실행하며 상호작용을 합니다.
이제 뷰 타입의 마지막인 할당 뷰 타입입니다.
할당 뷰 타입은 소프트웨어 요소가 환경적인 구조에 어떻게 맵핑하는가를 보여줍니다.
이 말은 모듈 또는 컴포넌트-커넥터 뷰 타입의 요소들이 환경 요소에 할당하는 것을 표현합니다.
뷰 타입의 요소는 소프트웨어 요소와 환경 요소가 있습니다.
환경 요소는 프로세서나 디스크, 구성 항목 또는 개발 그룹과 같은 환경적인 구조를 나타내고,
소프트웨어 요소는 모듈 또는 컴포넌트-커넥터 뷰 타입의 요소로 이뤄 집니다.
할당 뷰 타입의 스타일에는
첫 번째로 배포 스타일이 있습니다.
배포스타일에서는 컴포넌트-커넥터 뷰타입의 소프트웨어 요소인 프로세스를 실행 플랫폼에 할당합니다.
이때 환경적인 요소는 CPU,커뮤니케이션 채널,메모리, 그리고 데이터 저장소 등의 물리적인 단위에 대응하는 실체가 됩니다.
배포 스타일은 성능, 신뢰성, 보안 등의 분석에 사용할 수 있으며, 비용 견적에도 사용 가능합니다.
두 번째는 구현스타일입니다.
구현 스타일은 모듈 뷰 타입의 모듈 요소를 개발 환경에 맵핑합니다.
구현 스타일에서 환경적인 요소는 파일과 디렉터리와 같은 구성 항목이며, 소프트웨어 요소는 클래스나 함수와 같은 모듈입니다.
마지막 스타일은 작업 할당 스타일입니다.
이 스타일은 모듈 뷰 타입의 모듈 요소를 개발 조직에 맵핑합니다.
작업 할당 스타일에서 환경적인 요소는 개인,팀,부서 등과 같은 조직 단위이며 소프트웨어 요소는 클래스나 함수와 같은 모듈입니다.
프로젝트를 진행해 가면서 우리는 계속해서 문서를 작성할 것입니다.
하지만 무작정 작성하는 것이 아니라 소프트웨어 아키텍처를 문서화 할 때 준수해야 할 기본적인 규칙이 있습니다.
첫 번째, 읽는 사람의 관점에서 문서를 작성하라.
두 번째, 불필요한 반복을 피하라
세 번째, 모호한 표현을 피하라
네 번째,표준 구성을 사용하라
다섯 번째, 설계 이유를 기술하라
여섯 번째, 문서를 최신 버전으로 유지하라
일곱 번째, 목적에 적합한 지 문서를 리뷰하라.
이러한 규칙들은 소프트웨어 아키텍처를 문서화할 때뿐만 아니라,
모든 소프트웨어 문서에도 적용해야
할 사항이라고 권고 하고 있습니다.
|