← 목록으로
SW공학·관리
#아키텍처스타일#디자인패턴#GoF#MSA#131회
최종 업데이트 · 2026-09-27

아키텍처 스타일과 디자인 패턴

1. 개요

가. 정의

아키텍처 스타일(Architecture Style) 은 시스템 전체 구조를 조직하는 거시적(Macro) 설계 틀이고, 디자인 패턴(Design Pattern) 은 특정 설계 문제를 반복적으로 해결하는 미시적(Micro)·재사용 가능한 해법이다. 전자는 컴포넌트의 배치와 연결·품질속성을 규정하고, 후자는 클래스·객체 수준의 생성·구조·행위를 규정한다.

두 개념의 관계는 '건물의 구조 양식'과 '방을 꾸미는 정형화된 기법'에 비유하면 명확해진다. 아키텍처 스타일이 아파트냐 단독주택이냐 하는 건물 전체의 골격(계층형·MSA·이벤트기반 등)을 정한다면, 디자인 패턴은 그 건물 안에서 반복적으로 마주치는 국소 문제—예를 들어 '어떻게 하면 특정 객체를 하나만 만들어 공유할까'—를 검증된 방식으로 푸는 해법이다. 건물의 양식을 바꾸는 것은 기초 공사부터 다시 하는 일에 가깝지만, 방 안의 가구 배치 기법을 바꾸는 것은 상대적으로 국소적이고 되돌리기 쉽다.

둘의 본질적 차이는 추상화 수준(Abstraction Level)과 영향 범위(Scope of Impact) 에 있다. 아키텍처 스타일의 선택은 성능·확장성·가용성·보안 같은 시스템 전체의 품질속성(Quality Attribute)을 좌우하는, 되돌리기 어려운(irreversible) 결정이다. 반면 디자인 패턴은 특정 클래스·컴포넌트 수준의 유연성·재사용성을 다루므로 리팩터링으로 비교적 쉽게 교체할 수 있다. 마틴 파울러(Martin Fowler)가 "아키텍처란 되돌리기 어려운 결정들의 집합"이라 표현한 것도 이 맥락이다.

나. 등장 배경과 필요성

소프트웨어가 커지고 복잡해질수록, 매번 처음부터 구조를 고민하면 비효율적이고 실패 위험이 크다. 1960년대 후반 이른바 '소프트웨어 위기(Software Crisis)' 이후, 검증된 구조적 해법을 재사용하려는 노력이 축적되었다. 아키텍처 스타일은 데이비드 갈란(David Garlan)과 메리 쇼(Mary Shaw)가 1990년대에 체계화했고, 디자인 패턴은 1994년 GoF(Gang of Four)의 저서 Design Patterns: Elements of Reusable Object-Oriented Software 로 23개 패턴이 정형화되었다.

이 두 도구가 필요한 이유는 세 가지로 정리된다. 첫째, 재사용성—선배 개발자들이 시행착오로 검증한 해법을 재사용해 바퀴를 다시 발명하지 않는다. 둘째, 의사소통—"이 부분은 옵서버 패턴", "전체는 MSA"라는 공통 어휘(Vocabulary)로 설계 의도를 압축해 전달한다. 셋째, 품질 예측 가능성—검증된 구조는 어떤 품질속성을 얻고 무엇을 희생하는지 알려져 있어, 트레이드오프를 미리 판단할 수 있다.

2. 아키텍처 스타일과 디자인 패턴의 전체 구도

두 개념은 하나의 시스템 안에서 서로 다른 층위를 담당한다. 아래 개념도는 거시(스타일)와 미시(패턴)가 어떻게 계층적으로 함께 작동하는지를 보여준다.

flowchart TB
  subgraph MACRO["거시 · 시스템 전체(Architecture Style)"]
    L["계층형(Layered)"]
    M["마이크로서비스(MSA)"]
    E["이벤트 기반(Event-driven)"]
  end
  subgraph MICRO["미시 · 컴포넌트 내부(Design Pattern)"]
    C["생성(Creational)"]
    ST["구조(Structural)"]
    B["행위(Behavioral)"]
  end
  MACRO -->|"구조 골격을 정한 뒤 내부를 채움"| MICRO
  QA["품질속성(성능·확장·보안)"] --- MACRO
  RU["코드 재사용·유연성"] --- MICRO
  style MACRO fill:#e8f0fe,stroke:#2f6fed,stroke-width:2px
  style MICRO fill:#fef3e8,stroke:#ed8a2f,stroke-width:2px

위 그림에서 강조되는 점은 두 층위가 경쟁이 아니라 보완 관계라는 것이다. 아키텍처 스타일이 시스템의 뼈대와 컴포넌트 경계를 정하면, 각 컴포넌트 내부는 디자인 패턴으로 구현된다. 예컨대 MSA에서 각 마이크로서비스 내부의 결제 모듈은 전략(Strategy) 패턴으로 결제수단을 교체하고, 팩토리(Factory) 패턴으로 결제 객체를 생성하며, 옵서버(Observer) 패턴으로 결제 완료 이벤트를 통지할 수 있다.

두 개념의 차이를 실무 관점에서 정리하면 다음과 같다. 표는 비교를 돕는 보조 수단이며, 핵심은 '왜 그 차이가 생기는가'다. 범위가 다르기 때문에 변경의 파급 효과가 다르고, 변경 파급이 다르기 때문에 되돌리기 난이도가 달라진다.

구분 아키텍처 스타일 디자인 패턴
범위 시스템 전체(거시) 클래스·컴포넌트(미시)
관심사 구조·컴포넌트·연결·품질속성 객체 생성·구조·행위
영향 성능·확장·보안(되돌리기 어려움) 코드 재사용·유연성(교체 용이)
대표 산출물 아키텍처 명세서·C4 다이어그램 클래스 다이어그램·UML
예 계층형, MSA, 이벤트기반, 파이프-필터 싱글턴, 팩토리, 옵서버, 전략

3. 대표적인 아키텍처 스타일

아키텍처 스타일은 문제 영역과 품질 요구에 따라 선택된다. 여기서는 실무에서 가장 자주 쓰이는 세 가지—계층형, 마이크로서비스, 이벤트 기반—를 원리와 트레이드오프까지 상세히 다룬다.

flowchart TB
  S["아키텍처 스타일 선택"] --> L["계층형(Layered)<br/>단순·보편"]
  S --> M["마이크로서비스(MSA)<br/>확장·자율"]
  S --> E["이벤트 기반(Event-driven)<br/>실시간·비동기"]
  L --> LT["트레이드오프: 관통 변경 취약"]
  M --> MT["트레이드오프: 분산 복잡성"]
  E --> ET["트레이드오프: 흐름 추적 곤란"]
  style S fill:#e8f0fe,stroke:#2f6fed,stroke-width:2px

가. 계층형(Layered) 아키텍처

계층형은 시스템을 표현(Presentation)·비즈니스(Business)·데이터(Data Access) 계층으로 수평 분리해 관심사를 나누는, 가장 보편적이고 이해하기 쉬운 스타일이다. 각 계층은 바로 아래 계층에만 의존하는 단방향 흐름을 원칙으로 하며, 이 규칙 덕분에 특정 계층의 내부 변경이 다른 계층으로 전파되지 않는다. 예컨대 데이터 접근 기술을 MyBatis에서 JPA로 바꿔도 비즈니스 계층은 인터페이스만 유지하면 영향을 받지 않는다.

이 스타일의 강점은 낮은 학습 비용과 명확한 책임 분리다. 대부분의 엔터프라이즈 웹 애플리케이션(전통적 Spring MVC 3-tier 구조)이 이 방식을 채택하는 이유가 여기 있다. 그러나 한계도 분명하다. 하나의 요구사항 변경이 표현·비즈니스·데이터 계층을 모두 관통(sinkhole)하는 경우—예를 들어 필드 하나를 추가하려면 화면·서비스·DTO·엔터티·테이블을 모두 고쳐야 하는 상황—이 잦아지면 계층 분리의 이점이 무색해진다. 또한 모든 요청이 계층을 순차 통과하므로 트래픽이 폭증하는 대규모 서비스에서는 수평 확장(scale-out)의 단위가 애플리케이션 전체가 되어 비효율적이다.

실무적으로는 도메인 규칙이 단순하고 수명이 예측되는 사내 관리 시스템, 초기 스타트업의 MVP처럼 빠른 개발이 중요한 곳에 적합하다. 반대로 트래픽과 도메인 복잡도가 함께 커지는 대형 커머스에서는 계층형만으로 버티기 어려워 MSA로 진화하는 경우가 많다.

나. 마이크로서비스(MSA) 아키텍처

마이크로서비스는 시스템을 독립적으로 배포 가능한 작은 서비스들로 분해하는 스타일이다. 각 서비스는 자체 데이터베이스를 소유(Database per Service)하고, 서비스 간에는 REST·gRPC·메시지로 통신한다. 넷플릭스(Netflix)는 2009년부터 약 7년에 걸쳐 모놀리스를 700개 이상의 마이크로서비스로 전환해 초당 수백만 요청을 처리하는 대표 사례이며, 아마존·우버·쿠팡 등도 유사한 경로를 밟았다.

MSA의 핵심 이점은 세 가지다. 첫째 독립 배포—결제 서비스만 하루에도 수십 번 배포할 수 있어 배포 위험이 격리된다. 둘째 서비스별 확장—트래픽이 몰리는 상품조회 서비스만 인스턴스를 늘려 자원을 효율적으로 쓴다. 셋째 장애 격리(Fault Isolation)—추천 서비스가 죽어도 주문 서비스는 계속 동작하도록 서킷 브레이커로 차단할 수 있다.

그러나 이 이점의 대가는 분산 시스템의 본질적 복잡성이다. 네트워크는 신뢰할 수 없고(지연·단절), 여러 서비스에 걸친 데이터 일관성은 분산 트랜잭션 대신 사가(Saga)·최종 일관성(Eventual Consistency)으로 풀어야 하며, 로그·추적·모니터링을 위한 관측성(Observability) 인프라와 서비스 메시(Service Mesh)가 추가로 필요하다. 즉 개발 복잡도가 운영 복잡도로 전이된다. 마틴 파울러가 "MSA를 감당하려면 최소한의 성숙도(배포 자동화·모니터링·장애 대응)를 먼저 갖춰야 한다"고 경고한 이유다.

아래는 사용자의 주문 요청이 MSA 환경에서 처리되는 흐름의 세부도다.

sequenceDiagram
    participant U as 사용자
    participant G as API 게이트웨이
    participant O as 주문 서비스
    participant P as 결제 서비스
    participant I as 재고 서비스
    participant Q as 메시지 브로커
    U->>G: 주문 요청
    G->>O: 라우팅
    O->>P: 결제 승인 요청
    P-->>O: 승인 완료
    O->>Q: 주문생성 이벤트 발행
    Q->>I: 재고 차감 구독
    I-->>Q: 재고 확정 이벤트
    O-->>U: 주문 접수 응답

다. 이벤트 기반(Event-driven) 아키텍처

이벤트 기반은 컴포넌트가 상태 변화를 '이벤트'로 발행(Publish)하고, 관심 있는 컴포넌트가 이를 구독(Subscribe)해 반응하는 스타일이다. 발행자와 구독자가 서로를 직접 알지 못하므로 느슨한 결합(Loose Coupling) 이 극대화되고, 비동기 처리로 실시간성과 확장성을 얻는다. 카프카(Apache Kafka)를 중심으로 한 이벤트 스트리밍이 대표 구현이며, 실시간 추천·IoT 센서 처리·금융 거래 감사 로그처럼 초당 수십만 건의 이벤트를 다루는 곳에서 위력을 발휘한다.

이 스타일의 강점은 확장성과 진화 가능성이다. 새로운 구독자(예: 마케팅 분석 서비스)를 추가해도 발행자 코드를 수정할 필요가 없어 시스템을 점진적으로 확장할 수 있다. 반면 흐름이 여러 이벤트를 거쳐 비동기로 퍼지므로 전체 처리 흐름을 한눈에 추적·디버깅하기 어렵고, 이벤트 순서 보장·중복 처리(멱등성)·최종 일관성을 별도로 설계해야 한다. 장애 시 "어디까지 처리되었는가"를 파악하기 위해 분산 추적(Distributed Tracing)이 필수가 된다.

세 스타일의 트레이드오프를 비교하면, 선택 기준은 결국 요구되는 품질속성에 있다. 단순함이 우선이면 계층형, 독립 확장·자율 개발이 우선이면 MSA, 실시간·느슨한 결합이 우선이면 이벤트 기반이다.

스타일 핵심 강점 트레이드오프 대표 적용
계층형 단순·명확한 책임 분리 관통 변경 취약, 확장 단위가 전체 사내 관리시스템, MVP
마이크로서비스 독립 배포·확장·장애 격리 분산 복잡성·운영 부담 넷플릭스, 대형 커머스
이벤트 기반 느슨한 결합, 실시간·비동기 흐름 추적·순서·중복 처리 곤란 실시간 추천, IoT, 금융

4. GoF 디자인 패턴

GoF 디자인 패턴은 목적에 따라 세 유형으로 나뉜다. 생성(Creational) 패턴은 객체를 어떻게 생성할지를 캡슐화해 생성 로직과 사용 로직을 분리하고, 구조(Structural) 패턴은 객체·클래스를 어떻게 조합해 더 큰 구조를 만들지를 다루며, 행위(Behavioral) 패턴은 객체 간 책임 분배와 상호작용·통신을 다룬다. 이 분류의 밑바탕에는 "변하는 것을 변하지 않는 것으로부터 분리하라"는 캡슐화 원칙과 SOLID 설계 원칙이 깔려 있다.

flowchart TB
  G["GoF 23개 패턴"] --> CR["생성(5)<br/>객체 생성 캡슐화"]
  G --> STR["구조(7)<br/>객체·클래스 조합"]
  G --> BEH["행위(11)<br/>책임 분배·상호작용"]
  CR --> C1["싱글턴·팩토리메서드<br/>추상팩토리·빌더·프로토타입"]
  STR --> S1["어댑터·데코레이터·프록시<br/>퍼사드·컴포지트·브리지·플라이웨이트"]
  BEH --> B1["옵서버·전략·커맨드·상태<br/>반복자·템플릿메서드·책임연쇄"]
  style G fill:#fef3e8,stroke:#ed8a2f,stroke-width:2px

가. 생성 패턴(Creational)

생성 패턴의 핵심 동기는 '객체를 생성하는 방식이 바뀔 때, 그 객체를 사용하는 코드가 흔들리지 않게 하는 것'이다. 싱글턴(Singleton) 은 인스턴스를 하나만 생성·공유해 설정·로그·커넥션 풀처럼 전역적으로 하나만 필요한 자원에 쓴다. 다만 전역 상태를 만들어 테스트를 어렵게 하고 멀티스레드 환경에서 동기화 비용이 생기므로, 현대에는 DI 컨테이너(Spring의 Bean 스코프)가 싱글턴 관리를 대신하는 경우가 많다.

팩토리 메서드(Factory Method) 는 객체 생성을 서브클래스에 위임해 클라이언트와 구체 클래스 간 결합도를 낮춘다. 새로운 타입이 추가되어도 클라이언트 코드를 고치지 않고 팩토리만 확장하면 되므로 개방-폐쇄 원칙(OCP)을 지원한다. 빌더(Builder) 는 생성자 인자가 많고 선택적일 때, 단계적으로 객체를 조립해 가독성과 불변성을 높인다(예: 자바의 StringBuilder, 다양한 SDK의 Builder API).

나. 구조 패턴(Structural)

구조 패턴은 이미 존재하는 클래스·객체를 조합해 새로운 기능이나 인터페이스를 만들되, 기존 코드를 수정하지 않는 데 초점을 둔다. 어댑터(Adapter) 는 호환되지 않는 인터페이스를 변환해 연결한다—레거시 시스템이나 외부 라이브러리를 새 코드에 맞출 때 필수적이며, 헥사고날 아키텍처의 '어댑터' 개념과 직결된다. 데코레이터(Decorator) 는 상속 대신 조합으로 객체에 기능을 동적으로 덧입힌다(예: 자바 I/O 스트림의 BufferedReader(new FileReader(...))). 프록시(Proxy) 는 실제 객체에 대한 접근을 대리 객체가 제어해 지연 로딩·접근 제어·캐싱·원격 호출을 투명하게 처리한다(예: JPA의 지연 로딩 프록시, RPC 스텁).

다. 행위 패턴(Behavioral)

행위 패턴은 객체 간 책임을 어떻게 나누고 어떻게 소통시킬지를 다룬다. 옵서버(Observer) 는 한 객체(Subject)의 상태 변화를 구독자들에게 자동 통지해 발행-구독을 코드 수준에서 구현하며, MVC의 모델-뷰 갱신과 이벤트 리스너의 기반이 된다. 흥미롭게도 옵서버 패턴은 앞서 본 이벤트 기반 아키텍처의 미시 버전으로 볼 수 있어, 스타일과 패턴이 같은 원리의 다른 스케일임을 보여준다. 전략(Strategy) 은 알고리즘군을 각각 캡슐화해 런타임에 교체할 수 있게 한다—결제수단(카드·계좌·간편결제)이나 정렬·할인 정책처럼 '무엇을 할지는 같은데 방식이 다른' 경우에 쓰인다. 커맨드(Command) 는 요청을 객체로 캡슐화해 실행·취소(Undo)·큐잉·로깅을 가능하게 한다.

유형 목적 대표 패턴 실무 예
생성 객체 생성 캡슐화 싱글턴, 팩토리메서드, 빌더 DI 컨테이너, SDK Builder
구조 객체·클래스 조합 어댑터, 데코레이터, 프록시 I/O 스트림, JPA 지연로딩
행위 책임 분배·상호작용 옵서버, 전략, 커맨드 MVC, 결제전략, Undo

5. 심화: 클라우드 네이티브 시대의 분산 아키텍처 패턴

전통 GoF 패턴이 단일 프로세스 내 객체 수준의 문제를 다룬다면, MSA·클라우드 네이티브 환경은 '프로세스와 네트워크를 넘나드는' 새로운 부류의 패턴을 요구한다. 이는 GoF를 대체하는 것이 아니라, 더 높은 스케일에서 보완하는 것이다.

첫째, 서킷 브레이커(Circuit Breaker) 는 넷플릭스 Hystrix(현재는 Resilience4j)로 대중화된 패턴으로, 하위 서비스의 연쇄 장애(Cascading Failure)를 막는다. 호출 실패율이 임계치를 넘으면 회로를 '열어(Open)' 즉시 실패 응답을 반환하고, 일정 시간 뒤 '반개방(Half-Open)'으로 시험 호출을 보내 복구를 확인한다. 이는 장애가 시스템 전체로 번지는 것을 물리적으로 차단한다.

둘째, 사가(Saga) 는 MSA에서 분산 트랜잭션을 대체하는 패턴이다. 여러 서비스에 걸친 업무를 로컬 트랜잭션의 연쇄로 나누고, 중간에 실패하면 이미 수행한 단계를 되돌리는 보상 트랜잭션(Compensating Transaction) 을 실행한다. 오케스트레이션(중앙 조정자) 방식과 코레오그래피(이벤트 연쇄) 방식이 있으며, 주문-결제-배송처럼 여러 서비스를 거치는 업무에서 최종 일관성을 보장한다.

셋째, API 게이트웨이(API Gateway) 와 BFF(Backend for Frontend) 는 클라이언트와 다수 마이크로서비스 사이에서 인증·라우팅·집계·속도 제한을 단일 진입점에서 처리한다. 넷째, CQRS·이벤트 소싱(Event Sourcing) 은 명령(쓰기)과 조회(읽기) 모델을 분리하고 상태를 이벤트의 누적으로 저장해, 읽기 확장과 완전한 감사 추적을 제공한다.

기출 연계 관점에서, 정보관리기술사 시험은 아키텍처 스타일(계층형·MSA·이벤트기반)과 GoF 분류, 그리고 최근에는 MSA 전환 전략·서킷브레이커·사가를 단독 또는 사례형으로 출제해 왔다. 따라서 답안은 "스타일과 패턴의 차이 → 대표 스타일의 트레이드오프 → GoF 3분류 → 클라우드 네이티브 패턴으로의 확장"이라는 계층적 구성으로 전개하면 깊이와 최신성을 동시에 보일 수 있다.

6. 고려사항 및 시사점

  1. 아키텍처 스타일로 품질속성을, 디자인 패턴으로 코드 유연성을 확보한다. 두 층위는 목적과 영향 범위가 다르므로 경쟁이 아니라 상호 보완적으로 적용해야 한다. 스타일 결정을 미룬 채 패턴만 쌓으면 국소 최적화에 그치고, 패턴 없이 스타일만 정하면 구현 단계에서 결합도가 높아진다.

  2. 패턴 남용은 과설계(Over-engineering)다. 문제가 없는데 '패턴을 위한 패턴'을 적용하면 복잡도만 늘린다. YAGNI(You Aren't Gonna Need It) 원칙에 따라 실제로 변화가 예상되는 지점에만 절제해 적용하고, 변경 이유(변경의 축)가 실재하는지를 먼저 검증한다.

  3. 아키텍처는 되돌리기 어려운 결정이므로 트레이드오프를 명시적으로 판단한다. MSA는 조직의 배포 자동화·모니터링·장애 대응 성숙도가 전제되어야 하며, 성숙도 없이 도입하면 '분산 모놀리스(Distributed Monolith)'라는 최악의 결과를 낳는다. 콘웨이의 법칙(Conway's Law)처럼 조직 구조와 아키텍처의 정합성도 함께 고려한다.

  4. 클라우드 네이티브·MSA 시대에는 전통 GoF를 보완하는 분산 패턴이 필수다. 서킷브레이커·사가·CQRS·이벤트 소싱 등을 이해하고, 관측성(로그·메트릭·추적)·서비스 메시(Istio 등)·컨테이너 오케스트레이션(Kubernetes)과 결합해 운영 관점까지 설계에 포함해야 한다.

  5. 기술사 관점의 전략적 선택. 스타일·패턴은 은탄환(Silver Bullet)이 아니며, 비즈니스 요구·팀 역량·예상 수명·트래픽 특성을 종합해 선택한다. 초기에는 모놀리스로 단순하게 시작하고 필요가 명확해질 때 점진적으로 MSA·이벤트 기반으로 진화(Strangler Fig 패턴)하는 것이 위험을 낮추는 실용적 전략이다.

참고자료


한 줄 요약: 아키텍처 스타일(계층형·MSA·이벤트기반)은 시스템 전체 구조와 품질속성을 결정하는 거시적·되돌리기 어려운 틀이고, GoF 디자인 패턴(생성·구조·행위)은 반복되는 설계 문제의 미시적 해법이며, 클라우드 네이티브 시대에는 서킷브레이커·사가 등 분산 패턴이 이를 보완하므로 트레이드오프를 명시적으로 판단해 절제하며 상호 보완적으로 적용해야 한다.