@Autowired ProductDao productDao; @Autowired UserDao userDao; public void createOrder(String productId,String userId,int count){ Product product = productDao.queryById(productId); UserInfo user=userDao.queryByUserId(userId); //堆代码 duidaima.com //风控检测 RiskResponse riskRes= riskClient.queryRisk(xxx); if(riskRes!=null&&riskRes.getCode()==0&&riskRes.getRiskCode().equal("0001")){ //命中风控 throw new BizException("下单失败,请检查网络") } Order order=new Order(); order.setOrderId(IdUtils.generateId()); order.setPrice(product.getPrice()*count); order.setAddress(user.getAddress()); order.setStatus(OrderEnum.OrderSucess); orderDao.insert(order); //预热缓存和增加记录 redisService.set("Order:OrderID_"+order.getOrderId(),order); orderLogDao.addLog(order); MessageEntity message = new MessageEntity(); message.setOrderId(order.getOrderId()); message.setMessage("下单成功"); kafkaSender.sent(messageEntity); }代码分析
5.发送订单下单成功消息,通知其他系统
riskRes!=null&&riskRes.getCode()==0&&(riskRes.getRiskCode().equal("0001")||riskRes.getRiskCode().equal("0002")||riskRes.getRiskCode().equal("0003")),然而,这种改动会使代码变得难以阅读和维护。每次接口变更,我们都需要在多处代码中进行类似的修改,而且这些修改会在整个代码库中产生涟漪效应,导致代码的耦合度上升,可维护性下降。
order.setOrderId(IdUtils.generateId()); order.setPrice(product.getPrice() * count);这两个赋值语句背后蕴含着更深层次的业务意义。其中,生成订单号是为了唯一标识每个订单,确保订单信息的准确无误;而计算订单价格则是根据产品数量和单价进行计算,确保订单金额的准确性。
5.领域间存在强耦合,对其他领域的修改容易对当前核心逻辑造成意外影响,增加系统的脆弱性和改动的风险。
@Service public class RiskCheckAdapter { @Autowired private RiskClient riskClient; public boolean isRiskDetected(String productId, String userId) { RiskResponse riskRes = riskClient.queryRisk(xxx); // 根据实际情况传入参数 return riskRes != null && riskRes.getCode() == 0 && riskRes.getRiskCode().equals("0001"); } } @Service public class RiskCheckService { @Autowired private RiskCheckAdapter riskCheckAdapter; public boolean isRiskCheckPassed(String productId, String userId) { return riskCheckAdapter.isRiskDetected(productId, userId); } }2. 仓储模式解耦数据访问
// IProductRepository.java public interface IProductRepository { Product findById(String productId); } // IUserRepository.java public interface IUserRepository { User findByUserId(String userId); } // IOrderRepository.java public interface IOrderRepository { Order add(OrderDO order); } // IOrderLogRepository.java public interface IOrderLogRepository { void addLog(OrderLogDO log); } // ProductRepository.java @Repository public class ProductRepository implements IProductRepository { @Autowired private ProductDao productDao; @Override public Product findById(String productId) { return productDao.queryById(productId); } } // UserRepository.java @Repository public class UserRepository implements IUserRepository { @Autowired private UserDao userDao; @Override public User findByUserId(String userId) { return userDao.queryByUserId(userId); } } // UserRepository.java @Repository public class OrderRepository implements IOrderRepository { @Autowired private OrderDao orderDao; @Autowired private OrderConvert orderConvert; @Override public int save(OrderDO order) { OrderPO orderPO=orderConvert.convertPO(order); return orderDao.insert(orderPO); } } // OrderLogRepository.java @Repository public class OrderLogRepository implements IOrderLogRepository { @Autowired private OrderLogDao orderLogDao; @Override public void addLog(OrderLog log) { orderLogDao.addLog(log); } }经过上面的组合后,我们可以看下前后的依赖对比,从图中可以看出,service层已经对数据不再有数据依赖。
public class Order { private String orderId; private int count; private double totalPrice; private String address; private int status; public void createOrder(Product product, User user, int count) { this.address = user.getAddress(); this.status = OrderEnum.OrderSuccess; this.generateOrderId(); this.calculateTotalPrice(product.getPrice(), count); } private void generateOrderId() { this.orderId = IdUtils.generateId(); } private void calculateTotalPrice(double price, int count) { this.count = itemCount; this.totalPrice = price * count; } // ...其他属性和方法 } public class OrderFactory { public static Order createOrder(Product product, User user, int itemCount) { Order order = new Order(); order.createOrder(product, user, itemCount); return order; } } //使用方式 Order order = orderFactory.createOrder(product, user, count); orderDao.insert(order);领域事件解耦领域间通信
// CommonEventListener.java @Service public class CommonEventListener { @Autowired private IOrderLogRepository orderLogRepository; @Autowired private RedisService redisService; @Autowired private KafkaSender kafkaSender; @EventListener public void handleOrderCreatedEvent(OrderCreatedEvent event) { String orderId = event.getOrderId(); Order order = getOrderDetailsFromRepository(orderId); // Process the event within the domain object order.processOrderCreatedEvent(orderLogRepository, redisService); sendMessage(order); } private Order getOrderDetailsFromRepository(String orderId) { // Retrieve order details from repository using orderId // Return the Order object } private void sendMessage(Order order) { MessageEntity message = new MessageEntity(); message.setOrderId(order.getOrderId()); message.setMessage("下单成功"); kafkaSender.send(message); } }优化后的核心业务代码
// OrderServiceImpl.java @Service public class OrderServiceImpl implements OrderService { @Autowired private ApplicationEventPublisher eventPublisher; @Autowired private IProductRepository productRepository; @Autowired private IUserRepository userRepository; @Autowired private IOrderRepository orderRepository; @Autowired private IOrderFactory orderFactory; @Autowired private RiskCheckService riskCheckService; @Override public Order createOrder(String productId, String userId, int count) { Product product = productRepository.findById(productId); User user = userRepository.findByUserId(userId); boolean isRiskPassed = riskCheckService.isRiskCheckPassed(); if (!isRiskPassed) { throw new BizException("下单失败,请检查网络"); } Order order = orderFactory.createOrder(product, user, count); orderRepository.save(order); // Publish OrderCreatedEvent eventPublisher.publishEvent(new OrderCreatedEvent(order.getOrderId())); return order; } }