Skip to content

Commit

Permalink
领域驱动设计Demo
Browse files Browse the repository at this point in the history
  • Loading branch information
Air433 committed Dec 29, 2019
0 parents commit 552244c
Show file tree
Hide file tree
Showing 40 changed files with 897 additions and 0 deletions.
6 changes: 6 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

37 changes: 37 additions & 0 deletions bank-application/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>dddbook</artifactId>
<groupId>com.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>bank-application</artifactId>


<dependencies>
<dependency>
<groupId>com.example</groupId>
<artifactId>bank-domain</artifactId>
<version>${dddbook.version}</version>
</dependency>

<dependency>
<groupId>com.example</groupId>
<artifactId>bank-persistence</artifactId>
<version>${dddbook.version}</version>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.example.bank.application;

import com.example.bank.common.Result;
import com.example.bank.exception.DailyLimitExceededException;
import com.example.bank.exception.InsufficientFundsException;
import com.example.bank.exception.InvalidCurrencyException;

import java.math.BigDecimal;

public interface TransferService {

Result<Boolean> transfer(Long sourceUserId, String targetAccountNumber, BigDecimal targetAmount, String targetCurrency) throws Exception, DailyLimitExceededException;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package com.example.bank.application.impl;

import com.example.bank.application.TransferService;
import com.example.bank.common.Result;
import com.example.bank.domain.entity.Account;
import com.example.bank.domain.service.AccountTransferService;
import com.example.bank.domain.types.AuditMessage;
import com.example.bank.exception.DailyLimitExceededException;
import com.example.bank.exception.InsufficientFundsException;
import com.example.bank.exception.InvalidCurrencyException;
import com.example.bank.external.ExchangeRateService;
import com.example.bank.messaging.AuditMessageProducer;
import com.example.bank.repository.AccountRepository;
import com.example.bank.types.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;

@Service
public class TransferServiceImpl implements TransferService {

@Autowired
private AccountRepository accountRepository;

private AuditMessageProducer auditMessageProducer;
private ExchangeRateService exchangeRateService;
private AccountTransferService accountTransferService;

// @Transactional(rollbackFor = Exception.class)
@Override
public Result<Boolean> transfer(Long sourceUserId, String targetAccountNumber, BigDecimal targetAmount, String targetCurrency) throws Exception, DailyLimitExceededException {
Money targetMoney = new Money(targetAmount, new Currency(targetCurrency));

Account sourceAccount = accountRepository.find(new UserId(sourceUserId));

Account targetAccount = accountRepository.find(new AccountNumber(targetAccountNumber));

ExchangeRate exchangeRate = exchangeRateService.getExchangeRate(sourceAccount.getCurrency(), targetMoney.getCurrency());

accountTransferService.transfer(sourceAccount, targetAccount, targetMoney, exchangeRate);

accountRepository.save(sourceAccount);

accountRepository.save(targetAccount);

// 发送审计消息
AuditMessage message = new AuditMessage(sourceAccount, targetAccount, targetMoney);
auditMessageProducer.send(message);

return Result.success(true);
}
}
28 changes: 28 additions & 0 deletions bank-domain/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>dddbook</artifactId>
<groupId>com.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>bank-domain</artifactId>


<dependencies>
<dependency>
<groupId>com.example</groupId>
<artifactId>bank-types</artifactId>
<version>${dddbook.version}</version>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
</dependency>
</dependencies>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package com.example.bank.domain.entity;

import com.example.bank.exception.DailyLimitExceededException;
import com.example.bank.exception.InsufficientFundsException;
import com.example.bank.exception.InvalidCurrencyException;
import com.example.bank.exception.MoneyAmoutNotNullException;
import com.example.bank.types.*;

public class Account {

private AccountId id;
private AccountNumber accountNumber;
private UserId userId;
private Money available;
private Money dailyLimit;

private Currency currency;

public AccountId getId() {
return id;
}

public void setId(AccountId id) {
this.id = id;
}

public AccountNumber getAccountNumber() {
return accountNumber;
}

public void setAccountNumber(AccountNumber accountNumber) {
this.accountNumber = accountNumber;
}

public UserId getUserId() {
return userId;
}

public void setUserId(UserId userId) {
this.userId = userId;
}

public Money getAvailable() {
return available;
}

public void setAvailable(Money available) {
this.available = available;
}

public Money getDailyLimit() {
return dailyLimit;
}

public void setDailyLimit(Money dailyLimit) {
this.dailyLimit = dailyLimit;
}

public Currency getCurrency() {
return currency;
}

public void setCurrency(Currency currency) {
this.currency = currency;
}

// 转出
public void withdraw(Money money) throws Exception, DailyLimitExceededException {
if (this.available.compareTo(money) < 0){
throw new InsufficientFundsException();
}

if (this.dailyLimit.compareTo(money) < 0){
throw new DailyLimitExceededException();
}

this.available = this.available.subtract(money);
}

// 转入
public void deposit(Money money) throws InvalidCurrencyException, MoneyAmoutNotNullException {
if (!this.getCurrency().equals(money.getCurrency())){
throw new InvalidCurrencyException();
}

this.available = this.available.add(money);

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.example.bank.domain.service;

import com.example.bank.domain.entity.Account;
import com.example.bank.exception.DailyLimitExceededException;
import com.example.bank.exception.InsufficientFundsException;
import com.example.bank.exception.InvalidCurrencyException;
import com.example.bank.types.ExchangeRate;
import com.example.bank.types.Money;

public interface AccountTransferService {
void transfer(Account sourceAccount, Account targetAccount, Money targetMoney, ExchangeRate exchangeRate) throws Exception, DailyLimitExceededException;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.example.bank.domain.service.impl;

import com.example.bank.domain.entity.Account;
import com.example.bank.domain.service.AccountTransferService;
import com.example.bank.exception.DailyLimitExceededException;
import com.example.bank.exception.InsufficientFundsException;
import com.example.bank.exception.InvalidCurrencyException;
import com.example.bank.types.ExchangeRate;
import com.example.bank.types.Money;
import org.springframework.stereotype.Service;

@Service
public class AccountTransferServiceImpl implements AccountTransferService {
@Override
public void transfer(Account sourceAccount, Account targetAccount, Money targetMoney, ExchangeRate exchangeRate) throws Exception, DailyLimitExceededException {
Money sourceMoney = exchangeRate.exchageTo(targetMoney);
sourceAccount.deposit(sourceMoney);
targetAccount.withdraw(targetMoney);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.example.bank.domain.types;

import com.example.bank.domain.entity.Account;
import com.example.bank.types.Money;

public class AuditMessage {
public AuditMessage(Account sourceAccount, Account targetAccount, Money targetMoney) {

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.example.bank.exception;

public class AccountNotFoundException {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.example.bank.exception;

public class DailyLimitExceededException extends Throwable {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.example.bank.exception;

public class InsufficientFundsException extends Exception{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.example.bank.external;

import com.example.bank.types.Currency;
import com.example.bank.types.ExchangeRate;

public interface ExchangeRateService {
ExchangeRate getExchangeRate(Currency source, Currency target);

}

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.example.bank.messaging;

import com.example.bank.domain.types.AuditMessage;

public interface AuditMessageProducer {
void send(AuditMessage message);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.example.bank.repository;

import com.example.bank.domain.entity.Account;
import com.example.bank.types.AccountId;
import com.example.bank.types.AccountNumber;
import com.example.bank.types.UserId;

public interface AccountRepository {
Account find(AccountId id) throws Exception;
Account find(AccountNumber accountNumber) throws Exception;
Account find(UserId userId) throws Exception;
Account save(Account account) throws Exception;
}
27 changes: 27 additions & 0 deletions bank-persistence/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>dddbook</artifactId>
<groupId>com.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>bank-persistence</artifactId>


<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
</dependency>
<dependency>
<groupId>com.example</groupId>
<artifactId>bank-domain</artifactId>
<version>${dddbook.version}</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.example.bank.external;

import com.example.bank.types.Currency;
import com.example.bank.types.ExchangeRate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;

@Service
public class ExchangeRateServiceImpl implements ExchangeRateService{
@Override
public ExchangeRate getExchangeRate(Currency source, Currency target) {
// if (source.equals(target)) {
return new ExchangeRate(BigDecimal.ONE, source, target);
// }

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.example.bank.persistence;

import com.example.bank.domain.entity.Account;

public interface AccountBuilder {
Account toAccount(AccountDO accountDO) throws Exception;

AccountDO fromAccount(Account account);
}
Loading

0 comments on commit 552244c

Please sign in to comment.