아키텍처
아키텍처 개요
아키텍처 정의
※ 출처: 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
Application
Architecture =Internal
Architecture +External
Architecture
아키텍처 역사
※ 출처: The Grand Unified Theory of Clean Architecture and Pyramid
아키텍처 원칙
아키텍처 원칙: Separation of concerns
관심사의 분리
- 개발 시 요구사항과 운영 시 로그는 서로 다른 시점이지만, 코드에 대한 관점은 Biz.와 Tech. 관심사 기준으로 같아야 합니다.
- 개발 시 요구사항을 비즈니스와 기술 관심사로 분해합니다.
- 운영 시 로그를 비즈니스와 기술 관심사로 식별합니다.
레이어
- 개발 시 요구사항과 운영 시 로그는 서로 다른 시점이지만, 코드에 대한 관점은 레이어 기준으로 동일해야 합니다.
- 비즈니스 관심사
- Application: 비즈니스 흐름(Biz. Flow)
- Domain: 비즈니스 단위(Biz. Unit)
- 기술 관심사
- Adapter
Known
입출력 AdapterUnknown
입출력 Adapter: 부수 효과(Side Effects)
- Adapter
레이어 배치
레이어 Known I/O 배치
레이어 Unknown I/O 배치
레이어 격리
레이어 격리 전
- 출력의 변화 영향이 입력까지 전파됩니다.
레이어 격리 후
- 입출력 인터페이스를 활용하여, 입출력 변화의 영향이 Operation 레이어에 전파되지 않도록 차단합니다(Strategy 패턴).
레이어 테스트
- 단위 테스트: Biz. 관심사를 테스트합니다.
- 통합 테스트: Tech. 관심사까지 포함하여 Biz. 관심사를 테스트합니다.
레이어 고도화
격리 고도화
- Mediator 패턴을 활용하여, 격리된 레이어 간의 소통을 위해 인터페이스의 입출력을 메시지 기반으로 단순화합니다.
- 메시지는 컴파일 타임과 런타임 모두에서 호출자와 수신자 정보를 숨길 수 있습니다(느슨한 결합).
구분 Mediator 패턴 Strategy 패턴 Compile-time Unknown Unknown Runtime Unknown Known - 메시지는 런타임에 메시지에 부가 기능을 더 쉽게 추가할 수 있습니다(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 메시지: 데이터 가변(
Command
: ORM(OLTP, Create, Update, Delete)- Command는 데이터의 상태를 변경하는 작업을 담당합니다.
- 이 작업은 일반적으로 여러 테이블을 참조하거나 복잡한 트랜잭션을 포함할 수 있습니다.
- 따라서 Command는 데이터베이스에 변경을 가하는데, 복잡한 로직을 처리하거나 여러 엔티티와 상호작용할 수 있습니다.
Query
: SQL(OLAP, Read)- Query는 데이터베이스에서 데이터를 읽어오는 작업에 해당합니다.
- 일반적으로 Command보다 쿼리의 수가 많을 수 있으며, 데이터 조회만을 목적으로 하므로 복잡도가 낮고 최적화된 방식으로 실행됩니다.
- Query는 데이터의 상태를 변경하지 않고, 데이터를 읽어오는 데 집중합니다.
메시지 범주화(CQRS) 흐름
※ 출처: Module Requests Processing via CQRS
구분 | Command | Query |
---|---|---|
트랜잭션 | O(필요) | X(불 필요) |
구현 | ORM | SQL |
DTO 변환 | O(필요) | X(불 필요) |
SQL 복잡도 | ↓(낮다) | ↑(높다) |
- 데이터 읽기 위한 메시지 처리에서는 SQL 구문을 사용하여 DTO 데이터 변환 없이 데이터베이스 조회 결과를 바로 반환합니다.