소프트웨어 아키텍처 101 - CHAPTER 19 아키텍처 결정
아키텍트에게 기대하는 핵심 가치 중 하나는 아키텍처 결정을 내리는 것입니다. 아키텍처 결정은 애플리케이션이나 시스템의 구조에 관한 것이 대부분이지만 기술 결정 역시 (그것이 아키텍처 특성에 영향을 미칠 경우) 포함될 수 있습니다. 아키텍처 결정을 하려면 충분한 정보를 수집하고 결정을 정당화, 문서화한 다음 이해관계자들과 효과적으로 소통해야 합니다.
19.1 아키텍처 결정 안티패턴
프로그래머 앤드류 케이니그(Andrew Koenig)는, 안티패턴이란 처음에는 좋은 생각처럼 보이지만 이내 곧 곤경에 빠뜨리는 애물단지라고 정의합니다. 부정적인 결과를 내는 반복 가능한 프로세스라고 정의하는 이들도 있습니다. 아키텍처 결정에서 자주 발생하는 아키텍처 안티패턴은 ‘네 패를 먼저 보여주지마(Covering Your Assets)’, ‘무한반복 회의(Groundhog Day)’, 이메일 기반 아키텍처(email-driven architecture)’ 세 가지를 꼽을 수 있습니다. 정확하고 효과적인 아키텍처 결정을 하려면 아키텍트는 이 세 안티패턴 모두 극복해야 합니다.
19.1.1 ‘네 패를 먼저 보여주지마’ 안티패턴
아키텍트가 잘못된 선택을 하는 것을 두려워한 나머지 아키텍처 결정을 회피하거나 미루는 현상을 말합니다.
이 안티패턴은 두 가지 방법으로 극복할 수 있습니다. 첫째, 어떤 중요한 아키텍처 결정을 내리기 전, 마지막으로 책임질 수 있는 순간(last responsible moment)까지 기다리는 것입니다. 아키텍트가 자신의 결정을 정당화하고 검증하기 위해 충분한 정보를 수집할 때까지 기다리지만, 개발팀을 마냥 붙잡아 두거나 분석 마비(analysis paralysis) 안티패턴에 빠질 정도로 오래 기다리지는 않음을 의미합니다. 둘째, 개발팀과 지속적으로 협력하면서 아키텍트가 결정한 내용을 원래 의도한 대로 추진합니다. 세부적인 기술에 관한 모든 이슈를 아키텍트 혼자 전부 알 수는 없기 때문에 개발팀의 협력은 절대적으로 필요합니다. 그래야 나중에 문제가 생겨도 아키텍트가 아키텍처 결정을 변경하면서 재빠르게 대응할 수 있습니다
19.1.2 ‘무한반복 회의’ 안티패턴
사람들이 어떤 결정을 왜 했는지 모르고 주구장창 회의만 계속 하는 것입니다.
‘무한반복 회의’ 안티패턴이 발생하는 이유는 아키텍트가 자신이 내린 결정을 정단화하는 데 실패했기 때문입니다. 아키텍처 결정을 정당화하려면 그 결정을 내리게 된 기술적, 비즈니스적 근거를 제시하는 것이 중요합니다.
어떤 아키텍처 결정이건 그것을 정당화할 때는 비즈니스 가치를 제시하는 것이 중요합니다. 그렇게 해야 그 아키텍처 결정을 정말 다른 무엇보다 우선해야 하는지 한 번 더 돌아볼 수 있습니다. 그럴 만한 비즈니스 가치가 없다면 좋은 아키텍처 결정이 아니니 한발짝 물러나 재고해 보는 것이 좋습니다.
가장 일반적인 비즈니스 정당화로는 비용, 출시 시기, 유저 만족도, 전략적 포지셔닝 등이 있습니다. 이 네 가지 관점에서 비즈니스적으로 정당화할 때에는 무엇이 비즈니스 이해관계자에게 중요한지 숙고해봐야 합니다. 이를테면, 비즈니스 이해관계자가 비용보다 시장 출시 시기에 더 관심이 있는데도 단순히 비용 절감만을 내세우면서 결정을 정당화하려는 건 바람직하지 않습니다.
19.1.3 ‘이메일 기반 아키텍처’ 안티패턴
사람들이 아키텍처 결정을 놓치거나 잊어버리고 심지어는 그렇게 결정됐다는 사실조차 알지 못해 아키텍처 결정을 구형하지 못하는 상태입니다. 즉, 아키텍처 결정을 효과적으로 전달하는 문제와 관련된 안티패턴입니다.
이 안티패턴을 방지하고 아키텍처 결정을 효과적으로 전달하려면 어떻게 해야 할까요? 이메일 본문에 아키텍처 결정으로 포함시키지 않습니다. 그럼 아키텍처 결정이 변경되거나 다른 결정으로 대체될 경우, 어떤 식으로 사람들에게 통보하는 게 좋을까요? 첫째, 이메일 본문에는 아키텍처 결정의 본질과 맥락 정도만 언급하고 세부 정보는 단일 기록 시스템에 보관해서 그 링크만 제공하면 됩니다.
둘때, 아키텍처 결정에 정말 관심이 있는 사람들에게만 통지합니다.
아키텍처 결정에 관한 세부 내용을 확인 가능한 링크를 제공하면 모든 정보를 일원화 하려 관리할 수 있는 체계가 완성됩니다.
19.2 아키텍처적으로 중요한
아키텍처 결정에 기술적인 내용이 포함되면 그것은 아키텍처 결정이 아니라, 기술 결정이라고 단정짓는 아키텍트들이 많지만, 아키텍트가 어떤 기술을 사용하기로 결정을 했고 그 기술을 어떤 아키텍처 특성을 직접 지원하기 위해 선택한 것이라면 이는 아키텍처 결정이 맞습니다.
저명한 소프트웨어 아키텍트이자 Release It 릴리즈 잇
(위키북스, 2007)의 저자 마이클 나이가드(Michael Nygard)는 아키텍트가 어떤 아키텍처 결정을 담달하는지 (즉, 아키텍처 결정이란 대관절 무엇인지) ‘아키텍처적으로 중요한(architecturally significat)’이라는 용어를 만들어 풀이하고자 했습니다. 그는 아키텍처적으로 중요한 결정이란 구조, 비기능성 특성, 의존성, 인터페이스, 구현 기술에 영향을 미치는 결정이라고 보았습니다.
구조(structure)는 사용 중인 아키텍처의 패턴이나 스타일에 영향을 미치는 결정들입니다.
비기능 특성(nonfunctional characteristic)은 개발 또는 유지보수 중인 애플리케이션이나 시스템에 중요한 아키텍처 특성(’~성’)들입니다.
의존성(dependency)은 전체 확장성, 모듈성, 민첩성, 시험성, 안정성 등에 영향을 미치는 시스템 내부의 컴포넌트와 (또는) 서비스 간의 커플링 지점을 가리킵니다.
인터페이스(interface)는 게이트웨이, 통합 허브, 서비스 버스, API 프록시를 통해 서비스와 컴포넌트에(를) 액세스하고 조정하는 수단을 말합니다. 계약 버저닝, 버전 구식화(deprecation) 전략 등 계약에 정의된 내용이 곧 인터페이스입니다.
구현 기술(construction technique)은 원래 그 자체는 기술적인 것이지만, 아키텍처의 많은 부분에 영향을 미치는 플랫폼, 프레임워크, 도구, 프로세스에 관한 결정입니다.
19.3 아치텍처 결정 레코드
아키텍처 결정을 가장 효과적으로 문서화하는 방법은 바로 아키텍처 결정 레코드(Architecture Decision Record, ADR)입니다.
19.3.1 기본 구조
ADR의 기본 구조는 제목(Title), 상태(Status), 콘텍스트(Context), 결정(Decision), 결과(Consequences), 이렇게 주요 5개 섹션으로 구성됩니다. 여기에 컴플라이언스(Compliance)와 노트(Notes)라는 추가 세션을 덧붙입니다. 필요시 세션을 추가하는 방법으로 기본 구조[그림 19-1]를 확장하는 식으로 템플릿을 간명하게 유지할 수 있습니다.
제목
ADR 제목(title)은 일련 번호와 함께 아키텍처 결정을 짤막한 문구로 표현합니다.
상태
ADR 상태(status)는 제안됨(Proposed), 수락됨(Accepted), 대체됨(Superseded)으로 표현합니다. ‘제안됨’은 해당 결정이 상위 레벨의 의사 결정권자 또는 아키텍처 거버넌스 협의체의 승인을 득해야 하는 상태입니다. ‘수락됨’은 결정이 승인되어 구현할 준비가 된 상태입니다. ‘대체됨’은 결정이 번복되어 다른 ADR에 의해 대체된 상태로, 이전 ADR 상태는 수락됨 상태여야 합니다. 즉, 제안됨 상태의 ADR은 다른 ADR로 대체되는 일 없이 수락됨 상태가 될 때까지 계속 수정됩니다.
대체됨 상태는 어떤 결정이 내려졌고, 당시 왜 그런 결정을 했는지, 새로운 결정은 무엇이고 어쩌다 변경을 하게 됐는지 등에 관한 이력을 보관하는 강력한 수단입니다. 일반적으로 어떤 ADR이 대체되면 그 ADR을 대체한 결정이 병기되며, 반대로 다른 ADR을 대체한 결정은 자신이 대체한 ADR로 병기됩니다.
예를 들어, ADR 42는 이미 전에 승인됐지만 이후 서비스의 구현체 및 위치가 바뀌어 두 서비스 간 통신 방식을 변경하기로 했다면(ADR 68) 상태는 다음과 같습니다.
콘텍스트
ADR 콘텍스트(context) 섹션은 불가항력적인 요소를 특정합니다. 다시 말해 ‘어떤 사정 때문에 그렇게 결정할 수밖에 없었나?’입니다. 아키텍트는 이 섹션에서 특수한 상황이나 문제점을 이야기하고 다른 대안에 대해 상술합니다. 각 대안을 상세히 분석한 문서가 필요할 경우, 콘텍스트 섹션 대신 ADR에 대안(Alternatives) 섹션을 추가합니다.
결정
ADR 결정(decision) 섹션에는 아키텍처 결정과 그렇게 결정하게 된 사유를 전부 밝힙니다. 마이클 나이가드는 수동적인 어조 대신, 매우 긍정적이고 당당한 어조로 아키텍처 결정을 설명하는 훌륭한 방법을 강조합니다.
결정 섹션의 가장 큰 강점은 아키텍트가 방법(how)보다 이유(why)에 더 무게를 실을 수 있다는 것입니다. 사실 왜 그런 결정을 내렸는지 이해하는 것이 그것이 어떻게 작동되는지 이해하는 것보다 훨씬 더 중요합니다. 결정을 내린 이유와 그런 결정을 할 수밖에 없었던 사연을 알고 나면 사람들은 문제의 맥락을 더 잘 이해하고 행여 다른 문제가 생기지 않도록 리팩터링을 통해 실수를 예방할 수 있습니다.
결과
ADR 결과(consequences) 역시 아주 강력한 섹션입니다. 이 섹션에는 아키텍처 결정의 전체적인 영향도를 기술합니다. 아키텍처 결정이 어떤 영향을 미치는지 구체적으로 기술함으로써 아키텍트는 결정의 장점보다 그 영향이 더 중요한지 되돌아보게 됩니다.
이 섹션은 아키텍처 결정에 관한 트레이드오프는 물론, 분석 결과도 문서화할 수 있으므로 유용합니다. ADR을 활용하면 결과 섹션에서 트레이드오프 분석 등 아키텍처 결정의 콘텍스트(및 트레이드오프)에 대한 전체 그림을 그려볼 수 있어 이슈를 예방할 수 있습니다.
컴플라이언스
ADR의 컴플라이언스(compliance) 섹션은 표준 섹션은 아닙니다. 이 섹션은 컴플라이언스 관점에서 아키텍트가 아키텍처 결정을 어떻게 측정/관리하는 게 좋을지 생각하게 만듭니다. 아키텍트는 본인의 결정에 대한 컴플라이언스 체크를 수동으로 할지, 아니면 피트니스 함수로 자동화할지 결정해야 합니다. 피트니스 함수로 자동화할 수 있으면 피트니스 함수를 작성하는 방법, 그리고 컴플라이언스 측면에서 이 아키텍처 결정을 판단하기 위해 코드베이스에 다른 변경은 필요 없는지 등의 내용을 이 섹션에 기재합니다.
노트
노트(note) 섹션 역시 표준 섹션은 아니지만 가급적 추가하는 게 좋습니다. 이 섹션에는 다음과 같이 ADR에 관한 다양한 메타데이터가 포함됩니다.
- 원저자
- 승인일
- 승인자
- 대체일
- 최종 수정일
- 수정자
- 최종 수정 내역
19.3.2 ADR 저장
ADR은 위키(또는 위키 템플릿) 또는 다른 문서 렌더링 소프트웨어에서 쉽게 접근 가능한 공유 파일 서버의 공유 디텍터리에 저장하는 것이 좋습니다.
19.3.3 ADR로 문서화
ADR은 소프트웨어 아키텍처를 효과적으로 문서화하는 수단으로 활용할 수 있습니다. ADR 콘텍스트 섹션은 아키텍처 결정이 필요한 시스템의 특정 영역을 기술하는, 더 없이 훌륭한 장소인 데다 어떤 대안들이 있는지 기술하기에 적절한 곳입니다. 하지만 무엇보다 중요한 섹션은, 아키텍처 결정을 내린 사유가 기술된 결정 섹션입니다. 이 섹션 하나만 봐도 ADR은 현존하는 최고의 아키텍처 문서화 포맷입니다.
19.3.4 ADR로 표준화
ADR 결정 섹션은 어떤 표준이 있는지, 그리고 (더 중요한 것이지만) 그런 표준이 왜 존재해야 하는지 표현합니다. 이것은 어떤 표준을 다른 무엇보다 우선시해야 하는 논리를 효과적으로 검증하는 수단이 됩니다. 표준이 필요한 이유를 개발자가 더 잘 납득할 수 있게 해야 그들이 표중을 따를 가능성이 높아집니다. ADR 결과 섹션은 어떤 표준이 타당하며 반드시 지켜져야 하는지를 아키텍트 스스로 검증하기에 적합한 기회입니다.
19.3.5 예시
요약
19.1 아키텍처 결정 안티패턴
- 안티패턴 정의: 처음에는 좋은 생각처럼 보이지만 결과적으로 문제를 일으키는 반복 가능한 프로세스.
- 주요 안티패턴 세 가지:
- ‘네 패를 먼저 보여주지마’ 안티패턴
- ‘무한반복 회의’ 안티패턴
- ‘이메일 기반 아키텍처’ 안티패턴
19.1.1 ‘네 패를 먼저 보여주지마’ 안티패턴
- 현상: 아키텍트가 잘못된 선택을 두려워하여 아키텍처 결정을 회피하거나 미룸.
- 극복 방법:
- 마지막으로 책임질 수 있는 순간까지 기다리기: 충분한 정보 수집 후 적시에 결정.
- 개발팀과 지속적인 협력: 세부 기술 이슈를 함께 해결하고, 필요 시 결정 변경에 빠르게 대응.
19.1.2 ‘무한반복 회의’ 안티패턴
- 현상: 결정의 이유를 몰라 회의만 반복하는 상황.
- 극복 방법:
- 결정을 비즈니스 가치로 정당화: 기술적, 비즈니스적 근거 제시.
- 비즈니스 이해관계자의 우선순위 고려: 비용, 출시 시기, 사용자 만족도, 전략적 포지셔닝 등.
19.1.3 ‘이메일 기반 아키텍처’ 안티패턴
- 현상: 아키텍처 결정이 효과적으로 전달되지 않아 구현되지 않음.
- 극복 방법:
- 이메일 본문에 결정 포함 금지: 세부 정보는 단일 기록 시스템에 저장하고 링크 제공.
- 관련자에게만 통지: 관심 있는 사람들에게만 정보를 공유.
- 정보 일원화: 변경 시 효율적인 통보와 관리가 가능하도록 시스템 활용.
19.2 아키텍처적으로 중요한
- 개념 정의: 아키텍처적으로 중요한 결정은 구조, 비기능 특성, 의존성, 인터페이스, 구현 기술에 영향을 미침.
- 구성 요소:
- 구조: 아키텍처 패턴이나 스타일에 영향.
- 비기능 특성: 시스템의 중요한 아키텍처 특성.
- 의존성: 컴포넌트와 서비스 간의 커플링 지점.
- 인터페이스: 서비스와 컴포넌트에 접근하는 수단과 계약 내용.
- 구현 기술: 플랫폼, 프레임워크, 도구, 프로세스에 관한 결정.
19.3 아키텍처 결정 레코드 (ADR)
- 정의: 아키텍처 결정을 효과적으로 문서화하는 방법.
- 활용 장점: 아키텍처 문서화, 표준화, 결정 이력 관리 등에 효과적.
19.3.1 기본 구조
- 주요 섹션:
- 제목 (Title): 일련 번호와 간단한 문구로 결정 표현.
- 상태 (Status): 제안됨, 수락됨, 대체됨 등으로 결정의 상태 표시.
- 콘텍스트 (Context): 결정에 필요한 상황이나 문제점, 대안 기술.
- 결정 (Decision): 아키텍처 결정과 그 사유를 명확하고 적극적인 어조로 기술.
- 결과 (Consequences): 결정의 전체적인 영향도와 트레이드오프 분석.
- 추가 섹션:
- 컴플라이언스 (Compliance): 결정의 준수 여부를 어떻게 관리할지 기술.
- 노트 (Notes): 메타데이터 정보(원저자, 승인일, 수정 내역 등) 포함.
19.3.2 ADR 저장
- 저장 방법: 위키나 공유 파일 서버의 디렉터리에 저장하여 쉽게 접근 가능하도록 함.
19.3.3 ADR로 문서화
- 효과적인 문서화 수단: 결정의 이유와 맥락을 상세히 기록하여 이해도 향상.
19.3.4 ADR로 표준화
- 표준의 필요성 및 이유 명확화: 개발자가 표준을 이해하고 준수할 가능성 증가.
19.3.5 예시
- ADR 작성 예시 제공: 실제 사례를 통해 ADR의 구조와 활용 방법 설명.