DDD之应用架构

一,前言

之所以写这些文章,很大程度上,是因为阅读了阿里技术专家的文章,读完之后,对我内心触动很大,文章多出引用了阿里技术文章的内容,仅作为个人学习用途,也是作为技术人,希望技术可以被更多人学习到。

作为一个实习生,谈架构,未免让人感觉,好高骛远,以下陈述只属于个人浅薄意见。

依个人浅薄意见,架构的本质就是应用的拆分和聚合。

拆分也就是应用微服务化,聚合,并不是指将多个微服务聚合成一个应用,而是指聚合多个微服务的功能,让他完成一个大的功能。这样做的灵活性,可扩展性就会更高。

所谓应用架构,个人理解,更可以指的是应用中固定不变的代码结构,设计模式,规范和组件间的通信。

一个好的应用架构,通过规定一套规范,可以让团队内能力参差不齐的开发人员更好的共同开发,降低开发成本,提升开发效率和代码质量。

要求,或者原则?

  • 独立于框架:架构不应该依赖某个外部的库或框架,不应该被框架的结构所束缚。
  • 独立于前端:前台展示的样式可能会随时发生变化(今天可能是网页、明天可能变成console、后天是独立app),但是底层架构不应该随之而变化。
  • 独立于底层数据源:无论今天你用MySQL、Oracle还是MongoDB、CouchDB,甚至使用文件系统,软件架构不应该因为不同的底层数据储存方式而产生巨大改变。
  • 独立于外部依赖:无论外部依赖如何变更、升级,业务的核心逻辑不应该随之而大幅变化。
  • 测试覆盖率:无论外部依赖了什么数据库、硬件、UI或者服务,业务的逻辑应该都能够快速被验证正确性。

通过一个需求,来论证。

用户可以通过银行网页转账给另一个账号,支持跨币种转账。同时因为监管和对账需求,需要记录本次转账活动。

二,传统互联网架构下的架构设计

1、从MySql数据库中找到转出和转入的账户,选择用 MyBatis 的 mapper 实现 DAO;

2、从 Yahoo(或其他渠道)提供的汇率服务获取转账的汇率信息(底层是 http 开放接口);

3、计算需要转出的金额,确保账户有足够余额,并且没超出每日转账上限;

4、实现转入和转出操作,扣除手续费,保存数据库;

5、发送 Kafka 审计消息,以便审计和对账用;

public class TransferController {
   
 
    private TransferService transferService;
 
    public Result<Boolean> transfer(String targetAccountNumber, BigDecimal amount, HttpSession session) {
   
        Long userId = (Long) session.getAttribute("userId");
        return transferService.transfer(userId, targetAccountNumber, amount, "CNY");
    }
}
 
public class TransferServiceImpl implements TransferService {
   
 
    private static final String TOPIC_AUDIT_LOG = "TOPIC_AUDIT_LOG";
    private AccountMapper accountDAO;
    private KafkaTemplate<String, String> kafkaTemplate;
    private YahooForexService yahooForex;
 
    @Override
    public Result<Boolean> transfer(Long sourceUserId, String targetAccountNumber, BigDecimal targetAmount, String targetCurrency) {
   
        // 1. 从数据库读取数据,忽略所有校验逻辑如账号是否存在等
        AccountDO sourceAccountDO = accountDAO.selectByUserId(sourceUserId);
        AccountDO targetAccountDO = accountDAO.selectByAccountNumber(targetAccountNumber);
 
        // 2. 业务参数校验
        if (!targetAccountDO.getCurrency().equals(targetCurrency)) {
   
            throw new InvalidCurrencyException();
        }
 
        // 3. 获取外部数据,并且包含一定的业务逻辑
        // exchange rate = 1 source currency = X target currency
        BigDecimal exchangeRate = BigDecimal.ONE;
        if (sourceAccountDO.getCurrency().equals(targetCurrency)) {
   
            exchangeRate = yahooForex.getExchangeRate(sourceAccountDO.getCurrency(), targetCurrency);
        }
        BigDecimal sourceAmount = targetAmount.divide(exchangeRate, RoundingMode.DOWN);
 
        // 4. 业务参数校验
        if (sourceAccountDO.getAvailable().compareTo(sourceAmount) < 0) {
   
            throw new InsufficientFundsException();
        }
 
        if (sourceAccountDO.getDailyLimit().compareTo(sourceAmount) < 0) {
   
            throw new DailyLimitExceededException();
        }
 
        // 5. 计算新值,并且更新字段
        BigDecimal newSource = sourceAccountDO.getAvailable().subtract(sourceAmount);
        BigDecimal newTarget = targetAccountDO.getAvailable().add(targetAmount);
        sourceAccountDO.setAvailable(newSource);
        targetAccountDO.setAvailable(newTarget
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值