请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

聚合的业务代码和资源库更新代码如何统一?

问题一:
修改订单状态与当前业务相关字段, 通过实体方法修改字段值, 最后由应用层调用资源仓库进行保存
那么是否就要求资源仓库的更新方法需要和实体方法进行一对一编码?

比如当领域层通过业务分支if else做出部分字段的修改
在资源库中如何识别哪些字段需要更新?
采用null判断也不行, 因为实体设计时字段是基础类型, 默认值是0

例子(写了代码注释):

应用层

  @Override
  @Transactional
  public void run(Map<String, Object> params) {
    DeviceFailureEvent event = (DeviceFailureEvent) params.get("event");
    SlotVendingMachine machine = machineRepository.getSlotVendingMachineById(
        event.getMachineId());
    LOGGER.info("running: {}", event.toString());
    if (machine.getCurOrder() != null
        && machine.getCurOrder().getOrderId() == event.getOrderId()) {
      machine.cancelOrder();
    } else {
      Order order = orderRepository.getOrderById(event.getOrderId());
      order.cancel();
      orderRepository.updateOrder(order);
    }
  }

领域层

  public void cancel() {
    state = OrderState.Canceled;
    // 当业务复杂时可能会存在 if else
    if (某个渠道) {
	    // 更新字段a
	    a = 1;
	} else if (特别渠道) {
		// 更新字段b
		b = 2;
	}
    eventBus.post(new OrderCanceledEvent(this));
  }

资源库

  @Override
  public void updateOrder(Order order) {
    OrderDo orderDo = new OrderDo();
    orderDo.setOrderId(order.getOrderId());
    orderDo.setState(order.getState().code());
    orderDo.setPaymentId(order.getPaymentId());
    // 到了资源库, 因为字段更新判断是在domain层修改的
    // 这里就不知道应该更新字段 a 还是 字段 b了
    orderDo.setA(order.getA())?
    orderDo.setB(order.getB())?
    orderMapper.updateStateAndPayment(orderDo);
  }

正在回答 回答被采纳积分+3

插入代码

1回答

尤达_技术咖啡 2022-04-14 21:08:25

如果不是性能要求极高,直接统一更新所有字段就好了(也有部分存储层中间件可以识别哪些字段有变更)。如果性能要求极高,而且存储底层不支持仅更新脏字段,也可以自己实现(无非就是在内存作标记,每个字段对应一个脏位)。这个问题在qq群里有过讨论,而且也有同学给出过方案,可以加qq群参与讨论。

0 回复 有任何疑惑可以回复我~
  • 提问者 qq_慕丝0528892 #1
    我已经加群了, 但是之前讨论的记录我看不到, 不知道这个内存标记的实现方案是什么? 通过ThreadLoacl完成?
    还有什么别的方案吗?
    我遇到的业务需要很高的性能, 因为实体字段太多, 特殊场景查询和更新都需要精确到部分字段查询和更新, 这类项目的场景能多提供一些既能兼顾性能又符合DDD设计的经验吗?
    回复 有任何疑惑可以回复我~ 2022-04-16 01:55:14
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信