适配器模式(不同类型的 MQ 消息 & 首次下单消息)

目录

定义

[适配不同类型的 MQ 消息](#适配不同类型的 MQ 消息)

注册开户MQ

内部订单MQ

第三⽅订单MQ

查询⽤户内部下单数量接⼝

查询⽤户第三⽅下单⾸单接⼝

MQ消息体适配类

代码实现

测试验证

接⼝使⽤适配

代码实现

分别实现两个不同的接⼝

内部商品接⼝

第三⽅商品接⼝

测试验证


定义

适配器模式的主要作⽤就是把原本不兼容的接⼝,通过适配修改做到统⼀。使得⽤户⽅便使⽤。

适配不同类型的 MQ 消息

做这样⼀个系统就会接收各种各样的MQ消息或者接⼝,如果⼀个个的去开发,就会耗费很⼤的成本,同时对于后期的拓展也有⼀定的难度。此时就会希望有⼀个系统可以配置⼀下就把外部的MQ接⼊进⾏,这些MQ就像上⾯提到的可能是⼀些注册开户消息、商品下单消息等等。

注册开户MQ

复制代码
public class create_account {
    private String number; // 开户编号
    private String address; // 开户地
    private Date accountDate; // 开户时间
    private String desc; // 开户描述
    // ... get/set 
}

内部订单MQ

复制代码
public class OrderMq {
    private String uid; // ⽤户ID
    private String sku; // 商品
    private String orderId; // 订单ID
    private Date createOrderTime; // 下单时间 
    // ... get/set 
}

第三⽅订单MQ

复制代码
public class POPOrderDelivered {
    private String uId; // ⽤户ID
    private String orderId; // 订单号
    private Date orderTime; // 下单时间
    private Date sku; // 商品
    private Date skuName; // 商品名称
    private BigDecimal decimal; // ⾦额
    // ... get/set 
}

查询⽤户内部下单数量接⼝

复制代码
public class OrderService {
    private Logger logger = LoggerFactory.getLogger(POPOrderService.class);
    public long queryUserOrderCount(String userId){
        logger.info("⾃营商家,查询⽤户的订单是否为⾸单:{}", userId);
        return 10L;
    }
}

查询⽤户第三⽅下单⾸单接⼝

复制代码
public class POPOrderService {
    private Logger logger = LoggerFactory.getLogger(POPOrderService.class);
    public boolean isFirstOrder(String uId) {
        logger.info("POP商家,查询⽤户的订单是否为⾸单:{}", uId);
        return true;
    }
}

MQ消息体适配类

代码实现

复制代码
public class MQAdapter {
    public static RebateInfo filter(String strJson, Map<String, String> link) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        return filter(JSON.parseObject(strJson, Map.class), link);
    }
    
    public static RebateInfo filter(Map obj, Map<String, String> link) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        RebateInfo rebateInfo = new RebateInfo();
        for (String key : link.keySet()) {
            Object val = obj.get(link.get(key));
            RebateInfo.class.getMethod("set" + key.substring(0, 1).toUpperCase() + key.substring(1), String.class).invoke(rebateInfo, val.toString());
        }
        return rebateInfo;
    }
}

主要⽤于把不同类型MQ种的各种属性,映射成我们需要的属性并返回。就像⼀个属性中有 ⽤户ID;uId ,映射到我们需要的; userId ,做统⼀处理。

测试验证

复制代码
@Test
public void test_MQAdapter() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
    create_account create_account = new create_account();
    create_account.setNumber("100001");
    create_account.setAddress("河北省.廊坊市.⼴阳区.⼤学⾥职业技术学院");
    create_account.setAccountDate(new Date());
    create_account.setDesc("在校开户"); 
    HashMap<String, String> link01 = new HashMap<String, String>();
    link01.put("userId", "number");
    link01.put("bizId", "number");
    link01.put("bizTime", "accountDate");
    link01.put("desc", "desc");
    
    RebateInfo rebateInfo01 = MQAdapter.filter(create_account.toString(), link01);
    System.out.println("mq.create_account(适配前)" + create_account.toString());
    System.out.println("mq.create_account(适配后)" + JSON.toJSONString(rebateInfo01));
    System.out.println("");
    
    OrderMq orderMq = new OrderMq();
    orderMq.setUid("100001");
    orderMq.setSku("10928092093111123");
    orderMq.setOrderId("100000890193847111");
    orderMq.setCreateOrderTime(new Date());
    HashMap<String, String> link02 = new HashMap<String, String>();
    link02.put("userId", "uid");
    link02.put("bizId", "orderId");
    link02.put("bizTime", "createOrderTime");
    RebateInfo rebateInfo02 = MQAdapter.filter(orderMq.toString(), link02);
    System.out.println("mq.orderMq(适配前)" + orderMq.toString());
    System.out.println("mq.orderMq(适配后)" + JSON.toJSONString(rebateInfo02));
}

接⼝使⽤适配

代码实现

复制代码
public interface OrderAdapterService {
    boolean isFirst(String uId);
}

分别实现两个不同的接⼝

内部商品接⼝
复制代码
public class InsideOrderService implements OrderAdapterService {
    private OrderService orderService = new OrderService();
    public boolean isFirst(String uId) {
        return orderService.queryUserOrderCount(uId) <= 1;
    }
}
第三⽅商品接⼝
复制代码
public class POPOrderAdapterServiceImpl implements OrderAdapterService {
    private POPOrderService popOrderService = new POPOrderService();
    public boolean isFirst(String uId) {
        return popOrderService.isFirstOrder(uId);
    }
}

测试验证

复制代码
@Test
public void test_itfAdapter() {
    OrderAdapterService popOrderAdapterService = new POPOrderAdapterServiceImpl();
    System.out.println("判断⾸单,接⼝适配(POP):" + popOrderAdapterService.isFirst("100001")); 
    OrderAdapterService insideOrderService = new InsideOrderService();
    System.out.println("判断⾸单,接⼝适配(⾃营):" + insideOrderService.isFirst("100001"));
}
相关推荐
一条泥憨鱼18 分钟前
【消息队列】ACK确认了什么:消息队列可靠投递的完整链路
java·后端·kafka·消息队列·rabbitmq
从琳开始9891 小时前
网络原理入门(二)------OSI七层模型?TCP/IP五层(四层)模型原来是这样的
java·网络·tcp/ip·java-ee·php
文丑颜不良啊1 小时前
LeetCode1861~1880题目解析
java·leetcode
Flynn Liang1 小时前
AgentScope Java 深度解析:ReActAgent、HarnessAgent 与多智能体编排——JVM 上的自治 Agent 底座
java·大模型·架构设计·ai agent·spring ai·langchain4j·agentscope
Flynn Liang1 小时前
上线后怎么排查 AI 调用?Spring AI Observability:token/延迟/成本埋点与全链路追踪
java·人工智能·spring·监控·可观测性·observability·springai
文丑颜不良啊1 小时前
LeetCode1921~1940题目解析
java·leetcode
Tt有了t2 小时前
设计模式速查
java·python·设计模式
Thomas.Sir2 小时前
第15课:SpringBoot连接池详解:HikariCP配置、调优、监控,4.x连接池新特性
java·spring boot
一条Go2 小时前
四个进程,一把锁:Alioth 的告警评测为什么不需要消息队列
后端·设计模式·架构
VimorphTech3 小时前
每批开 4 个线程,为什么限制不住 TTS 的总并发?
java·spring boot·spring