Skip to content

아키텍처

아키텍처 개요

아키텍처 정의

※ 출처: Making Architecture Matter, 소프트웨어 아키텍처의 중요성

아키텍처 범주

※ 출처: Making old applications new again

Application Architecture
  ├─ Monolithic Architecture
  ├─ Modular Monolithic Architecture
  ├─ N-tier Architecture
  └─ Microservices Architecture
      ├─ Internal Architecture
      │    └─ Layered Architecture
      │         ├─ Hexagonal Architecture
      │         ├─ Onion Architecture
      │         ├─ Clean Architecture
      │         ├─ Vertical Slice Architecture
      │         └─ ...

      └─ External Architecture
           └─ 외부 시스템 구성 아키텍처: 예. CNCF Landscape

아키텍처 역사

※ 출처: The Grand Unified Theory of Clean Architecture and Pyramid

아키텍처 원칙

아키텍처 원칙: Separation of concerns

관심사의 분리

  • 개발 시 요구사항과 운영 시 로그는 서로 다른 시점이지만, 코드에 대한 관점은 Biz.와 Tech. 관심사 기준으로 같아야 합니다.
    • 개발 시 요구사항을 비즈니스와 기술 관심사로 분해합니다.
    • 운영 시 로그를 비즈니스와 기술 관심사로 식별합니다.

레이어

  • 개발 시 요구사항과 운영 시 로그는 서로 다른 시점이지만, 코드에 대한 관점은 레이어 기준으로 동일해야 합니다.

  • 비즈니스 관심사
    • Application: 비즈니스 흐름(Biz. Flow)
    • Domain: 비즈니스 단위(Biz. Unit)
  • 기술 관심사
    • Adapter
      • Known 입출력 Adapter
      • Unknown 입출력 Adapter: 부수 효과(Side Effects)

레이어 배치

레이어 Known I/O 배치

레이어 Unknown I/O 배치

레이어 격리

레이어 격리 전

  • 출력의 변화 영향이 입력까지 전파됩니다.

레이어 격리 후

  • 입출력 인터페이스를 활용하여, 입출력 변화의 영향이 Operation 레이어에 전파되지 않도록 차단합니다(Strategy 패턴).

레이어 테스트

  • 단위 테스트: Biz. 관심사를 테스트합니다.
  • 통합 테스트: Tech. 관심사까지 포함하여 Biz. 관심사를 테스트합니다.

레이어 고도화

격리 고도화

  • Mediator 패턴을 활용하여, 격리된 레이어 간의 소통을 위해 인터페이스의 입출력을 메시지 기반으로 단순화합니다.
    • 메시지는 컴파일 타임과 런타임 모두에서 호출자와 수신자 정보를 숨길 수 있습니다(느슨한 결합).
      구분Mediator 패턴Strategy 패턴
      Compile-timeUnknownUnknown
      RuntimeUnknownKnown
    • 메시지는 런타임에 메시지에 부가 기능을 더 쉽게 추가할 수 있습니다(Decorator 패턴)
    • 메시지는 입출력을 범주화할 수 있습니다(Command 메시지와 Query 메시지: CQRS 패턴).

메시지 고도화

  • Known 입출력(Mediator 패턴)은 Decorator 패턴(Pipeline)과 조합하여 동적으로 메시지에 새 기능을 추가할 수 있습니다.
    • 예. 메시지 처리 시간 로그
    • 예. 입력 메시지 유효성 검사
    • 예. Command 메시지일 때 트랜잭션 처리(CQRS 패턴)

  • Unknown 입출력(Strategy 패턴)도 역시 Decorator 패턴(Pipeline)과 조합하여 동적으로 새 기능을 추가할 수 있습니다.

메시지 범주화(CQRS)

  • Mediator 패턴을 통해 데이터 쓰기를 위한 메시지(Command)와 데이터를 읽기 위한 메시지(Query)로 구분할 수 있습니다.
    • Command 메시지: 데이터 가변(CUD:Create, Update, Delete)
    • Query 메시지: 데이터 불변(R: Read)
  • Command: ORM(OLTP, Create, Update, Delete)
    • Command는 데이터의 상태를 변경하는 작업을 담당합니다.
    • 이 작업은 일반적으로 여러 테이블을 참조하거나 복잡한 트랜잭션을 포함할 수 있습니다.
    • 따라서 Command는 데이터베이스에 변경을 가하는데, 복잡한 로직을 처리하거나 여러 엔티티와 상호작용할 수 있습니다.
  • Query: SQL(OLAP, Read)
    • Query는 데이터베이스에서 데이터를 읽어오는 작업에 해당합니다.
    • 일반적으로 Command보다 쿼리의 수가 많을 수 있으며, 데이터 조회만을 목적으로 하므로 복잡도가 낮고 최적화된 방식으로 실행됩니다.
    • Query는 데이터의 상태를 변경하지 않고, 데이터를 읽어오는 데 집중합니다.

메시지 범주화(CQRS) 흐름

※ 출처: Module Requests Processing via CQRS

구분CommandQuery
트랜잭션O(필요)X(불 필요)
구현ORMSQL
DTO 변환O(필요)X(불 필요)
SQL 복잡도↓(낮다)↑(높다)
  • 데이터 읽기 위한 메시지 처리에서는 SQL 구문을 사용하여 DTO 데이터 변환 없이 데이터베이스 조회 결과를 바로 반환합니다.