DDD架构设计

今天的应用架构,意指软件系统中固定不变的代码结构、设计模式、规范和组件间的通信方式。在应用开发中架构之所以是最重要的第一步,因为一个好的架构能让系统安全、稳定、快速迭代。在一个团队内通过规定一个固定的架构设计,可以让团队内能力参差不齐的同学们都能有一个统一的开发规范,降低沟通成本,提升效率和代码质量。

  在做架构设计时,一个好的架构应该需要实现以下几个目标:

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

这就好像是建筑中的楼宇,一个好的楼宇,无论内部承载了什么人、有什么样的活动、还是外部有什么风雨,一栋楼都应该屹立不倒,而且可以确保它不会倒。但是今天我们在做业务研发时,更多的会去关注一些宏观的架构,比如SOA架构、微服务架构,而忽略了应用内部的架构设计,很容易导致代码逻辑混乱,很难维护,容易产生bug而且很难发现。

1 . 传统Springboot MVC架构设计弊端

样例:

以微信支付收单为例,按照业务拆分,其业务需求可能会被如下拆分:

1. 从数据库获取数据,比如查看订单数据是否存在

2.业务参数校验

3.获取服务费,计算金额

4.微信下单

5.数据保存

6.发送消息

伪代码如下所示:

public class TransferServiceImpl implements TransferService {

    private OrderMapper orderDao;
    private WxForexService WxForex;

    @Override
    public Result<Boolean> transfer(String orderId, BigDecimal amount, String storeId) {
        // 1. 从数据库读取数据
        OrderDo targetOrderDo = orderDao.selectByOrderId(orderId);

        // 2. 业务参数校验
        if (amount != null) {
            throw new InvalidAmountException();
        }

        // 3. 获取服务费,计算金额
        BigDecimal exchangeRate = WxForex.getServiceRate(amount, storeId);
        BigDecimal newTarget = serviceFeeAmount.add(amount);
		// 4. 微信下单
		wxPay.orderPlacement(param);

        // 5. 更新到数据库
        orderDao.update(targetOrderDo);
        
        // 6. 发送消息
        mq.push(message);

        return Result.success(true);
    }

}

可以看到,一段业务代码里经常包含了参数校验、数据读取、业务计算、调用外部服务等多种逻辑。在这个案例里虽然是写在了同一个方法里,在真实代码中经常会被拆分成多个子方法,但实际效果是一样的,而在我们日常的工作中,绝大部分代码都或多或少的接近于此类结构。虽然这种类似于脚本的写法在功能上没有什么问题,但是长久来看,他有以下几个很大的问题:可维护性差、可扩展性差、可测试性差。

问题1-可维护性能差

一个应用最大的成本一般不是来自于开发阶段,而是应用整个生命周期的总维护成本,所以代码的可维护性代表了最终成本。

**可维护性 = 当依赖变化时,有多少代码需要随之改变**

参考以上的案例代码,上述脚本类的代码很难维护因为以下几点:

数据结构的不稳定性:OrderDO类是一个纯数据结构,映射了数据库中的一个表。这里的问题是数据库的表结构和设计是应用的外部依赖,长远来看都有可能会改变,比如数据库要做Sharding,或者换一个表设计,或者改变字段名。

依赖库的升级:AccountMapper依赖MyBatis的实现,如果MyBatis未来升级版本,可能会造成用法的不同(可以参考iBatis升级到基于注解的MyBatis的迁移成本)。同样的,如果未来换一个ORM体系,迁移成本也是巨大的。

计算逻辑的的不确定性:比如微信的服务费率计算未来很有可能会有变化,而且下单的服务费率也不仅仅是微信的,后面可能还需要计算支付宝的,甚至整个服务费率计算逻辑会推倒重来。

第三方服务API的

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值