JAVA · 디자인패턴
이벤트 소싱
상태 변경을 이벤트로 기록하고 재구성하는 이벤트 소싱 패턴입니다.
디자인패턴고급이벤트소싱EventSourcingsealed이벤트스토어
핵심 설명
상태 변경을 이벤트로 기록하고 재구성하는 이벤트 소싱 패턴입니다.
Java code
import java.util.*;
import java.time.Instant;
// 이벤트 정의
sealed interface AccountEvent {
String accountId();
Instant timestamp();
}
record AccountCreated(String accountId, String owner, Instant timestamp)
implements AccountEvent {}
record MoneyDeposited(String accountId, long amount, Instant timestamp)
implements AccountEvent {}
record MoneyWithdrawn(String accountId, long amount, Instant timestamp)
implements AccountEvent {}
// 이벤트 스토어
class EventStore {
private final List<AccountEvent> events = new ArrayList<>();
void append(AccountEvent event) { events.add(event); }
List<AccountEvent> getEvents(String accountId) {
return events.stream()
.filter(e -> e.accountId().equals(accountId))
.toList();
}
}
// 상태 재구성
record AccountState(String id, String owner, long balance) {
static AccountState replay(List<AccountEvent> events) {
String id = "", owner = "";
long balance = 0;
for (AccountEvent e : events) {
switch (e) {
case AccountCreated c -> { id = c.accountId(); owner = c.owner(); }
case MoneyDeposited d -> balance += d.amount();
case MoneyWithdrawn w -> balance -= w.amount();
}
}
return new AccountState(id, owner, balance);
}
}
class Main {
public static void main(String[] args) {
EventStore store = new EventStore();
store.append(new AccountCreated("A1", "홍길동", Instant.now()));
store.append(new MoneyDeposited("A1", 50000, Instant.now()));
store.append(new MoneyWithdrawn("A1", 20000, Instant.now()));
AccountState state = AccountState.replay(store.getEvents("A1"));
System.out.printf("%s 잔액: %d원%n", state.owner(), state.balance());
}
}학습 팁
이벤트 소싱은 모든 변경 이력을 보존합니다. 감사 로그, 시간 여행 디버깅, 상태 재구성에 강력합니다.
주의할 점
이벤트 스키마를 변경하면 기존 이벤트를 역직렬화할 수 없습니다. 이벤트 버전 관리 전략을 미리 설계하세요.
자주 묻는 질문
이벤트 소싱란 무엇인가요?
상태 변경을 이벤트로 기록하고 재구성하는 이벤트 소싱 패턴입니다.
이벤트 소싱 학습 시 주의할 점은 무엇인가요?
이벤트 스키마를 변경하면 기존 이벤트를 역직렬화할 수 없습니다. 이벤트 버전 관리 전략을 미리 설계하세요.
Continue Learning
Java 학습을 이어가세요
총 200개의 독립 HTML 학습 문서 중 하나입니다. 각 문서는 고유 URL과 canonical 메타데이터를 가집니다.