Make It Work, Make It Right, Make It Fast
코드는 팀이 함께 완성해 가는 한 편의 글입니다. 우리는 그 글을 차곡차곡 쌓아 시스템을 만들어 갑니다.
- 소스 코드의 구조는 책의 목차처럼 명확하고 직관적이어야 하며, 이를 통해 도메인과 시스템을 자연스럽게 이해할 수 있어야 합니다.
- 테스트 코드는 검증 도구를 넘어, 비즈니스 규칙을 이해하고 학습하는 데 핵심적인 가이드 역할을 해야 합니다.
도메인 주도 설계의 '무엇을 표현할지'와 함수형 프로그래밍의 '어떻게 표현할지'가 만나서, 변경에 강하고, 테스트 가능하고, 명확한 의도를 가진 코드를 만듭니다.
- 무엇을 표현할지: 복잡성 분리
- 복잡한 비즈니스 로직을 도메인 모델 중심으로 풀어나가는 설계 방법입니다.
- 도메인 전문가의 언어(Ubiquitous Language)로 시스템을 설계하는 것이 핵심입니다.
- 어떻게 표현할지: 부작용 최소화
- 함수(수학적인 함수)에 기반한 프로그래밍 방식입니다.
- 상태 변경 없이, 입력에 따라 일관된 출력을 보장합니다.
- 변경에 강한 모델
- 도메인 주도 설계: 복잡성 분리 (관심사의 분리: 도메인과 기술)
- 함수형 프로그래밍: 부작용 최소화 (합성 함수: 부작용 없는 순수 함수 연결)
- 예측 가능한 동작
- 도메인 주도 설계: 명확한 경계 (Bounded Context)
- 함수형 프로그래밍: 순수 함수 지향
- 풍부한 도메인 표현
- 도메인 주도 설계: 명확한 의미 부여 (Ubiquitous Language)
- 함수형 프로그래밍: 타입 기반 설계
Fin<T>
는 성공(Success) 또는 실패(Failure) 상태를 나타내는 값입니다.FinT<M, T>
는 Fin를 다른 모나드M
과 결합하여 복합적인 효과를 처리할 수 있도록 하는 모나드 변환기입니다.- 예를 들어,
FinT<IO, T>
는IO
작업 중 발생할 수 있는 오류를Fin<T>
을 통해 명시적으로 처리할 수 있게 합니다.
- 도메인
LanguageExt.Core
: 함수형Dapr
: 액터 모델MediatR
: 기술 관심사와 도메인 관심사 간의 느슨한 결합 (Mediator 패턴)FluentValidation
: 유효성 검사Ardalis.SmartEnum
: 열거형 도메인 타입Ulid
: Entity Id
- 테스트
xUnit
: 테스트TngTech.ArchUnitNET
: 아키텍처 테스트Reqnroll
: BDD (Behavior-Driven Development) 테스트Verify
: 스냅샷 테스트Testcontainers
: 컨테이너 테스트NBomber
: 부하 테스트coverlet
: 코드 커버리지AwesomeAssertions
: Fluent 테스트 검증NSubstitute
: 인터페이스 MockingBogus
: Fake 데이터 생성기Allure Report
: 테스트 보고서
- 기술
OpenTelemetry
: 관찰 가능성 (Observability)Aspire
: 분산 클라우드 네이티브FastEndpoints
: Web APIZiggyCreatures.FusionCache
: 메모리 캐시MassTransit
: RabbitMQEntity Framework Core
: Command ORMDapper
: Query ORMPolly
: Resilience
TODO
- 001 | 솔루션 | 관심사의 분리 (Separation of Concerns)
- 002 | 솔루션 | 테스트 자동화 (Unit Test, Integration Test)
- 003 | 솔루션 | 폴더 구성
- 004 | 솔루션 | .NET SDK 버전 (global.json)
- 005 | 솔루션 | NuGet 저장소 소스 (nuget.config)
- 006 | 솔루션 | NuGet 패키지 버전 중앙 관리 (Directory.Packages.props)
- 007 | 솔루션 | 프로젝트 속성 중앙 관리 (Directory.Build.props)
- 008 | 솔루션 | 전역 버전
- 009 | 프로젝트 | 어셈블리 정의 (AssemblyReference.cs)
- 010 | 프로젝트 | 클래스 기본 접근 제어자 (internal sealed)
- 011 | 프로젝트 | 옵션 유효성 검사 (appsettings.json, IOption<T>)
- 012 | 프로젝트 | 소스 생성기
- 013 | 테스트 | 테스트 범주화
- 014 | 테스트 | 테스트 보고서 (Code Coverage Report, Allure Report)
- 015 | 테스트 | 스냅샷 테스트 (Snapshot)
- 016 | 테스트 | 설계 규칙 테스트 (ArchUnitNET)
- 017 | 테스트 | 도메인 규칙 테스트 (BDD: Reqnroll)
- 018 | 도메인 레이어 | 값 객체 설계 규칙
- 019 | 도메인 레이어 | 엔티티 설계 규칙
- 020 | 애플리케이션 레이어 | CQRS 메시지
- 021 | 애플리케이션 레이어 | 이벤트 메시지
- 022 | 애플리케이션 레이어 | 파이프라인
- ...
단순한 Divide
구현을 출발점으로 삼아, 부작용 없이 예측 가능한 순수 함수(Pure Function)로 개선하고, 이를 통해 유효한 값만 표현할 수 있는 도메인 타입(Value Object)을 점진적으로 설계해 나가는 과정을 통해 도메인 주도 설계와 함수형 프로그래밍의 핵심 가치를 함께 익힙니다.
// 개선 전
int Divide(int x, int y)
{
return x / y;
}
// 개선 후
int Divide(int x, NonZeroInt y)
{
return x / y;
}
이 과정은 의미 있는 타입 설계, 입력 유효성 보장, 오류 처리의 명확화, 도메인 언어 강화 등을 아우르며, 유지보수성과 안정성이 높은 코드를 구성하는 기반을 마련합니다.
- 1. 시작은 단순한 나눗셈에서
- 2. 예외를 예방하려는 우리의 첫 시도
- 3. 실패도 값이다
- 4. 그 값이 문제라면, 애초에 들어오지 못하게 하자 (Always Valid)
- 5. 코드의 표현력을 더 풍부하게 (연산자 오버로딩)
- 6. 값이 같다면 객체도 같아야 한다 (값의 동등성)
- 7. 객체의 책임을 분리하자 (단일 책임 원칙: SRP)
- 8. 설계 규칙을 자동으로 검증하기
- 9. 타입으로 말하는 도메인
Scott Wlaschin "Designing with types" F# 코드를 C# 기반으로 재구성하는 글입니다.
- TODO
Amichai Mantinband "Clean Architecture" 템플릿을 함수형 기반의 도메인 주도 설계와 아키텍처로 재구성하는 글입니다.
- TODO
"Getting Started: Domain-Driven Design" 강의 예제를 함수형 기반의 도메인 주도 설계와 아키텍처로 재구성하는 글입니다.
- Part 1. Hexagonal 아키텍처 (도메인 레이어: 도메인 타입)
- Chapter 01. 도메인 탐험
- Chapter 02. 도메인 구조화
- Chapter 03. 도메인 함수형화
- Chapter 04. 도메인 Entity Id 소스 생성기
- Chapter 05. 도메인 시나리오 테스트 (BDD: Cucumber)
- Part 2. Hexagonal 아키텍처 (애플리케이션 레이어: 유스케이스)
- Chapter 06. 유스케이스 CQRS & Event
- Chapter 07. 유스케이스 미들웨어
- Chapter 08. 유스케이스 시나리오 테스트 (BDD: Cucumber)
- Part 3. Hexagonal 아키텍처 (어댑터 레이어)
- Chapter 09. Web API
- Chapter 10. IAdapter 인터페이스 소스 생성기
- Chapter 11. 저장소 CQRS (Command: EF Core, Query: Dapper)
- Chapter 12. 컨테이너화
- Chapter 13. 통합 테스트
- Chapter 14. 부하 테스트
- Part 1. Microservices 아키텍처
- Chapter 01. Aspire
- Chapter 02. RabbitMQ
- Chapter 03. Resilience
- Chapter 04. Reverse Proxy
- Chapter 05. Chaos Engineering
- Part 2. 운영
- Chapter 06. OpenFeature (Feature Flag 관리)
- Chapter 07. OpenSearch (Observability 시스템)
- Chapter 08. Ansible (Infrastructure as Code)
- Chapter 09. Backstage (Building Developer Portals)
"eShop"을 Functional 도메인 주도 설계와 아키텍처로 재구성하는 글입니다.
- TODO