public class VirtualWallet { // Domain领域模型(充血模型) private Long id; private Long createTime = System.currentTimeMillis();; private BigDecimal balance = BigDecimal.ZERO; public VirtualWallet(Long preAllocatedId) { this.id = preAllocatedId; } public BigDecimal balance() { return this.balance; } public void debit(BigDecimal amount) { if (this.balance.compareTo(amount) < 0) { throw new InsufficientBalanceException(...); } this.balance.subtract(amount); } public void credit(BigDecimal amount) { if (amount.compareTo(BigDecimal.ZERO) < 0) { throw new InvalidAmountException(...); } this.balance.add(amount); } } public class VirtualWalletService { // 通过构造函数或者IOC框架注入 private VirtualWalletRepository walletRepo; private VirtualWalletTransactionRepository transactionRepo; public VirtualWallet getVirtualWallet(Long walletId) { VirtualWalletEntity walletEntity = walletRepo.getWalletEntity(walletId); VirtualWallet wallet = convert(walletEntity); return wallet; } public BigDecimal getBalance(Long walletId) { return walletRepo.getBalance(walletId); } public void debit(Long walletId, BigDecimal amount) { VirtualWalletEntity walletEntity = walletRepo.getWalletEntity(walletId); VirtualWallet wallet = convert(walletEntity); wallet.debit(amount); walletRepo.updateBalance(walletId, wallet.balance()); } public void credit(Long walletId, BigDecimal amount) { VirtualWalletEntity walletEntity = walletRepo.getWalletEntity(walletId); VirtualWallet wallet = convert(walletEntity); wallet.credit(amount); walletRepo.updateBalance(walletId, wallet.balance()); } public void transfer(Long fromWalletId, Long toWalletId, BigDecimal amount) { //...跟基于贫血模型的传统开发模式的代码一样... } }
可以看到Domain中也实现了几个业务判定
整体在Service中也调用了domain中的几个方法
如果业务更加复杂
public class VirtualWallet { private Long id; private Long createTime = System.currentTimeMillis();; private BigDecimal balance = BigDecimal.ZERO; private boolean isAllowedOverdraft = true; private BigDecimal overdraftAmount = BigDecimal.ZERO; private BigDecimal frozenAmount = BigDecimal.ZERO; public VirtualWallet(Long preAllocatedId) { this.id = preAllocatedId; } public void freeze(BigDecimal amount) { ... } public void unfreeze(BigDecimal amount) { ...} public void increaseOverdraftAmount(BigDecimal amount) { ... } public void decreaseOverdraftAmount(BigDecimal amount) { ... } public void closeOverdraft() { ... } public void openOverdraft() { ... } public BigDecimal balance() { return this.balance; } public BigDecimal getAvailableBalance() { BigDecimal totalAvaliableBalance = this.balance.subtract(this.frozenAmount); if (isAllowedOverdraft) { totalAvaliableBalance += this.overdraftAmount; } return totalAvaliableBalance; } public void debit(BigDecimal amount) { BigDecimal totalAvaliableBalance = getAvailableBalance(); if (totoalAvaliableBalance.compareTo(amount) < 0) { throw new InsufficientBalanceException(...); } this.balance.subtract(amount); } public void credit(BigDecimal amount) { if (amount.compareTo(BigDecimal.ZERO) < 0) { throw new InvalidAmountException(...); } this.balance.add(amount); } }
更复杂的业务在Domain中得到解决,实际repo或dao还会在service中进行
Domain中保留独立性 与其他服务层解耦