Tag Archives: Architectural Style

An Introduction to Software Architecture

An Introduction to Software Architecture

David Garlan and Mary Shaw
CMU-CS-94-166

효과적인 소프트웨어 엔지니어링을 위해서는 아키텍처적 소프트웨어 디자인의 장려가 필요하다는 점은 더욱 분명해지고 있다.

  • 시스템 간의 상위수준에서의 관계를 이해하고 기존 시스템을 기반으로 새로운 시스템을 작성하기 위해서는 아키텍처와 같은 일반적 페러다임을 인식할 수 있는 능력이 중요하다.
  • 올바른 아키텍처를 도출하는 과정은 때때로 소프트웨어 시스템의 성공적 설계를 방해하는 치명적인 요소가 되어 재앙에 가까운 참사를 유발할 수 있다.
  • 소프트웨어 아키텍처에 대한 상세한 이해는 설계와 관련된 선택가능한 대안들 중에 원칙을 준수한 올바른 선택을 할 수 있도록 엔지니어를 돕는다.
  • 아키텍처를 통한 시스템의 표현은 복잡한 시스템을 상위수준에서 정의하고 분석하기 위해 필수적인 요소이다.

이러한 이유에서 아키텍처 스타일에 대해 이해하고 사용할 수 있는 능력을 기르는 것은 프로그래머에게 필수불가결한 선택이 될 것이다. 여기서는 An Introduction to Software Architecture에서 언급되고 있는 아키텍처 스타일의 정의와 특징에 대해 정리하고자 한다.


Intro: Architectural Style

아키텍처 스타일이란 일련의 유사한 특징을 가진 소프트웨어 제품군에 대하여, 그 구조적 조직의 공통점을 패턴화하여 정의한 것이다. 아키텍처 스타일은 해당 스타일을 인스턴스로 사용될 수 있도록 하기 위하여 컴포넌트들과 컨넥터들에 대한 개념/용어들을 정의하고 있으며, 어떻게 컴포넌트들과 컨넥터들이 함께 연결될 수 있는지에 대한 제약사항을 정의한다. 다음의 항목들에서는 아키텍처 스타일의 대표적인 사례들에 대하여 탐색한다.


1. Pipes and Filters

1.1 정의 및 특징

파이프/필터 스타일의 각 컴포넌트들은 일련의 입력에 대한 집합과 그에 상응하는 출력의 집합을 갖고 있다. 필터는 개체들과 반드시 독립적이여야 한다는 특징을 갖고 있으며, 이는 다음과 같은 내용을 의미한다.

  • 필터는 다른 필터들과 상태정보를 공유하지 않아야 함
  • 필터는 자신을 선행하는 필터(Upstream Filter)나 뒤따라르는 필터(Downstream Filter)에 대한 정보를 알 수 없음
  • 파이프/필터 네트워크의 출력값에 대한 정확성은 필터의 배열 순서에 종속되지 않아야 함

1.2 장점

  • 시스템 이해가 쉬움
    • 설계자는 각 필터들의 행위들을 간단히 조합해보는 과정을 통해 시스템의 입출력 행위를 이해할 수 있음
  • 재사용을 지원
    • 어떠한 두개의 필터든 상호간에 연결될 수 있으며, 상호간 데이터의 전송을 보장함
  • 시스템의 유지보수와 개선이 용이
    • 새로운 필터를 기존 파이프/필터 시스템에 추가할 수 있어, 기존의 필터는 개선된 필터로 쉽게 변경될 수 있음
  • 시스템 분석
    • Throughput/데드락과 같은 특수한 분석들을 지원함
  • 동시성
    • 태생적으로 동시성(Concurrency)을 보장함

1.3 단점

  • 처리업무의 일괄 조직(batch organization)을 야기
    • 점진적 업무처리의 특성이 있지만, 각 필터들은 독립적이기 때문에 설계자는 일괄처리(특정 필터 집중처리) 시스템의 형태로 치우칠 위험이 있음
    • 특히 대화형 응용프로그램을 다루는데에 적합하지 않음
  • 서로 연관된, 분리된 두 스트림의 관련성(Correspondence)를 유지하기가 어려움
  • 구현에 따라서 데이터 전송시 낮은 수준의 공통분모만을 공유할 수도 있음
    • 각 필터에서 전송된 데이터를 필요에 따라 다시 파싱하는 등의 추가 비용 소모

2. Data Abstraction and Object-Oriented Organization

2.1 정의 및 특징

이 스타일에서는 데이터의 표현(representation)과 데이터와 연결된 중요 동작(operation)들이 추상 데이터형으로 캡슐화된다. 다시 말하자면, 디자인 결정사항은 캡슐화하여 숨기는 가운데 인터패이스의 제공을 통해 객채들 간의 관계를 정의하게 된다. 객체는 해당되는 자원들의 무결성을 보장하고 이를 위해 자원들을 보호할 책임이 있으며 추상 데이터형과 캡슐화가 이러한 책임을 성취하기 위한 도구로써 사용된다. 이 스타일의 중요한 특징 두 가지를 다시 정리하자면 다음과 같다.

  • 객체는 객체의 표현방식(object representation)에 대한 무결성(integrity)을 보장하여야 함
  • 객체의 표현방식은 다른 객체들에겐 감추어져 공개되지 않음

2.2 장점

  • 객체의 클라이언트들에게 객체의 표현방식이 감추어지기 때문에, 클라이언트들에게 영향을 미치지 않고 구현을 변경할 수 있음
    • 동일한 동작에 대하여 다양한 구현방식을 선택할 수 있는 가운데, 구현 방식에 변경이 발생하더라도 외부에서는 이를 알 수 없고 기능에는 변화가 없기 때문에 구현 변경으로 인한 부작용(side effect)에서 자유로울 수 있음
  • 어떤 데이터 조작에 참여하는 접근루틴(access routine)의 집합을 묶어 분류할 수 있기 때문에 설계자는 특정 문제에 대하여 관여자들 간의 상호작용으로 문제의 범위를 분리/축소할 수 있음
    • 데이터에 대한 무분별한 접근이 허용되지 않으며, 정해진 인터페이스를 명시적으로 호출하는 관계에 있는 관여자들에 한해서만 데이터의 조작이 이루어짐

2.3 단점

  • 어떤 객체가 다른 객체와 통신하기 위해서는 대상 객체에 대한 정보를 해당 객체가 미리 알고 있어야만 함
    • 예를 들어 앞서 살펴본 pipe and filter 스타일의 경우에 특정 필터는 원하는 상호작용을 위해서 다른 필터들의 정보를 알고 있을 필요가 없음
    • 특히 다른 객체들에 의해 명시적으로 참조(혹은 invoke)되는 부분(인터페이스로 보면 됨)에서 수정이 발생할 경우, 해당 부분을 참조하고 있는 모든 객체들의 연쇄적인 수정을 야기함
  • 하나의 객체에 대해 복수의 객체가 상호작용하고 있는 경우, 특정 객체의 상호작용이 나머지 참조 객체들에게 예기치 않은 부작용을 야기할 수 있음
    • 다수의 객체들에서 복수의 요청이 발생했을 때, 해당 요청들이 일정한 규칙을 갖고 순차적으로 발생하는 것이 아님

3. Event-based, Implicit Invocation

3.1 정의 및 특징

미리 공개된 인터페이스에 따라 이를 명시적으로 호출하며 프로시저나 함수가 진행되는 통합 방식과는 달리, 암묵적인 호출(implicit invocation)을 통한 반응적 통합(혹은 selective broadcast)이 또 다른 대안 기법으로 제시 되었다. 특정 프로시저를 직접적으로 호출하는 개념과는 달리 암묵적 호출의 개념은 특정 컴포넌트가 하나 이상의 이벤트를 발행(announce 혹은 broadcast)하는 동작을 기반으로 한다. 사전에 해당 이벤트에 대하여 구독 등록을 한 프로시저들이 이러한 발행에 대응하여 암묵적으로 호출되게 된다. 이러한 이벤트 기반의 스타일은 다음과 같은 특징을 갖는다.

  • 아키텍처의 측면에서, 이러한 스타일의 컴포넌트는 “이벤트의 집합”과 “프로시저의 묶음”에 대한 인터페이스를 제공함
  • 이벤트의 발행자는 발행하는 이벤트가 어떠한 컴포넌트에게 영향을 미칠지를 알 수 없음[footnote]이는 앞서 설명한 객체 스타일의 단점이었던 ‘부작용(side-effect)과도 일맥상통하는 특성이다. 약한 결합(loosely-coupled)은 재사용성을 증가시키나 충분히 절제되고 관리되지 못하기 때문에 명확한 상호작용을 정의할 수 없고 예기치 않은 영향을 야기한다. 이 때문에 암묵적 호출 방식을 선택한 시스템에서는 명시적 호출 방식을 함께 사용하고 있는 경우가 있다.[/footnote] (암묵적 호출의 특성)

3.2 장점

  • 강력한 재사용 지원
    • 어떠한 컴포넌트가 추가되든 단순한 이벤트의 구독 동작을 통해 시스템 내의 상호작용에 쉽게 참여할 수 있음
  • 시스템의 변화(evolution)가 용이
    • 약한 결합을 기반으로 직접 연결되어 상호작용하지 않기 때문에 컴포넌트는 다른 컴포넌트의 인터페이스에 영향을 미치지 않고 쉽게 교체될 수 있음

3.3 단점

  • 컴포넌트는 시스템의 계산 활동에 대한 제어권을 상실(혹은 포기)하게 됨
    • 이벤트가 발송되는 순간에 이벤트를 발송한 컴포넌트는 해당 이벤트가 어떠한 컴포넌트에 영향을 미칠지를 알 수 없음
    • 더구나 만약 발송된 이벤트를 구독할 컴포넌트들을 특정지을 수 있다고 하더라도, 이벤트에 의한 묵시적 호출이 어떠한 순서로 호출을 야기하고 어떠한 순서로 호출이 종료될지를 특정지을 수 없음
  • 데이터의 교환 문제
    • 경우에 따라서는 이벤트에 데이터를 포함하여 전송할 수 있는 경우도 있으나, 이러한 전달이 적합하지 않은 경우에는 공유 저장소(repository)를 사용하여 데이터를 교환할 수 밖에 없음
    • 이러한 경우 광범위한 범위에서의 성능 이슈와 자원 관리 이슈와 같은 심각한 문제에 봉착할 수 있음
  • 정확성(correctness)의 판단 시 문제가 발생할 여지가 높음
    •  이벤트의 발행에 대한 프로시저의 의미는 발행 시점에서의 문맥적 결합(context of bindings, 발행-구독 관계)정보에 의해 결정되기 떄문에 정확성을 판단할 기준을 세우기 어려움

4. Layered Systems

4.1 정의 및 특징

레이어드 시스템(layered system)은 계층적(hierarchically)으로 구성된다. 각 계층(layer)은 보다 상위에 위치한 계층들에게는 서비스를 제공자가 되고, 하위 계층들로부터는 서비스를 제공받는 클라이언트의 입장이 된다.

  • 각 계층은 상위계층에게는 일종의 가상머신으로 동작하게 되며, 어떤 계층에 속한 서비스가 인접한 상위계층에게만 공개될지 모든 상위계층에게 공개될지는 신중히 결정되어야 함
  • 계층 간의 상호작용은 프로토콜로 정의된 연결자(connector)들을 통해 이루어짐

4.2 장점

  • 추상화(abstraction) 수준의 증가에 기반한 디자인을 지원함
    • 복잡한 문제를 점진적이고 순차적으로 분할하여 구현할 수 있도록 함
  • 발전성(enhancement)를 지원함
    • 파이프라인 스타일과 유사하게, 특정 서비스의 수정이 많아도 두 개의 인접한 계층에만 영향을 미치게 됨으로 변화가 불필요하게 전파되지 않고 고립됨
  • 재사용을 지원함
    • 추상데이터형과 유사하게, 동일한 계층에 위치한 다른 구현들은 인접한 계층에 동일한 인터페이스를 제공하여 상호 교환을 지원할 수 있음
    • 즉, ‘표준 계층 인터페이스’의 정의가 가능하게 함

4.3 단점

  • 모든 시스템들이 쉽게 계층 구조적 형태로 조직될 수 있는 것은 아님
  • 설령 구조적으로는 레이어드 시스템의 구성이 가능하더라도, 논리적 상위 기능들과 논리적 하위 기능 구현 사이의 인접한 커플링에 대한 성능적 이슈가 고려되어야만 함
  • 올바른 추상화 수준을 찾는 것이 상당히 어려울 수 있음

5. Repositories

5.1 정의 및 특징

저장소(repository) 스타일은 현재의 상태(state)를 저장하는 중앙자료구조(central data structure)와 중앙 저장소에 대한 동작을 수행하는 독립된 컴포넌트들의 집함으로 구성된다. 이러한 저장소 중심의 스타일은 크게 ‘전통적 데이터베이스’와 ‘블랙보드’의 두 가지 유형으로 나눌 수 있다. 과거의 일반적인 데이터베이스의 경우는 트랙젝션들을 유발하는 입력 스트림에 의하여 수행될 프로세스들이 선택되었다면, 블랙보드 유형은 중앙자료구조의 현재 상태에 의해 수행할 프로세스가 선택 된다(이 때의 중앙 저장소를 ‘블랙보드’라고 칭한다).

5.2 블랙보드 모델의 구성

  • 지식원천 (The knowledge sources)
    • 응용프로그램 의존적인 정보의 독립적으로 분리 된 구역들
    •  지식원천들 간의 상호작용은 블랙보드를 통하여 이루어짐
    •  지식원천의 호출(invocation)은 블랙보드의 상태에 의해 작동됨
  • 블랙보드 자료구조 (The blackboard data structure)
    • 응용프로그램 종속적인 계층 안에 조직된 ‘문제해결 상태 정보’를 일컬음
    • 지식원천들에 의하여 블랙보드의 정보는 변화되며, 이를 통하여 점진적으로 문제의 해결책으로 나아가게 됨
  •  제어 (Control)
    • 블랙보드의 상태에 전적으로 의존적인 부분
    • 블랙보드의 변화에 의해 지식원천에 대한 요청이 필요한 경우를 관리함
    • 다시 말하자면, 블랙보드 모델에서 시스템 내부의 전반적 문제해결 흐름을 중재하며 관리함

6. Table Driven Interpreters

6.1 정의 및 특징

인터프리터의 조직을 위해서는 가상머신이 소프트웨어 안에 생성되게 된다. 번역엔진 스스로에 의해 해석된 수도프로그램(pseudo-program)이 인터프리터에 포함되어있으며, 수도프로그램은 프로그램 자신과 함께 인터프리터의 실행 상태에 대한 유추정보(analog)를 제공한다.

6.2 구성

  • 번역엔진 (Interpretation engine)
    • 번역 작업을 수행
  • 저장공간 (Memory)
    • 번역 된 수도코드가 저장될 공간
  • 번역엔진의 제어상태 (Representation of the control state of the interpretation engine)
  • 실험중인 프로그램의 현재상태 (Representation of the current state of the program being simulated)

Outro

이상과 같이 논문에서 기사에서 언급되고 있는 6개의 대표적인 아키텍처 스타일들의 특징을 정리해보았다. 원문에서는 이러한 태표 스타일들과 함께 기타 유사한 아키텍처들에 대해 언급함과 함께, 실제 시스템에서는 여러 종류의 스타일들이 결합하여 포함되어야 함을 강조하고 있다. 그리고 이러한 결합을 위한 방법으로서, 계층구조의 도입이나 아키텍처적 연결자 역할을 할 컴포넌트를 도입, 그리고 특정 아키텍처 기술(description) 수준의 타 아키텍처로의 완전한 치환 등을 제시한다. 하지만 이제까지 정리한 내용과 이러한 아키텍처의 결합에 대한 내용을 보다 분명히 이해하기 위해서는 원문의 나머지 부분에서 다루고 있는 예제들에 대한 고민이 필수적일 것으로 보이며 이러한 예제에 대한 내용은 직접 확인하여 스스로의 이해를 돕도록 하자.