들어가며

소프트웨어 개발자에게는 디자인 패턴으로 잘 알려져 있는 Christopher Alexander(CA)는 건축가이다. 그는 수많은 프로젝트에 참여했으며, 사후에도 Center for Environmental Structure(CES)를 통해 그의 사상은 Building Beauty 프로그램 등을 통해 교육적으로 계승되고 있다. Alexander의 중심 개념들은 고정된 형태를 설계하는 것이 아니라, 사용자의 참여와 환경의 변화에 따라 '살아있는 구조(living structure)' 로 점진적으로 키워가는 과정이라는 철학을 담고 있다.

적용 사례: Eishin 학교와 University of Oregon

Alexander의 철학은 다양한 프로젝트에 적용되었다. 그중 대표적인 두 사례는 일본의 Eishin 학교 캠퍼스와 미국 University of Oregon 이다.

  • Eishin 학교는 Alexander가 직접 설계한 유일한 고등학교 캠퍼스이며, Generative Sequence와 Pattern Language가 매우 충실히 구현된 사례로 알려져 있다. 학생, 교사, 설계자 모두가 참여하여 하나의 생명 있는 공간을 창조했다. 이 과정이 "The Battle for the Life and Beauty of the Earth: A Struggle Between Two World-Systems"에 잘 설명되어 있다.
  • University of Oregon은 1975년에 시작되어 University of Oregon이 고정된 마스터플랜 대신 참여 중심의 계획과 점진적인 변화 방식을 도입한 장기 프로젝트이다. 이 실험은 이후 공식적인 Campus Plan의 철학적 기반이 되었다. 이 내용은 "The Oregon Experiment"에 잘 설명되어 있다.

2025 Campus Plan의 핵심 원칙 세 가지

특히 이번 2025 개정판에서는 CA의 철학과 밀접하게 연결되는 세 가지 원칙이 보인다.

  1. 원칙 1: Process and Participation

    • “의미 있는 참여 기회를 제공해야 한다.”
    • 사용자 그룹과 전문가, 위원회가 협력하여 계획을 수립하며, 누구나 프로세스에 참여할 수 있는 구조가 마련되어 있다.
  2. 원칙 4: Space Use and Organization

    • “공간은 기능적이고 유연하며 조화롭게 조직되어야 한다.”
    • 사람 중심의 배치와 10분 도보권 안에서의 공간 설계를 기본으로 하여, 생명력 있는 물리적 질서를 만들고자 한다.
  3. 원칙 11: Patterns

    • “패턴은 문장의 단어처럼 함께 작동해 하나의 전체를 만든다.”
    • CA의 Pattern Language를 실무에 적용하며, 모든 설계 프로젝트는 관련 패턴을 선택하고 검토하는 절차를 따라야 한다.

이 세 가지 원칙은 Generative Sequence의 실행 조건이기도 하며, Oregon 대학이 단순한 철학을 넘어 실천으로 전환하고 있다는 증거로 볼 수 있다.

마무리

"The Nature of Order"를 통해, CA는 설계가 단순히 '형태를 만드는 프로세스'가 아니라 '살아있음을 향상시키는 형태를 만드는 과정'이어야 한다고 말한다. Eishin 학교가 그 이상을 구체적으로 구현한 시도였다면, University of Oregon의 Campus Plan은 그 철학을 수십 년간 유지하며 제도화해 온 실천 모델이라고 할 수 있다.

한편, Hatfield‑Dowlin Complex와 같은 대형 기부 프로젝트는 설계의 방향이 기부자의 의사에 의해 결정되었으며, 사용자 참여는 거의 이루어지지 않았다는 점에서 비판의 여지가 크다. 이는 Alexander의 사상과 반대되는 것으로, 현실적 타협의 산물이라 할 수 있다. 다만, 이 건물이 메인 캠퍼스와 물리적으로 분리된 위치에 있다는 점에서 그 영향은 제한적이라 볼 수 있다.

다시 말하자면, 완전하지는 않지만 여전히 ‘살아있는 캠퍼스’를 만들어가고 있는 보기 드문 사례이다.

참고문헌

  • Christopher Alexander, "The Nature of Order: Book 2 – The Process of Creating Life" (2002)
  • Christopher Alexander et al., "The Battle for the Life and Beauty of the Earth: A Struggle Between Two World-Systems", (2012) Center for Environmental Structure, 16
  • Christopher Alexander et al., "The Oregon Experiment", 1975
  • University of Oregon, Campus Plan 2025 (공식 웹사이트 cpfm.uoregon.edu)

✅ 왜 Cross-platform 개발이 필요한가?

Cross-platform 개발은 한번의 개발로 여러 플랫폼에 적용 가능한 것을 이야기 한다.

무엇 보다도 비싼 개발 리소스 절감이 가능하다. 모바일도 크게는 Android와 iOS로 나뉘어 있어서 각각 따로 개발해야 한다. 개발 인력만 봐도 최소 2배가 필요하다. 개발도 효율화가 되지만, 유지보수 효율도 높아 진다. 공통 코드이므로 한번만 수정하면 된다. 또한, 일부 플랫폼 특화 기능만 분기 처리 (예: Platform.OS === 'ios')도 가능하다.

스타트업 같은 경우는 시장 대응 속도도 빠르게 가능하다. 특히, 초기 MVP 또는 실험적 서비스는 짧은 시간에 양 플랫폼에 출시하는 것이 중요할 수 있다. 이 때, Cross-platform은 런칭 시간 단축, 빠른 배포 가능하다.

무엇 보다도 중요한 것 중에 하나는 일관된 사용자 경험 이라고 할 수 있겠다. 동일한 UI 구성 요소와 로직을 공유함으로써 Android/iOS 간 UI/UX의 일관성 확보하고, 디자인 시스템이나 UI 패턴을 통합하여 관리할 수 있다.

하지만, Cross-platform이 만능은 아니다. 다음과 같은 지적도 있다. 그래서 많은 기업들이 "핵심 기능은 Native, 나머지는 Cross-platform" 구조를 도입한다. "Cross-platform은 하나의 기술 방식이고, Hybrid는 이를 Native와 조합하는 전략이라고 할 수 있다.

반론 설명
성능 문제 아주 고성능(게임, AR, 애니메이션 등)에서는 Native가 우위
플랫폼 특화 기능 OS 레벨 기능이나 복잡한 센서 접근은 Native로 작성 필요
디버깅 복잡도 RN/Flutter 모두 브리지나 엔진 레이어가 있어 디버깅이 더 어려움

이러한 Cross-platform 전략에는 Flutter, React Native 등이 있다. React Native의 경우는 기존의 Web 개발자들이 접근이 용이하여 많이 채용되고 있는 상황이다. 위에서 언급한 것처럼 Native도 일부 적용하고 있으므로 기존 iOS, Android 개발 경험도 도움이 될 수 있겠다.

React Native로 사용할 수 있는 옵션은 크게 세 가지 범주로 나뉘며, 개발 목적과 프로젝트 규모, 유지보수 편의성에 따라 적절한 선택이 필요합니다:

✅ 1. 기본 React Native (Bare React Native)

✦ 설명:

  • Facebook에서 만든 기본 react-native 프레임워크
  • Native 모듈(Android/iOS) 직접 개발 가능

✦ 장점:

  • Native 기능에 가장 직접적으로 접근 가능
  • 필요한 라이브러리만 선택해서 구성 가능 (유연함)
  • EAS Build 또는 Xcode/Android Studio 사용 가능

✦ 단점:

  • 환경 설정 복잡 (Xcode, Android SDK, CocoaPods 등)
  • 초기 설정과 유지보수 부담 큼

✅ 2. Expo (Managed Workflow)

✦ 설명:

  • React Native 위에 구축된 프레임워크
  • 설정, 빌드, 배포까지 쉽게 만들어주는 도구 포함 (Expo Go, EAS Build)

✦ 장점:

  • 개발 시작이 매우 빠름 (npx create-expo-app)
  • Hot Reload, Expo Go로 실시간 테스트 가능
  • 다수의 기본 API 내장 (카메라, 위치, 센서 등)

✦ 단점:

  • Expo SDK에 없는 기능은 eject 필요
  • 네이티브 코드 직접 수정이 어려움 (Managed Workflow 기준)

✅ 3. Expo Bare Workflow (또는 Ejected Workflow)

✦ 설명:

  • Expo의 유용한 기능은 유지하면서도 native code 수정이 가능하도록 한 방식
  • expo eject 명령으로 전환 가능

✦ 장점:

  • Expo SDK의 일부 기능 사용 가능
  • Native 모듈 직접 커스터마이징 가능

✦ 단점:

  • Expo 관리형 워크플로우의 간편함은 일부 상실됨
  • Native 설정 및 빌드 환경 세팅 필요

✅ 주요 선택 기준 비교

기준 Expo Managed Workflow Expo Bare Workflow Bare React Native
초기 설정 매우 쉬움 중간 복잡
네이티브 모듈 사용 제한적 (eject 필요) 자유로움 자유로움
빠른 프로토타이핑 매우 유리 보통 불리
성능 최적화/커스터마이징 제한적 가능 가능
빌드 도구 지원 (EAS, etc.) 완전 지원 일부 지원 외부 설정 필요

![[react_native_workflows.png]]

 

✅ 사용 예시

  • 간단한 앱 + 빠른 배포가 목적: Expo Managed Workflow
  • 카메라, Bluetooth, Background task 등 Native 기능 필요: Expo Bare 또는 Bare React Native
  • 기업 앱, 고성능/맞춤형 기능이 많은 앱: Bare React Native

대표적인 사례로 React Native는 Facebook, Instagram, Discord 등에서 채용하고 있다고 한다. 하지만, React Native만 쓴다기 보다는 Native도 활용하는 Hybrid가 대세라고 하겠다. 보안이나 HW와 연동하는 부분에서는 특히 이러한 것들이 필요하겠다.

다음은 React Native에서도 접근 가능한 전략이라고 하겠다. Native와 연동은 모두 가능하다고 하겠다.

당신의 목표는?
├── 빠르게 MVP 출시 or 간단한 앱 → Expo Managed Workflow
│
├── 네이티브 기능이 일부 필요하다면? (카메라, Bluetooth 등)
│   ├── Expo 기능도 일부 쓰고 싶다 → Expo Bare Workflow
│   └── Expo 없이 완전한 커스터마이징 원함 → Bare React Native
│
└── 고성능 앱 or 대규모 앱 (예: 게임, 복잡한 비즈니스 로직)
    → Bare React Native 권장

✅ 마무리

이 글은 React Native로 간단한 구현을 하면서 검토하기 시작했고, 마무리 단계에서 다시 정리해 본 글이다. Android가 주된 개발 경험인 입장에서 이러한 설계에 가까운 개념 검토와 정리는 향후 어려 설계 및 구현에도 도움이 될 것이라 기대해 본다.

 

개요

MVA (Minimum Viable Architecture)는 시스템의 필수적인 아키텍처만을 구현하여 빠르고 효율적으로 제품을 시장에 출시하고 사용자 피드백을 받는 접근 방식이다[1]. 이는 효과적인 아키텍처 실험과 밀접하게 연결된다. MVA를 통해 각 실험은 원자성(Atomic), 시기적절함(Timely), 명확성(Unambigous)한 특징을 유지하면서, 최소한의 아키텍처로 실험을 진행하여, 더 큰 아키텍처 변경 전에 필요한 피드백을 신속하게 얻을 수 있다. 이러한 접근 방식은 리스크를 최소화하고, 결과의 해석을 간단하게 하며, 전체 개발 과정을 더욱 효과적으로 관리할 수 있도록 돕는다.

 

효과적인 아키텍처 실험의 특징

특징설명

원자성 한 번에 하나의 질문에 집중하여 혼란을 방지하고 결과를 명확하게 한다.
시기 적절함 위험을 작고 관리 가능한 단위로 나누어 빠르게 피드백을 얻고 결과 해석을 간소화한다.
명확성 명확한 성공 기준과 측정 가능한 결과를 가지고 있어 실험이 성공했는지 판단할 수 있다.

 

효과적인 아키텍처 실험을 위한 질문

아래 표는 기사에서 설명하는 효과적인 아키텍처 실험을 수행하는 핵심 원칙을 요약하고, 이러한 실험을 계획하고 실행하기 위한 구조적 접근 방식을 제공한다.

가설 설정
(A clear hypothesis)
우리가 테스트하는 구체적인 가설은 무엇이며, 어떤 결과가 가설이 유효하다는 것을 나타낼까?
측정 가능성
(An explicit and measurable goal or target)
성공을 어떻게 측정할 것이며, 어떤 메트릭을 사용할까?
구현
(A method for running the experiment and mechanisms for measuring its success or failure)
실험을 수행하기 위해 어떤 단계를 밟을 것이며, 결과를 어떻게 문서화할까?
대체 계획
(A plan for rollback if the experiment fails)
실험이 실패할 경우, 우리의 롤백 계획은 무엇인가?
시간
(An explicit timeline for the experiment)
이 실험을 완료해야 하는 시간 프레임은 무엇이며, 우리의 목표와 어떻게 일치해야 하는가?

 

참고 문서

[1] Pierre Pureur and Kurt Bittner, "Software Architecture and the Art of Experimentation", Dec 17, 2024, https://www.infoq.com/articles/architecture-experimentation/?utm_source=infoqEmail&utm_medium=editorial&utm_campaign=ArchitectNL&utm_content=01312025

개요

소프트웨어 아키텍처에 대해서 학습을 하다가 보면, 정말 많은 문서 작업을 요구한다. 정말 이런 것들이 다 필요한 것일까? 정말 다 줄이고 하나만 남긴다면 무엇을 할 수 있을까? 아니면 아예 문서 작업을 하지 않으려 한다면 그래도 이건 꼭 해보자면 무엇을 이야기할 수 있을까?

애자일 하게 개발을 진행하는 조직에서 요구 사항도 취합되어 백로그에 유저 스토리들이 쌓여 있다고 해보자. 이렇게 개발하다 보면, 자연 스럽게 개발자 수준에서 설계도 되어 우리 팀의 아키텍처가 내재되어 나오게 된다. 

하지만, 위의 상황은 상당히 이상적이다. 여러 담당자들이 구현을 해 가다 보면, 이상하다고 느껴지는 부분이 생기곤 한다. 진행이 안되고 막혀 있다는 부분이 있다. 이러한 부분은 의사 결정이 필요할 수도 있고, 실험을 통해서 확인이 필요할 수도 있다. 여기서는 의사 결정을 해야 하는 경우에 대해서 다뤄보자. 이를 위한 것이 아키텍처 의사 결정이고 이를 기록하는 것이 아키텍처 의사 결정 레코드 (Architectural Decision Record)이다.

이렇게 Architect는 의사 결정자나 이해관계자(Stakeholder)가 결정할 수 있또록 정보를 제공하여 결정을 지원하거나, 책임이 자신에게 있다면 기술적인 결정을 해야 한다. 그렇다면, 무엇을 가지고 어떻게 할 수 있을까?

아키텍처 의사 결정 기록 (ADR)소개

이와 같은 경우를 위해 활용할 수 있는 것이 다음과 같은 아키텍처 의사 결정 기록(Architectural Decision Record, ADR)이다. [1]에서는 ADR의 아주 간단한 형식을 보여 준다.

[기능 또는 컴포넌트]에 해당하는 맥락에서,
[요구 사항 또는 목표로 하는 품질 속성(Quality Attribute)]을 충족할 필요가 있다,
우리는 [이익]을 우선적으로 달성하기 위해
[선택된 옵션]을 채택하기로 결정하고
그리고 [대안]은 선택하지 않아서
그 선택에 따르는 [부정적인 결과]는 받아들인다.

이 내용은 아주 간단하게 기술되어 있다. 그렇기 때문에 다음과 같이 나누어 상세 한 부분을 살펴 볼 수 있다.

  • Problem Statement: "[기능 또는 컴포넌트]에 해당하는 맥락에서,"가 이 부분이다. 우리가 결정이 필요한 문제가 어떤 것인지 말한다. 위의 예에서는 간단하게 되어 있지만, 맥락을 잘 표현하기 위해서 더 상세히 설명해야 할 수도 있다.
  • Candidate Architecture: 위의 예에서는 [선택된 옵션]과 [대안]이 여기에 포함된다. 위의 예어서는 2개만 표현되어 있지만 3개 이상일 수 있다. 특히, 옵션들은 정말로 어떤 것을 선택할지 고민이 된다면 중요한 Architecture Problem일 수 있다.
  • 요구 사항 및 품질 속성: 많은 경우, Problem Statement에 우리가 다루려고 하는 Functional Scenario가 이미 포함된다. 아키텍처 선택을 할 때 우리가 고려해야 하는 품질 속성의 중요도에 따라 의사 결정을 하는 것이 일반적이다.
  • 보완 필요 부분: "부정적인 결과"를 받아 들인다고 했다. 하지만, 이 부분이 늘 쉽지는 않다. 그렇기 때문에 이 부정적인 결과에 대한 대책이 필요하기도 하다.

패턴들의 구조에서도 설명되지만 문제 기술도 필요하다. 위의 구조와 유사하지만 다음과 같은 형태도 사용한다

다른 형태의 ADR

위와 같이 간단한 형태에서 상세 내용을 기반으로 조정한 ADR이 포함해야 하는 항목을 다시 한번 정리해 보자.

Problem Statement

이 부분을 분리하는 경우는 ADR이 다루려고 하는 문제를 더 상세히 표현하려고 할 때 분리해서 설명하면 좋다. 그렇지 않고, 간단한 문장으로도 표현할 수 있다.

Candidate Architectures

우리가 실제로 고민해야 하는 Architecture적으로 중요한 결정 사항은 무엇일까? 대안들이 2개 이상일 때 Architecture 적으로 중요한 문제일 수 있다. 예를 들어 보자. 어려 이해관계자들이 요구 사항의 충돌이 있을 때, 이 부분을 조정하여 결정해야 하는 사항이다.

간단한 사례

간단한 사례로 "학교 프로젝트를 만들기 위한 발표 자료를 어떻게 준비할까?"를 예로 들어 ADR 형식으로 만들어 보자.

 

  손으로 직접 그림 그리기 파워포인트 슬라이드 사용 큰 포스터로 만들기
장점 (만족하는 품질 속성) 창의적이고 독창적임. 
준비 비용이 적음
수정이 쉽고 깔끔함
팀과 쉽게 공유 가능
시각적으로 강렬함
한눈에 보기 좋음
단점 (손해보는 품질 속성) 시간이 오래 걸림
수정이 어려움
컴퓨터가 필요함
디자인에 시간 소요
운반이 불편함
수정이 어려움
큰 공간 필요

 


이해관계자인 팀원들과 수정이 쉽고 깔끔하게 보이고, 팀원들과 쉽게 공유하고 의견을 주고받을 수 있기 때문에 파워포인트 슬라이드 사용하기로 의사 결정하였다. 이렇게 의사 결정 했을 때에는 디자인에 시간이 소요되고 컴퓨터가 필요하다는 것을 알고 있다. 다지안의 경우는 미리 제공되는 템플릿을 최대한 활용하여 시간을 절약하기로 하였고, 디자인 감각이 있는 팀원이 디자인은 전담하기로 역할 분담을 하였다. 발표에도 컴퓨터가 필요하기 때문에 컴퓨터가 필요하다는 것을 확인하였고 팀원 중 한명이 준비하기로 하였다. 

아마도 다른 옵션들을 선택하는 경우도 있을 수 있다. 제약으로 컴퓨터를 사용하지 못할 경우도 있고, 포스터 세션처럼 운용될 수도 있어서 다른 옵션을 선택해야만 하는 경우도 있을 수 있다. 즉, 다른 옵션들도 의미 없이 그냥 만든 것이 아니고 많은 고민을 해야 하는 옵션들인 것이다.

결론

위에서 살펴 본 것과 같이 ADR에 대해서 살펴 보았고, 아주 간단한 사례를 통해서 여러 옵션들을 도출하고 이를 비교해서 의사 결정을 하는 사례도 살펴 보았다. 

참고 문헌

[1] 올라프 짐머만, 미르코 스토커, 다니엘 뤼브케, 우베 즈둔, 세자레 파우타소, "마이크로서비스 API 디자인 패턴, 쉬운 통합을 위한 결합도 최적화 전략" 에이콘출판, 이승범 (옮긴이)  

개요

리엔지니어링 패턴의 10장 다형성 적용한 조건문 변환은 객체 지향 리엔지니어링 패턴 중에서 조건문을 다형성으로 변환하는 데 중점을 둔다. 이러한 변환은 시스템의 유연성과 유지 보수성을 높이는 데 기여하며, 다양한 조건문을 대체할 수 있는 6가지 주요 패턴을 제시한다. 각 패턴은 특정 상황에서 반복적으로 발생하는 문제를 해결하기 위해 설계되었다.

주요 패턴 요약

  1. 자신 타입 체크 변환하기
    • 클래스의 타입을 검사하는 조건문을 각 타입에 맞는 서브클래스와 다형성 메서드 호출로 대체하여 확장성을 개선한다.
  2. 클라이언트 타입 검사 변환하기
    • 클라이언트 클래스에서 특정 프로바이더 타입을 검사하는 조건문을 제거하고, 각 프로바이더에 새로운 메서드를 추가하여 결합도를 줄인다.
  3. 상태 추출하기
    • 상태(State) 디자인 패턴을 적용하여 객체의 상태에 따라 다른 동작을 수행하도록 하며, 상태를 별도의 클래스 객체로 캡슐화하여 유지 보수성을 향상시킨다.
  4. 전략 추출하기
    • 전략(Strategy) 패턴을 적용해 알고리즘을 캡슐화하고, 조건문을 대체하여 다양한 전략을 동적으로 교체할 수 있도록 한다.
  5. 널 객체 도입하기
    • 널 값을 검사하는 조건문을 널 객체로 대체하여 클라이언트 코드의 간소화 및 가독성을 높인다.
  6. 조건문을 등록으로 변환하기
    • 도구와 클라이언트 간의 결합도를 낮추기 위해 조건문을 등록(Registration) 메커니즘으로 대체하여 모듈화와 유연성을 개선한다.

이 패턴들은 조건문을 다형성으로 변환하여 코드 중복을 줄이고, 향후 시스템 확장을 보다 유연하게 할 수 있도록 한다.

 

참고 문헌
[1] Serge Demeyer et al., "Object-oriented Reengineering Patterns"
[2] https://github.com/blcktgr73/OORP/blob/master/OORP_latest.pdf

리엔지니어링 패턴의 9장 책임 재배치는 기존 시스템의 클래스와 객체들이 지나치게 많은 책임을 갖거나, 너무 적은 책임만 수행하는 문제를 해결하는 방법론이다. 세 가지 주요 패턴에 대해 이야기 한다.

  1. 동작을 데이터 가까이 이동하기
    데이터 컨테이너에서 행동을 수행하는 클라이언트 클래스에 정의된 행동을 데이터가 있는 곳으로 이동하여 캡슐화를 강화하는 방식이다. 이를 통해 클라이언트가 데이터 구조에 대한 직접적인 의존을 줄이고, 코드 중복을 줄이는 효과가 있다. 이 패턴은 데이터 컨테이너를 더욱 객체답게 만들고, 클라이언트 코드의 유지 보수를 쉽게 한다.
  2. 탐색 코드 제거하기
    객체 간 탐색을 줄여 클래스 간 결합도를 낮추는 패턴이다. 특정 객체의 속성에 접근하기 위해 여러 단계를 거쳐야 할 경우, 탐색 코드를 데이터 컨테이너 내로 옮겨 캡슐화를 높인다. 이를 통해 클래스 간의 불필요한 종속성을 줄이고, 변경의 영향을 최소화할 수 있다.
  3. 신 클래스(God Class) 분할하기
    하나의 클래스에 지나치게 많은 책임이 집중된 경우, 이를 여러 작은 클래스로 분리하는 방법이다. 신 클래스는 여러 기능을 담당하며, 시스템의 모든 제어를 맡아 비대해진 클래스이다. 이를 분할하여 각 기능을 적절한 클래스에 배분함으로써 유지 보수성을 높이고, 객체 지향 설계를 강화할 수 있다.

이 세 패턴은 책임을 올바르게 분배하고, 코드의 응집도와 캡슐화를 개선하는 데 중점을 두고 있다.

 

참고 문헌
[1] Serge Demeyer et al., "Object-oriented Reengineering Patterns"
[2] https://github.com/blcktgr73/OORP/blob/master/OORP_latest.pdf

[1]의  9장에서는 API의 계약 문서화와 이해 관계자들과 커뮤니케이션을 위한 패턴을 다룬다.

1. API 설명

  • 설명: API의 기능, 메시지 구조, 동작의 의미 등을 문서화하여 클라이언트 개발자가 이해할 수 있도록 한다. OpenAPI와 같은 기술적 계약 설명 언어를 사용할 수 있다.
  • 주요 특징:
    • 상호 운용성 보장
    • 정보 은닉 유지
    • 확장성과 진화 가능성 지원
  • 포스의 충돌:
    • 지나치게 복잡한 설명은 유지보수에 어려움을 주고, 간단한 설명은 상호 운용성을 해칠 수 있음.
    • 정보 은닉과 상호 운용성 사이의 균형을 유지해야 함.

2. 요금 책정 플랜

  • 설명: API 사용량에 따라 요금을 청구하는 플랜을 정의하는 패턴. 구독 기반 요금제, 사용량 기반 요금제 등이 있으며, 고객의 사용량을 정확히 측정하고 요금 부과.
  • 주요 특징:
    • 경제적 측면, 정확성, 세분성, 보안 등의 고려 필요
    • 구독형, 사용량 기반, 시장 기반 등의 요금제 변형 가능
  • 포스의 충돌:
    • 사용량 측정과 청구의 정확성을 유지하면서, 비용 효율적인 방법을 찾아야 함.
    • 고객의 만족과 프로바이더의 수익성 사이의 균형 유지 필요.

3. 사용 비율 제한

  • 설명: 클라이언트가 API를 과도하게 사용하는 것을 방지하기 위한 패턴. 주기적으로 재설정되는 간격 기반 전송률 제한을 사용하여 과도한 요청을 차단하거나 제한.
  • 주요 특징:
    • 경제적 측면과 성능 보장
    • 남용 방지 및 신뢰성 유지
  • 포스의 충돌:
    • 너무 엄격한 제한은 사용자의 불만을 초래할 수 있으며, 너무 느슨한 제한은 시스템의 안정성을 해칠 수 있음.
    • 서비스 품질과 클라이언트의 자유로운 사용 사이의 갈등을 조율해야 함.

4. 서비스 수준 계약 (SLA)

  • 설명: API가 제공하는 서비스의 품질을 명시적으로 정의한 계약. 특정 서비스 수준 목표(SLO)를 포함하여, 이를 충족하지 못했을 때의 벌칙이나 보상 등을 규정.
  • 주요 특징:
    • 가용성, 성능, 보안, 법적 준수 등의 품질 특성 측정 가능
    • 소비자 관점에서의 매력도 향상
  • 포스의 충돌:
    • 높은 품질 보증은 프로바이더에게 높은 비용과 위험을 수반할 수 있음.
    • 클라이언트의 신뢰를 얻으면서도 비용 효율적인 방법을 찾아야 함.

 

참고 문헌
[1]  올라프 짐머만 , 미르코 스토커 , 다니엘 뤼브케 , 우베 즈둔 , 세자레 파우타소 , "마이크로서비스 API 디자인 패턴: 쉬운 통합을 위한 결합도 최적화 전략" 에이콘. 이승범 역

[1]의  8장에서는 다룬 API 진화 패턴을 다룬다. 각 패턴에 대한 설명, 주요 특징, 그리고 충돌하는 요구 사항(포스)을 포함한다.

변경 사항 도입 패턴:

  1. 공격적 폐기
    • 설명: 이전 버전을 빠르게 폐기하고, 클라이언트에게 빠르게 신규 버전으로 전환하도록 강제.
    • 주요 특징:
      • 사용 빈도가 낮은 기능을 신속히 제거.
      • 유지 관리 비용 절감.
      • 최신 버전 채택 촉진.
    • 포스:
      • 신속한 혁신과 클라이언트 안정성 간의 균형.
      • 빠른 전환이 어려운 클라이언트와의 충돌 가능성.
  2. 실험적 미리 보기
    • 설명: 초기 버전을 미리 공개하여 클라이언트가 테스트하고 피드백을 제공할 수 있게 함.
    • 주요 특징:
      • 초기 채택과 피드백 장려.
      • 정식 출시 전 API를 개선할 수 있음.
    • 포스:
      • 불안정한 기능 노출의 위험.
      • 기능의 안정성과 클라이언트 기대치 관리 필요.
  3. 2개의 상용 버전
    • 설명: 기존 버전과 새로운 버전을 동시에 유지하여 점진적인 전환 지원.
    • 주요 특징:
      • 클라이언트의 중단 없는 전환 가능.
      • 역호환성 제공.
    • 포스:
      • 여러 버전을 유지 관리하는 데 필요한 자원 증가.
      • 새로운 기능과 이전 버전 지원 간의 균형.
  4. 제한적 수명 보장
    • 설명: API 버전의 지원 기간을 명확히 설정.
    • 주요 특징:
      • 버전 지원 종료 시점을 명확히 하여 클라이언트의 계획 수립 도움.
    • 포스:
      • 클라이언트의 기대치와 실제 지원 기간 간의 조율 필요.
      • 더 긴 지원이 필요한 클라이언트와의 충돌 가능성.
    •  

버전 표시 패턴:

  1. 버전 구분자
    • 설명: 명확한 버전 식별자를 사용하여 API 업데이트 구분.
    • 주요 특징:
      • 역호환성 관리.
      • 클라이언트가 특정 버전을 선택할 수 있게 함.
    • 포스:
      • 버전 관리 규칙의 엄격한 제어 필요.
      • 여러 버전이 동시에 사용될 때의 어려움.
  2. 시멘틱 버전 관리
    • 설명: 구조화된 버전 체계(예: major.minor.patch)를 사용하여 변경의 성격을 표시.
    • 주요 특징:
      • 버전 간 호환성 이해를 간편하게 만듦.
      • 중요한 변경 및 신규 기능을 명확히 신호.
    • 포스:
      • 새로운 기능 추가와 역호환성 유지의 균형 필요.
      • 일관된 버전 규칙 준수가 요구됨.

호환성 보장 패턴:

  1. 서비스 수준 계약(SLA)
    • 설명: API의 가용성, 성능 및 지원에 대한 명확한 기대치를 설정.
    • 주요 특징:
      • 클라이언트에게 안정성을 보장.
      • 신뢰성과 가동 시간 기준 설정.
    • 포스:
      • 안정성을 보장하면서 지속적인 개선을 하는 것의 충돌.
      • 높은 기준을 유지하기 위한 비용 부담.

참고 문헌
[1]  올라프 짐머만 , 미르코 스토커 , 다니엘 뤼브케 , 우베 즈둔 , 세자레 파우타소 , "마이크로서비스 API 디자인 패턴: 쉬운 통합을 위한 결합도 최적화 전략" 에이콘. 이승범 역

[1]의  7장에서는 주로 메시지 설계 품질을 개선하는 다양한 패턴과 접근 방식을 설명한다. API의 직관적 이해, 성능, 진화 가능성과 같은 품질 요소의 중요성을 설명하며, 성능과 보안, 확장성 등의 상충하는 요구 사항 사이에서 균형을 맞추는 방법을 다룬다. 패턴을 크게 나누면, 케시지 크기 및 요청 수 조정, 참조 관리 그리고 제어 및 표현 정도에 따른 패턴으로 구분할 수 있다. 각 패턴의 설명과 주요 특징, 그리고 패턴 적용 시 발생할 수 있는 주요 요구 사항인 '포스(force)' 충돌에 대해 요약한다.

메시지 크기 및 요청 수 조정하기를 위한 패턴

  1. 요청 번들
    • 설명: 여러 작은 요청을 하나의 큰 요청으로 묶어 클라이언트가 여러 번의 요청을 보내지 않도록 한다.
    • 주요 특징:
      • 네트워크 대역폭 절약
      • 응답 지연 시간 감소
      • 클라이언트 구현 단순화
    • 포스의 충돌:
      • 처리 복잡성 증가 vs. 성능 최적화
      • 클라이언트-서버 간 데이터 일관성 유지 필요
  2. 조건부 요청
    • 설명: 클라이언트가 이미 보유한 데이터와 서버의 데이터를 비교하여 변경된 데이터만 전송받도록 한다.
    • 주요 특징:
      • 네트워크 사용량 감소
      • 서버 및 클라이언트 간 데이터 일관성 유지
    • 포스의 충돌:
      • 효율성 vs. 추가 구현 복잡성
      • 상태 관리 필요성 증가
  3. 페이지네이션
    • 설명: 대량의 데이터를 청크로 나누어 클라이언트가 순차적으로 필요한 데이터만 가져오게 한다.
    • 주요 특징:
      • 대용량 데이터의 효율적 전송
      • 클라이언트의 메모리 사용 최적화
    • 포스의 충돌:
      • 데이터 최신성 vs. 성능 최적화
      • 네트워크 안정성과 리소스 사용 조정 필요

참조 관리의 대안으로서 패턴

  1. 임베디드 엔티티
    • 설명: 필요한 데이터를 응답 메시지에 직접 포함하여 클라이언트가 추가 요청 없이 필요한 모든 데이터를 얻도록 한다.
    • 주요 특징:
      • 관련 데이터의 한 번에 전송
      • 클라이언트-서버 간 추가 요청 최소화
    • 포스의 충돌:
      • 데이터 일관성 vs. 메시지 크기 증가
      • 전송 시간 증가와 대역폭 소비
  2. 링크된 정보 보유자
    • 설명: 관련 데이터를 직접 포함하는 대신, 해당 데이터를 참조하는 링크를 제공하여 필요 시 클라이언트가 추가 요청을 통해 접근할 수 있게 한다.
    • 주요 특징:
      • 메시지 크기 감소
      • 독립적 데이터 관리 가능
    • 포스의 충돌:
      • 효율성 vs. 추가 요청 필요성
      • 데이터의 최신성 유지 vs. 데이터 접근 지연

제어 및 표현의 정도에 따른 패턴

  1. 위시 리스트
    • 설명: 클라이언트가 요청 시 필요한 응답 데이터의 속성만 지정하여 선택적으로 데이터를 요청한다.
    • 주요 특징:
      • 데이터 전송 최적화
      • 클라이언트의 요구에 맞춘 맞춤형 응답 제공
    • 포스의 충돌:
      • 성능 최적화 vs. 클라이언트 복잡성 증가
      • 정확한 데이터 전달 vs. 데이터 취합의 어려움
  2. 위시 템플릿
    • 설명: 클라이언트가 중첩된 데이터 구조에서 필요한 부분만을 요청하여 더 세부적으로 응답을 조정할 수 있다.
    • 주요 특징:
      • 데이터 과다 전송 방지
      • 세밀한 데이터 제어 가능
    • 포스의 충돌:
      • 데이터 간결성 vs. 클라이언트-서버 간 데이터 처리 복잡성
      • 성능 향상 vs. 클라이언트의 정확한 요청 설계 필요

 

참고 문헌
[1]  올라프 짐머만 , 미르코 스토커 , 다니엘 뤼브케 , 우베 즈둔 , 세자레 파우타소 , "마이크로서비스 API 디자인 패턴: 쉬운 통합을 위한 결합도 최적화 전략" 에이콘. 이승범 역

[1]의 6장은 API 설계와 관련된 내용으로, 특히 요청 및 응답 메시지에 포함되는 메시지 표현의 설계에 대한 다양한 패턴과 고려 사항을 다루고 있다. 클라이언트와 프로바이더 간의 상호 운용성, 성능, 보안, 유지보수성을 보장하기 위해 요청 및 응답 메시지의 표현을 설계하는 것이 중요하다. 또한, 메시지 표현은 데이터 구조의 복잡성과 효율성 간의 균형을 맞추어야 한다. 메시지 표현의 과제는 여러가지가 포함된다. 메시지 크기, 대화의 복잡성, 상호 운용성, 지연 시간, 처리량, 확장성, 유지보수성, 개발자 경험 등 다양한 요소를 고려해야 한다. 그리고, 클라이언트와 프로바이더의 독립적인 배포 가능성을 확보하는 것이 중요하다.

 

패턴 소개

1. 데이터 엘리먼트 (Data Element)

설명:
데이터 엘리먼트는 API 요청 및 응답 메시지에서 도메인 모델 개념을 표현하는 기본 구성 요소이다. 클라이언트와 프로

바이더 간의 통신을 위한 핵심 데이터 구조로 사용된다. 구조화된 데이터로서, 아토믹 파라미터, 파라미터 트리 등 다양한 형태로 존재할 수 있다.

 

주요 특징:

  • 도메인 모델의 복잡한 개념을 추상화하고 구조화하여 데이터 표현을 용이하게 함.
  • 클라이언트와 프로바이더 간의 느슨한 결합(loose coupling)을 촉진해 유지보수성 향상.
  • 데이터 계약(data contract)을 통해 클라이언트가 데이터 구조를 이해하고 상호작용할 수 있게 함.

포스 충돌:

  • 풍부한 기능 vs. 성능: 복잡한 도메인 모델을 노출할수록 클라이언트에게 더 많은 기능을 제공할 수 있지만, 그만큼 성능 저하와 유지보수의 어려움이 있을 수 있다.
  • 보안 vs. 구성의 용이성: 데이터를 많이 노출할수록 보안 위협에 노출될 가능성이 크며, 이에 따라 구성 및 처리 부담이 커질 수 있다.
  • 유연성 vs. 유지보수성: 다양한 표현을 제공하여 유연성을 높이려다 보면 유지보수의 어려움이 생길 수 있다.

 

2. 메타데이터 엘리먼트 (Metadata Element)

설명:
메타데이터 엘리먼트는 요청 및 응답 메시지의 데이터를 설명하거나 보충하는 추가 정보를 제공한다. 이는 메시지의 의미를 명확히 하거나 처리 효율성을 높이는 데 사용된다.

제어 메타데이터, 애그리게이티드 메타데이터, 출처 메타데이터 등 다양한 변형이 있다.

 

주요 특징:

  • 데이터의 의미, 출처, 상태 등의 추가 정보 제공으로 상호 운용성(interoperability)을 강화.
  • 메시지 수신자가 데이터를 더 잘 해석할 수 있도록 도움을 줌.
  • 클라이언트가 데이터 처리와 분석을 효율적으로 할 수 있도록 정보 제공.

 

  • 포스 충돌:
    상호 운용성 vs. 결합도: 메타데이터가 많아질수록 해석이 쉬워져 상호 운용성이 향상되지만, 클라이언트와 서버 간의 결합도가 높아질 수 있다.
  • 사용 편의성 vs. 성능: 메타데이터가 메시지 크기를 늘려 처리 성능을 저하시킬 수 있다.
  • 보안 vs. 관리 용이성: 메타데이터에 보안 정보가 포함될 때, 관리의 복잡성이 증가할 수 있다.

 

3. ID 엘리먼트 (ID Element)

설명:

  • ID 엘리먼트는 API의 엔드포인트, 동작, 메시지 표현을 고유하게 식별하기 위한 데이터 요소이다. 클라이언트가 특정 데이터를 정확히 요청하고 처리할 수 있도록 한다.
  • UUID, URI, URN 등 다양한 형태로 제공될 수 있으며, 글로벌 고유성과 로컬 고유성을 보장할 수 있다.

주요 특징:

  • 각 데이터 요소를 고유하게 식별하여 명확한 참조를 가능하게 함.
  • 글로벌 고유성(예: UUID)과 로컬 고유성(예: 특정 세션 내에서만 유효한 ID)으로 나뉨.
  • 분산 시스템에서도 안정적인 데이터 참조가 가능.

 

포스 충돌:

  • 노력 vs. 안정성: 로컬 ID는 생성이 쉽지만, 글로벌 고유성을 보장하기 어려울 수 있습니다. 반면, 글로벌 ID는 관리가 복잡하지만 안정적이다.
  • 가독성 vs. 보안: 사람이 읽기 쉬운 ID는 보안에 취약할 수 있으며, 무작위화된 ID는 보안은 좋지만 가독성이 떨어질 수 있다.
  • 구조화 vs. 간결성: 데이터베이스 키와 같은 구조화된 ID는 효율적이지만, 관리의 복잡성을 초래할 수 있다.

 

4. 링크 엘리먼트 (Link Element)

설명:

링크 엘리먼트는 메시지 내에서 데이터 요소 간의 관계를 명확히 하여, 클라이언트가 필요한 데이터를 찾고 추가 요청을 수행할 수 있게 합니다. 하이퍼미디어 컨트롤의 일환으로 사용된다. REST API에서 중요한 하이퍼미디어 제어 요소로, 다음 작업 단계나 관련 데이터 리소스를 탐색할 수 있게 한다.

 

주요 특징:

  • 데이터 요소 간의 명확한 관계를 정의하고, 클라이언트가 추가 요청을 수행할 수 있게 함.
  • 하이퍼미디어 패턴을 통해 클라이언트가 더 적은 정보로도 효율적으로 작업을 수행할 수 있게 함.
  • URI, URL 등을 사용해 명확한 데이터 참조를 제공.

 

포스 충돌:

  • 유연성 vs. 복잡성: 클라이언트가 다양한 경로를 탐색할 수 있게 하면 유연성이 높아지지만, 그만큼 메시지의 복잡성도 증가한다.
  • 명확성 vs. 성능: 링크를 사용하면 명확하게 데이터 간 관계를 표현할 수 있지만, 많은 링크는 페이로드 크기를 키워 성능 저하를 초래할 수 있다.
  • 보안 vs. 접근성: 링크를 통해 제공하는 데이터는 보안이 중요하지만, 쉽게 접근할 수 있게 하려다 보면 보안 취약점이 발생할 수 있다.

참고 문헌
[1]  올라프 짐머만 , 미르코 스토커 , 다니엘 뤼브케 , 우베 즈둔 , 세자레 파우타소 , "마이크로서비스 API 디자인 패턴: 쉬운 통합을 위한 결합도 최적화 전략" 에이콘. 이승범 역

+ Recent posts