육각형 아키텍처는 도메인 중심의 아키텍처에 적합하기 때문에 도메인 엔티티를 만드는 것으로 시작하고, 후에 해당 도메인 엔티티를 중심으로 유스케이스를 구현하겠다.

도메인 모델 구현하기

한 계좌에서 다른 계좌로 송금하는 유스케이스를 구현해보자.

객체지향적인 방식으로 모델링하는 한 가지 방법은 입금과 출금을 할 수 있는 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 엔티티에 포착된다.