干货 | 后微服务时代,领域驱动设计在携程国际火车票的实践

作者简介

 

Ma Ning,携程国际火车票后端开发工程师,关注系统架构、微服务、高可用等技术领域。


一、前言

领域驱动设计(Domain-Driven Design,简称 DDD)是一种软件开发设计思想,其旨在以领域为核心,让软件系统在实现时准确地基于对真实业务过程的建模,专注于业务问题域的需要。

DDD将软件系统设计分为了2个部分:战略设计和战术设计,战略设计用于提炼问题域并塑造应用程序的架构,战术设计用于帮助创建用于复杂有界上下文的有效模型。基于此,DDD强调专注于核心领域,通过协作对公共语言和知识进行提炼,并且持续致力于领域的知识提炼,让模型持续发展。

本文基于DDD思想,在携程国际火车票中台预订系统项目进行实践。


二、实践背景

本文以国际火车票中台预订系统项目的创单流程为例,其服务结构下图所示:

伪代码如下所示:

@Override
protected CreateOrderResponse execute(CreateOrderRequest request) {
    // 1、参数校验
    if (!validate(request)) {
        throw new BusinessException(P2pBookingResultCode.PARAM);
    }
    if (orderMapper.select(request.getOrderId()) != null) {
        throw new BusinessException(P2pBookingResultCode.ORDER_EXISTS);
    }
    
    // 2、初始化订单
    OrderDao orderDao = new OrderDao();
    orderDao.setOrderId(request.getOrderId());
    orderDao.setOrderStatus(100);
    orderMapper.insert(orderDao);
    // 初始化乘客信息
    PassengerDao passengerDao = new PassengerDao();
    ...
    passengerMapper.insert(passengerDao);
    
    // 3、转换汇率
    ExchangeRate exchangeRate = exchangeService.getExchangeRate(originCurrency, targetCurrency);
    
    // 4、购买保险
    if (isBuyInsurance(request)) {
        // 调用保险服务
        InsuranceInfo insuranceInfo = insuranceService.buyInsurance(request);
        // 保存保险信息
        InsuranceDao insuranceDao = new InsuranceDao();
        ...
        insuranceMapper.insert(insuranceDao);
    }
    
    // 5、供应商创单
    SupplierOrder supplierOrder = supplierService.createOrder(request, exchangeRate);
    // 保存供应商订单信息
    SupplierOrderDao supplierOrderDao = new SupplierOrderDao();
    ...
    supplierOrderMapper.insert(SupplierOrderDao);
    
    // 6、保存订单信息
    orderDao = new orderDao();
    orderDao.setOrderId(request.getOrderId);
    orderDao.setOrderStatus(OrderStatusEnum.WAIT_FOR_PAY.getCode());
    ...
    orderMapper.update(orderDao);
    
    // 7、发送超时支付取消消息
    messageProducer.push(MessageQueueConstants.TOPIC_TIMEOUT_CANCEL, "orderId", String.valueOf(orderDao.getOrderId()), appSettingProp.getTimeoutMinutes(), TimeUnit.MINUTES);
    
    // 8、返回结果
    return mappingResponse(orderDao, orderInsuranceEntity, exchangeRateResponse);
}

2.1 控制层臃肿

在传统的互联网软件架构中,通常都会采用MVC三层架构,其是一种古老且经典的软件设计模式,基于分层架构的思想,将整个程序分为了Model、View和Controller三层:

  • Model(模型层):最底下一层,是核心的数据,也就是程序需要操作的数据或信息;

  • View(视图层):最上面一层,直接面向最终用户的视图,它是提供给用户的操作界面,是程序的外壳;

  • Controller(控制层):中间的一层,就是整个程序的逻辑控制核心,它负责根据视图层输入的指令选取数据层的数据,然后对其进行相应操作产生最终结果;

MVC三层架构模式,将软件架构分为了三层,就可以让软件实现模块化,使三层相互独立,修改外观或者变更数据都不需要修改其他层,方便了维护和升级。但是这种软件架构中模型层只关注数据,控制层只关注行为,随着迭代的不断演化,业务逻辑越来越复杂,便会导致整个控制层的代码量越来越多,而模型层和视图层的变更却很少,最终导致整个控制层变得十分臃肿,从而失去了分层的意义。


2.2 过度耦合

在业务初期,程序的功能都非常简单,此时系统结构逻辑是清晰的,但是随着程序的不断迭代,一方面会导致业务逻辑越来越复杂,系统逐渐冗余,模块之间彼此关联,软件架构设计模式逐渐向“大泥球”模式(BBoM,Big Ball of Mud)发展;另一方面系统会调用越来越多的第三方服务,从而导致数据格式不兼容,业务逻辑无法复用。

在出票系统中,除了订单相关的功能外,还包括了保险、汇率、供应商订单

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值