소프트웨어 아키텍처란?

소프트웨어 아키텍처는 쉽게 말하면,
**'소프트웨어를 만드는 설계도이자 구조'**입니다.

비유를 들어볼게요.


건물을 지을 때 만드려는 집의 모양을 그리고, 기둥을 세우고, 벽돌을 쌓는 방식으로는 작은 집은 만들 수 있습니다.

그렇지만, 복잡한 건물이나, 고층 건물은 이렇게 단순한 지식만으로 만들 수 없죠.

 

고층 건물을 만들려면 건물의 구조 설계, 공간 설계(업무 공간, 생활 공간, 휴식/편의/문화 공간, 주차 공간, 관리 공간 등), 유동량에 따른 도로 설계, 전기/수도 등 설비, 각 설계에 맞는 적합한 자재 선정, 
건물을 가장 효율적으로 지어 올리기 위한 일정관리(작업 일정에 맞춘 자재 납품, 인력, 장비),

건물이 완성된 이후 인테리어, 유지보수 설계(점검/교체 주기) 

 


건축가(아키텍트)설계도를 만든다는 개념은 대부분 쉽게 이해합니다.

S/W 아키텍처는 건축의 아키텍처에서 유래했습니다. 


S/W 아키텍처를 설계하는 것은 건물 설계만큼이나 전문지식과 경험이 필요하고, 전문성이 있는 건축가로부터 멋진 건축물이 만들어지는 것처럼 S/W 아키텍트의 전문성(역량)에 따라 대량의 서비스가 문제없이 원활하게 서비스되면서도, 사용하기 편리하고, 확정성, 유지보수성까지 뛰어난 S/W가 될수도 있고,

성능도 느리고, 장애도 많고, 확장도 어렵고, 사용하기 불편하고, UX도 촌스럽고, 유지보수성도 떨어지는 하자가 많은 S/W가 만들어 질수도 있습니다.

 

 

S/W 개발은 단순히 개발 언어를 이용해서 코딩을 하는 것이 아니라,

 

클라이언트(S/W 개발을 요청한 고객 - 건축주와 같은 개념)의 요구사항에 맞는 S/W를 설계하고, 개발해 나가는 과정은  요구사항에 맞춰, 전체 구조를 설계하고, 각 구조 영역에 세부 설계를 하고, 각 세부설계에 적합한 기술(Tools)을 선정하고, 각 기술을 보유한 개발자를 일정에 맞춰 투입해서 완성해 나가는 광대한 지식과 경험이 필요한 분야 입니다.

 
이 과정을 우리는 **'아키텍처를 설계한다'**라고 부릅니다.

아키텍처가 중요한 이유는 이렇습니다.

  • 처음에 잘못 설계하면: 건물처럼, 나중에 문제가 생겼을 때 고치는 데 막대한 비용과 시간이 듭니다.
  • 처음에 잘 설계하면: 소프트웨어가 쉽게 확장되고, 문제가 생겨도 빠르게 대응할 수 있습니다.

특히,  사업 환경이 빠르게 변하는 S/W를 개발해야 하는 경우라면
**"변화에 잘 대응할 수 있도록 유연하고 견고하게 만드는 것"**이 정말 중요합니다.
그 중심에 바로 이 소프트웨어 아키텍처가 있습니다.

 

정리하면,
소프트웨어 아키텍처는 소프트웨어라는 건물을 튼튼하고, 안전하고, 오랫동안 쓰기 좋게 만드는 설계와 구조라고 이해하시면 됩니다.

 

 

소프트웨어 아키텍처 세부 구성과 필요 전문 지식

시스템 아키텍처 (System Architecture)

소프트웨어 전체 시스템의 큰 구조를 설계하는 것

  • 전문 지식
    • 모놀리식 vs 마이크로서비스(MSA) 구조 이해
    • 계층형 아키텍처 (Layered Architecture) 설계
    • 이벤트 기반 아키텍처 (Event-driven Architecture) 설계
  • 필요 기술
    • 클라우드 네이티브 설계(AWS, Azure, GCP)
    • 컨테이너 오케스트레이션 (Docker, Kubernetes)
    • API Gateway 및 메시지 브로커 (Kafka, RabbitMQ)

데이터 아키텍처 (Data Architecture)

데이터의 흐름, 저장, 관리 방법을 설계하는 것

  • 전문 지식
    • 데이터베이스 설계
      • 관계형 데이터베이스(RDBMS) : MySQL, Oracle, MS-SQL 등
      • 비관계형 데이터베이스(NoSQL) : Redis, MongoDB
    • 데이터 모델링 (ERD 설계)
    • 데이터 통합 및 파이프라인 설계
  • 필요 기술
    • MySQL, PostgreSQL, MongoDB, Redis
    • 데이터 웨어하우스 (BigQuery, Redshift)
    • 도메인 설계 기술
    • DB 튜닝(Index, Hint, Join의 이해, 반정규화)
    • 캐싱
    • 정적 콘텐츠 호스팅
    • 검색 엔진

애플리케이션 아키텍처 (Application Architecture)

소프트웨어 기능을 어떻게 구성하고 연결할지 설계하는 것

  • 전문 지식
    • 디자인 패턴
    • OOP
    • 도메인 주도 설계(DDD)
    • MVC, MVVM, Clean Architecture
    • Refactoring
    • TDD
    • 서비스 분리 및 인터페이스 설계
  • 필요 기술
    • OOP, DDD, TDD, Refactoring 등
    • Spring Boot, .NET Core, Django
    • GraphQL, REST API 설계
    • 기타 : OAuth2, JWT 인증 방식 ...

인프라 아키텍처 (Infrastructure Architecture)

소프트웨어가 구동될 하드웨어, 네트워크를 설계하는 것

  • 전문 지식
    • 서버 및 스토리지 구성
    • 네트워크 구성 (VPC, VPN, Load Balancer)
    • 모니터링과 로깅 전략
  • 필요 기술
    • Cloud 설계 / 관리 기술
    • Terraform, Ansible (IaC: Infrastructure as Code)
    • Prometheus, Grafana, ELK Stack
    • CDN, WAF 설정

보안 아키텍처 (Security Architecture)

시스템과 데이터의 보안을 설계하는 것

  • 전문 지식
    • 암호화, 인증, 권한 부여 설계
    • 보안 취약점 분석 및 대응
    • SSL 
    • 인증서 운영 기술
    • 개인정보보호법, GDPR 등 규제 준수
  • 필요 기술
    • HTTPS, TLS/SSL, OAuth2
    • WAF, IAM (Identity Access Management)
    • 보안 스캐너 (OWASP ZAP, SonarQube)

운영/배포 아키텍처 (DevOps Architecture)

소프트웨어를 어떻게 빠르고 안정적으로 운영하고 배포할지 설계하는 것

  • 전문 지식
    • CI/CD 파이프라인 설계
    • 블루그린 배포, 롤링 업데이트 전략
    • 무중단 배포, 장애 복구 전략
    • 서비스 모니터링, H/W 성능 모니터링
    • 장애 감지 / 통보
    • S/W, H/W 장애 대응 전략
    • 장애 대응 훈련 및 장애 대응 전략 업데이트
  • 필요 기술
    • Jenkins, GitHub Actions, GitLab CI
    • Docker, Kubernetes (Helm 포함)
    • Canary Release, Feature Toggle

📋 표로 정리

세부 항목주요 전문 지식필요 기술
시스템 아키텍처 MSA, 계층형 설계, 이벤트 기반 설계 AWS, Docker, Kubernetes, Kafka
데이터 아키텍처 데이터베이스 설계, 데이터 모델링, 파이프라인 설계 MySQL, MongoDB, BigQuery, Airflow
애플리케이션 아키텍처 디자인 패턴, DDD, 인터페이스 설계 Spring Boot, REST API, GraphQL, OAuth2
인프라 아키텍처 서버/네트워크 구성, 모니터링 전략 Terraform, Prometheus, ELK Stack, CDN
보안 아키텍처 암호화/인증/권한, 규제 준수 TLS, OAuth2, WAF, IAM, OWASP ZAP
운영/배포 아키텍처 CI/CD, 무중단 배포, 장애 복구 Jenkins, GitHub Actions, Kubernetes, Canary Release

 

 

요약

소프트웨어 아키텍처는 단순히 구조를 짜는 것이 아니라,
시스템, 데이터, 애플리케이션, 인프라, 보안, 운영
이 여섯 가지 관점에서 각각 깊은 전문성과 기술적 선택이 필요한 일이며, 
S/W 아키텍처는 위의 모든 항목에 대해 전문지식과 경험을 가지고 있어야 합니다. 

 

'프로그래밍 > 아키텍처_DDD' 카테고리의 다른 글

표현 영역과 응용 영역  (0) 2024.11.29
DDD 용어 개념 정리  (0) 2024.10.22
왜 지금 도메인 주도 설계가 필요한가?  (0) 2024.10.18
DDD - 이벤트 명명 규칙  (3) 2024.09.30

테스트 주도 개발(Test Driven Development, TDD)에서 "이벤트 명칭"은 테스트를 작성할 때, 특히 이벤트 주도 시스템에서 이벤트를 정의하고 명명하는 방법과 관련이 있습니다. 이벤트 명칭 규칙은 주로 코드의 가독성을 높이고 이벤트가 시스템에서 수행하는 역할을 명확하게 표현하기 위한 표준입니다. 명명 규칙은 일관성을 유지하면서 테스트 및 실제 코드에서 사용하는 이벤트의 명확한 의미를 부여하는 데 중요한 역할을 합니다. 이러한 표준화는 테스트를 더 명확하게 만들고 시스템의 의도를 파악하는 데 도움을 줍니다.

다음은 TDD에서 이벤트 명칭을 만들 때 고려해야 할 표준 규칙들입니다.

1. 이벤트 명칭은 도메인 용어를 반영해야 함

이벤트는 시스템에서 중요한 비즈니스 또는 도메인 관점의 행동이나 상태 변화를 표현해야 합니다. 이벤트 명칭은 도메인 주도 설계(DDD)의 원칙과 유사하게 도메인 용어를 기반으로 하여, 이벤트의 의도가 명확하게 드러나야 합니다.

  • 예시:
    • OrderPlaced (주문이 완료된 경우)
    • PaymentProcessed (결제가 처리된 경우)
    • UserRegistered (사용자가 등록된 경우)

이처럼 이벤트 명칭은 구체적이고 직관적으로 그 행동이 무엇인지를 표현해야 합니다. 이는 테스트에서도 명확한 목적을 전달하는 데 도움이 됩니다.

2. 이벤트는 과거 시제로 명명

이벤트는 발생한 사건이나 행동을 나타내므로, 일반적으로 과거 시제로 명명합니다. 이는 이벤트가 이미 발생한 사실을 의미하기 때문에 자연스럽습니다.

  • 예시:
    • OrderPlaced
    • ProductShipped
    • UserLoggedIn

이러한 과거 시제를 사용함으로써, 이벤트가 특정 상태 변화를 나타내는지 알 수 있으며, 테스트 작성 시에도 자연스럽게 이해할 수 있습니다.

3. 이벤트는 명사 + 동사의 조합으로 명확하게 표현

이벤트 명칭은 일반적으로 명사와 동사의 조합으로 구성됩니다. 이를 통해 어떤 객체어떤 동작을 수행했는지를 명확하게 표현할 수 있습니다. 이러한 명명 규칙은 읽기 쉽고 코드에서 무슨 일이 일어나고 있는지를 쉽게 알 수 있게 만듭니다.

  • 예시:
    • CustomerSubscribed (고객이 구독함)
    • InvoiceGenerated (청구서가 생성됨)
    • SessionExpired (세션이 만료됨)

4. 도메인 내 특정 이벤트를 명확하게 구분

시스템 내 여러 이벤트가 존재할 경우, 비슷한 행동을 나타내는 이벤트라도 차별성을 두어야 합니다. 이를 통해 이벤트를 통해 발생하는 구체적인 상태 변화를 구분할 수 있습니다.

  • 예시:
    • OrderShipped vs. OrderDelivered (출고와 배송 완료는 다른 상태이므로 명칭을 구분해야 함)
    • UserLoggedIn vs. UserLoggedOut (로그인과 로그아웃은 반대 동작이므로 명확하게 구분)

5. 이벤트가 트리거 되는 조건을 명확히 표현

이벤트는 주로 어떤 상태 변화나 조건에 의해 트리거되므로, 그 조건이나 이유를 명확히 반영해야 합니다. 이벤트 명칭만으로도 왜 이 이벤트가 발생했는지 명확해야 합니다.

  • 예시:
    • PaymentFailed (결제 실패)
    • OrderCanceled (주문 취소됨)

이러한 명명 방식은 테스트에서 어떤 조건에서 이 이벤트가 발생하는지를 알기 쉽게 만듭니다.

6. 이벤트가 발생하는 주체를 명확히 표시

이벤트는 주로 도메인 객체의 상태 변화를 반영하므로, 이벤트의 주체가 되는 도메인 객체를 명칭에 포함하는 것이 일반적입니다. 이는 테스트 시 어떤 객체가 이벤트의 대상이 되는지를 쉽게 파악할 수 있게 합니다.

  • 예시:
    • OrderPlaced (주문이 완료됨 - Order 객체가 주체)
    • PaymentAuthorized (결제가 승인됨 - Payment 객체가 주체)

7. 이벤트 명칭은 짧고 간결하게 유지

이벤트 이름은 지나치게 길거나 복잡하게 만들지 않고, 핵심 정보를 반영하는 단어들로 간결하게 작성해야 합니다. 이벤트 명칭이 지나치게 길어지면 코드 가독성이 떨어질 수 있기 때문에 적절히 줄이는 것이 중요합니다.

  • 예시:
    • OrderPlacedSuccessfully 대신 OrderPlaced로 명명 (성공 여부는 이벤트의 의미상 이미 내포됨)

8. 일관성 있는 명명 규칙 유지

시스템 전반에 걸쳐 이벤트 명칭 규칙은 일관되게 적용해야 합니다. 일부 이벤트에서만 과거 시제를 사용하거나, 특정 부분에서만 명사-동사 구조를 사용하는 등의 비일관성을 피하는 것이 중요합니다. 이는 코드의 유지보수성을 높이는 데 큰 도움이 됩니다.

9. 테스트 명칭과 이벤트 명칭의 연관성 유지

TDD(Test Driven Development)에서는 이벤트와 관련된 테스트 시나리오를 작성할 때, 이벤트 명칭과 테스트 명칭 간의 연관성을 유지하는 것이 매우 중요합니다. 이를 통해 테스트 코드만 보더라도 해당 테스트가 어떤 이벤트를 다루는지 쉽게 파악할 수 있고, 테스트 목적이 분명해집니다.

테스트 명칭 작성 방식

테스트 메서드나 함수 이름에는 일반적으로 다음 두 가지 측면이 포함되어야 합니다.

  1. 트리거 조건: 어떤 상태나 조건에서 이벤트가 발생하는지 설명합니다.
  2. 기대 결과: 이벤트가 발생했을 때 시스템이 어떻게 동작해야 하는지 설명합니다.

이러한 방식으로 테스트 명칭을 작성하면 테스트의 목적과 시스템의 기대 동작을 한눈에 파악할 수 있습니다.

예시:

  • shouldSendOrderConfirmationEmailWhenOrderIsPlaced()
    • 이 테스트는 주문이 완료될 때 주문 확인 이메일이 전송되는지 검증합니다.
    • 이벤트: OrderPlaced
    • 기대 결과: 주문 확인 이메일이 전송됨
  • shouldMarkOrderAsShippedWhenShippingLabelIsGenerated()
    • 이 테스트는 배송 라벨이 생성되면 주문 상태가 "배송 완료"로 변경되는지 검증합니다.
    • 이벤트: ShippingLabelGenerated
    • 기대 결과: 주문 상태가 "배송 완료"로 변경됨

이벤트 명칭과 테스트 명칭 간의 일관성

테스트 명칭은 가능한 한 이벤트의 명칭을 그대로 반영하거나, 그 의미를 잘 표현해야 합니다. 이벤트 명칭이 도메인 지식을 반영하듯, 테스트 명칭도 도메인 지식을 바탕으로 작성됩니다. 이를 통해 테스트 코드가 도메인 논리를 명확하게 드러낼 수 있습니다.

  • 이벤트 명칭: UserLoggedIn
  • 테스트 명칭: shouldLoadUserDashboardWhenUserLogsIn()

이처럼 이벤트의 이름과 관련된 동작이 테스트 메서드 이름에 포함되면, 테스트의 목적을 한눈에 이해할 수 있습니다. 이는 특히 TDD 사이클에서 테스트를 빠르게 작성하고 유지보수하는 데 큰 도움이 됩니다.


이렇게 이벤트 명칭과 테스트 명칭의 연관성을 유지하는 것은 코드 가독성을 높이고, 테스트의 목적과 시스템 동작을 명확하게 정의하는 데 중요한 역할을 합니다.

'프로그래밍 > 아키텍처_DDD' 카테고리의 다른 글

S/W 아키텍처  (0) 2025.04.28
표현 영역과 응용 영역  (0) 2024.11.29
DDD 용어 개념 정리  (0) 2024.10.22
왜 지금 도메인 주도 설계가 필요한가?  (0) 2024.10.18

+ Recent posts