Java 기반으로 실전 프로젝트를 단계별로 만들고 리팩터링하면서, 원칙과 습관에 기술을 더하는 체득하게 되는 입문단계의 개발자용 실무 가이드이다.
작은 프로젝트를 통해 실전과 같은 학습을 진행하게 되는데 이를 통해 실제 큰 프로젝트에 대해 적용할 수 있게 된다.
Bank Statements Analyzer
KISS 원칙
- Keep It Simple, Stupid
- 지금 필요한 가장 단순한 설계에 집중하자.
- 과설계, 범용화, 추상화 등 남발 금지
SRP/응집도
- SOLID 원칙 중 단일 책임 원칙을 적용하자
- 하나의 책임을 수행하는 모듈과 클래스는 하나의 액터에 대해서만 책임져야 한다.
KISS 원칙을 지키면 SRP 원칙을 지키기 쉽다.
높은 응집과 낮은 결합은 유지 보수의 비용을 절감시킨다.
Document Management System(DMS)
LSP
하위 타입은 상위 타입으로 대체 가능해야한다.
이역시 SOLID 원칙에 근거하여 어떻게 적용하는지 작은 프로젝트를 통해 알 수 있다.
- 하위 타입이 더 까다로운 조건을 요구하면 안 된다.
- 상위 타입이 약속한 결과나 효과를 줄이거나 빼먹으면 안 된다.
- 상위 타입의 불변 조건은 하위에서도 항상 성립해야 한다.
- 상위 타입이 던지지 않던 예외를 새로 던지지 말 것
캡슐화 및 재사용
- 데이터 은닉 + 동작은 의도를 드러낼 때만 노출
- 불변 객체와 방어적 복사
- 도메인 값 객체로 규칙을 타입에 가두어라
- DIP 로 외부 인프라(혹은 도메인 하위 계층 등)를 포트/어댑터로 분리
- 서비스는 인터페이스에 의존하여 구현을 자유롭게 변경할 수 있도록
Business Rules Engine
TDD 사이클
Red → Green → Refactor
- 규칙인 조건과 행동은 자주 바뀌므로 빠른 피드백과 안전한 리팩터링을 가져간다
- 가장 작은 규칙 1개를 실패하는 것으로 테스트 시작
스위치보단 플루언트 API
- 스위치,
if-else
등은 시작은 빠르지만 규칙이 늘어날 수록 난잡해진다.
- 플루언트 API 로 조건(predicate)과 행동(action)을 선언적으로 표현하면 조합/테스트(재사용까지) 쉬워진다.
Twootr
헥사고날 아키텍처(Port & Adapter)
- 가장 중요한 계층인 도메인과 유스케이스는 포트(인터페이스)에만 의존하며 어댑터가 실제 구현을 담당한다.
- 테스트 및 변경이 용이해지고 결합을 최소화할 수 있다.
영속성 레파지토리
- 도메인 언어로 저장/조회만 책임진다.
- CQRS 패턴으로 코드 수준에서 부터 시스템 구조까지 해당 패턴을 확장 시킬 수 있다.
동기와 비동기
- 동기 (REST/RPC): command, query 에 단순하고 즉답. 디버깅이 쉽다
- 비동기 (이벤트/큐): 타임라인 fan-out, 아웃박스 이벤트
equals/hashCode 계약
- 값 객체(Value Object): 모든 상태로 동등성을 정의한다.
- 엔티티(Entity): 식별자로 동등성을 정의한다.
FP 확장 (람다, 메서드 레퍼런스, 스트림 등)
- 의도 중심으로(혹은 마치 도메인언어처럼) 간결하게 코드를 좀 더 표현력 높게 작성할 수 있다.
- 빌더 패턴으로 usecase 를 작성한다면 실제 구현체인 어댑터들의 재사용을 훨씬 높일 수 있으며 수정에 대해서도 대처가 빠르다. (feat.트랜잭션 스크립트 패턴)