订单接收不同业务消息设计

一,业务场景

消息下发到订单系统,不同的消息代表不同的订单业务逻辑

二,业务设计思路

1.关于消息:应该统一个格式,比如消息是xml或者json,应该定义统一的消息结构,方便后续统一解析处理

2.相同的处理逻辑:拿到消息后,需要统一解析处理,解析出核心业务消息体,传入相应业务处理逻辑

3.不同的逻辑:不同的消息,对应不同的业务处理逻辑

4.怎么区分不同的消息:发送消息时,定义一个参数如:tags,区分不同的业务消息

5.不同的消息怎么进入对应的业务处理中:根据tags,取到实现类

三,代码设计思路

代码:

1.接口

public interface BmsService {

    boolean execute(EccMessageReqVO eccMessageReqVO) throws Exception;

    BmsServiceEnum getType();
}

2.抽象类

@Component
@Slf4j
public abstract class AbstractBmsService implements BmsService {

    private static final String SHEET = "SHEET";

    @Override
    @Transactional
    public boolean execute(EccMessageReqVO eccMessageReqVO) throws Exception {
	log.info("执行ecc-bms-mq消费消息service:{},入参:{}", eccMessageReqVO.getEccServiceName(),
			JSON.toJSONString(eccMessageReqVO));
	String message = eccMessageReqVO.getMessage();
	//	JSONObject obj = JSON.parseObject(message).getJSONObject(SHEET);
	//	if (Objects.nonNull(obj)) {
	//	    String msg = JSON.toJSONString(obj);
	//	    eccMessageReqVO.setMessage(msg);
	//	}
	this.process(eccMessageReqVO);
	return true;
    }

    public abstract void process(EccMessageReqVO eccMessageReqVO) throws Exception;

}

 3.实现类

@Service
@Slf4j
public class ECCBMS152ServiceImpl extends AbstractBmsService {

    @Override
    public void process(EccMessageReqVO eccMessageReqVO) throws Exception {
	String msaage = eccMessageReqVO.getMessage();
	log.info("ECCBMS152 message: {}", msaage);
	return;
    }

    @Override
    public BmsServiceEnum getType() {
	return BmsServiceEnum.ECC_BMS152;
    }
}

设计模式:策略 +工厂+模板

类与接口:

一个接口:抽象类实现该接口,接口中包含两个方法,模板方法:抽象类实;区分不同业务类方法:子类实现

一个抽象类:解决上述2.3问题,共同的解析逻辑在抽象类中公共方法实现,定义一个抽象接口由不同业务实现类实现。方法:模板方法:处理共同逻辑; 抽象方法:子类实现

多个业务实现类:解决上述3,5问题,继承抽象类,实现抽象类中抽象方法:实现自己的业务;实现接口中方法:标记实现类本身,用于后续获取具体实现类

设计模式体现:

1.模板方法模式:抽象类:模板方法实现公共逻辑,抽象方法实现具体逻辑,

模板方法模式(模板方法设计模式)详解

2.策略模式:定义一个接口,不同子类实现自己类型逻辑

策略模式(策略设计模式)详解

3.抽象工厂:实现自己类型逻辑模型,也可以理解为抽象工厂。与策略很相似

抽象工厂模式(详解版)

抽象工厂简介:

抽象工厂模式同工厂方法模式一样,也是由抽象工厂、具体工厂、抽象产品和具体产品等 4 个要素构成,但抽象工厂中方法个数不同,抽象产品的个数也不同。现在我们来分析其基本结构和实现方法。

抽象工厂模式的主要角色如下。

  1. 抽象工厂(Abstract Factory):提供了创建产品的接口,它包含多个创建产品的方法 newProduct(),可以创建多个不同等级的产品。
  2. 具体工厂(Concrete Factory):主要是实现抽象工厂中的多个抽象方法,完成具体产品的创建。
  3. 抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能,抽象工厂模式有多个抽象产品。
  4. 具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间是多对一的关系。

抽象工厂与代码对应关系

1.抽象工厂:对应接口

2.具体工厂:对应实现类

3.抽象产品:对应枚举类,接口中返回的枚举类

public enum BmsServiceEnum implements GenericStringEnum {

    ECC_BMS110("ECC_BMS110", "退货申请单上传-生鲜"),
    ECC_BMS110A("ECC_BMS110A", "退货申请单上传-食品用品"),

4.具体产品:子类接口中返回的具体商品,如:

 public BmsServiceEnum getType() {
	return BmsServiceEnum.ECC_BMS152;
    }

四,上述第二点业务逻辑中第五点问题具体实现

利用多态,项目启动时,把所有实现类,存储到map中,key:枚举类,value:接口。消息下发时,根据tags取对应枚举,再根据枚举获取对应实现类,执行相应业务逻辑

@Component
public class BmsServiceSelector implements InitializingBean {

    private static final Map<BmsServiceEnum, BmsService> serviceMap = new HashMap<>();

    @Resource
    private List<BmsService> EccServices;

    @Override
    public void afterPropertiesSet() {
	for (BmsService service : EccServices) {
	    serviceMap.put(service.getType(), service);
	}
    }

    public BmsService getService(BmsServiceEnum bmsServiceEnum) {
	if (null == bmsServiceEnum) {
	    throw new IllegalArgumentException("操作失败!");
	}
	return serviceMap.get(bmsServiceEnum);
    }
}

 

五,思考

模板与策略区别

1.模板定义的是抽象类,策略定义的是接口

2.与子类关系:

抽象类:子类的执行结果可能返回来影响抽象的中的逻辑,即把子类处理的结果作为抽象类中其他逻辑的参数,进一步处理。

策略:没有上述抽象类,反向影响的逻辑

策略与工厂区别

 相同点:都是通过定义接口实现

不同点:工厂涉及抽象产品,具体产品,通过多态体现;策略:上述实现通过枚举体现

理解错误的地方,欢迎留言指正交流,谢谢!

おすすめ

転載: blog.csdn.net/C18298182575/article/details/120767400