육각형 아키텍처는 도메인 중심의 아키텍처에 적합하기 때문에 도메인 엔티티를 만드는 것으로 시작하고, 후에 해당 도메인 엔티티를 중심으로 유스케이스를 구현하겠다.
한 계좌에서 다른 계좌로 송금하는 유스케이스를 구현해보자.
객체지향적인 방식으로 모델링하는 한 가지 방법은 입금과 출금을 할 수 있는 Account
엔티티를 만들고,
출금 계좌에서 돈을 출금해 입금 계좌로 돈을 입금하는 것이다.
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class Account {
@Getter private final AccountId id;
@Getter private final Money baselineBalance;
@Getter private final ActivityWindow activityWindow;
baselineBalance
: 계좌의 현재 잔고를 계산하기 위해 활동창(ActivityWindow
) 활동 전의 잔고를 표현
→ 현재의 총 잔고 : 기존 잔고 + 활동창의 모든 활동들의 잔고의 합
public Money calculateBalance() {
return Money.add(
this.baselineBalance,
this.activityWindow.calculateBalance(this.id));
}
public boolean withdraw(Money money, AccountId targetAccountId) {
if (!mayWithdraw(money)) {
return false;
}
Activity withdrawal = new Activity(
this.id,
this.id,
targetAccountId,
LocalDateTime.now(),
money);
this.activityWindow.addActivity(withdrawal);
return true;
}
private boolean mayWithdraw(Money money) {
return Money.add(
this.calculateBalance(),
money.negate())
.isPositiveOrZero();
}
public boolean deposit(Money money, AccountId sourceAccountId) {
Activity deposit = new Activity(
this.id,
sourceAccountId,
this.id,
LocalDateTime.now(),
money);
this.activityWindow.addActivity(deposit);
return true;
}
Account
엔티티는 계좌의 현재 스냅숏을 제공하며, 계좌의 모든 입출금은 Activity
엔티티에 포착된다.