策略模式+spring

策略模式的使用

简介:策略模式主要是指对象有某个行为,但是在不同的场景中,该行为有不同的实现算法。
下面我刚做需求,根据不同的交易类型发送不同的通知给商户。

需求:扫描商户订单给商户发送通知,不同的交易类型,有不同通知报文。

比如:TX(提现),CZ(充值)

重构前的代码:
if(order.getTp().eqults("TX")){
    //发送提现通知
}else if(order.getTp().eqults("CZ")){
    //发送充值通知
}else if ....

重构前很多if,else,假如再增加一个交易类型,那么又需要新增一个if,很明显违背了"开闭原则",即对新增开放,对修改关闭。重构前整个通知系统有10多种通知,而且以后可能持续增加,开发维护都越来越困难。

重构:

首先观察一下,这段共同的行为是发送通知,但是不同的业务,有不同的发送报文。将组发送报文的代码抽象出来,刚好用得上策略模式。

参数策略接口

/**
 * 发关参数策略接口
 */
public  interface IPostParamStrategy {
	PostParamData genParam(TAccountTxnLog tAccountTxnLog)
}

提现参数策略

/**
 * 提现参数策略
 */
public class CashoutPostParamStrategy implements IPostParamStrategy {
	@Override
	public PostParamData genParam(TAccountTxnLog tAccountTxnLog) throws FuiouException {
    	PostParamData resData = new PostParamData();
    	resData.setPostJson(genJson(tAccountTxnLog));//设置提现post报文
    	resData.setPostUrl(getTxUrl());//设置提现通知地址
        return resData;
	}
}

充值参数策略

/**
 * 充值参数策略
 */
public class RechargePostParamStrategy implements IPostParamStrategy {
	@Override
	public PostParamData genParam(TAccountTxnLog tAccountTxnLog) throws FuiouException {
    	PostParamData resData = new PostParamData();
    	resData.setPostJson(genJson(tAccountTxnLog));//设置充值具体post报文
    	resData.setPostUrl(getCzUrl());//设置充值通知地址
        return resData;
	}
}

策略环境(策略的调用)

/**
 * 策略环境(策略的调用)
 */
public class PostParamContext {
	private static Map<String, IPostParamStrategy> paramStrategyMap;

	public static IPostParamStrategy getStrategy(String urlTp) throws FuiouException {
		for (String key : paramMapStrategy.keySet()) {
			if (urlTp.equals(key)) {
				return paramMapStrategy.get(key);
			}
		}
		throw new FuiouException("未找该通知类型,请确认请求参数urlTp");
	}

	public void setParamStrategyMap(Map<String, IPostParamStrategy> paramStrategyMap) {
		PostParamGenGenerator.paramStrategyMap = paramStrategyMap;
	}
}

主程序

//主程序
List<TAccountTxnLog> txnLogs = TAccountTxnLogMapper.listUnNotifyData();
for(TAccountTxnLog txnData : txnLogs){
    //获取通知参数
    PostParamData paramData = PostParamContext.getStrategy(txnData.getBusiTp()).genParamStrategy(txnData);
    HttpClint.post(paramData.getPostUrl(),paramData.getPostJson());
    
}

post参数生成器中PostParamGenGenerator的paramMap用spring注入

	<bean class="com.fuiou.jzh.notify.core.assembler.PostParamContext">
	   <property name="paramStrategyMap">
	       <map>
	           <entry key="CZ" value-ref="rechargePostParamStrategy" />
	           <entry key="TX" value-ref="cashoutPostParamStrategy" />
	       </map>
	   </property>
总结:

重构后,如果再加一个通知类型,只需要新增一个类,实现IPostParamStrategy接口,另外配置文件上加一个类型就可以了,开发效率大大提高,代码也非常简洁,并且新的通知类型即使代码有问题,也完全不会影响老的业务通知。

Spring Boot 中使用策略模式结合 Map 的方式,你可以按照以下步骤进行实现: 1. 首先,定义一个接口,表示策略模式的抽象策略,例如: ```java public interface Strategy { String execute(); } ``` 2. 创建具体的策略类实现接口,例如: ```java @Component public class StrategyA implements Strategy { @Override public String execute() { return "执行策略A"; } } @Component public class StrategyB implements Strategy { @Override public String execute() { return "执行策略B"; } } ``` 3. 在使用策略的地方,注入策略类的集合,并通过 Map 存储,将策略类的名称作为键,策略类对象作为值,例如: ```java @Service public class StrategyService { private final Map<String, Strategy> strategyMap; public StrategyService(List<Strategy> strategyList) { this.strategyMap = new HashMap<>(); for (Strategy strategy : strategyList) { strategyMap.put(strategy.getClass().getSimpleName(), strategy); } } public String executeStrategy(String strategyName) { Strategy strategy = strategyMap.get(strategyName); if (strategy != null) { return strategy.execute(); } return "未找到对应的策略"; } } ``` 4. 在使用策略的地方调用 `executeStrategy()` 方法,并传入对应的策略名称,例如: ```java @RestController public class StrategyController { private final StrategyService strategyService; public StrategyController(StrategyService strategyService) { this.strategyService = strategyService; } @GetMapping("/execute/{strategyName}") public String executeStrategy(@PathVariable String strategyName) { return strategyService.executeStrategy(strategyName); } } ``` 这样,当访问 `/execute/StrategyA` 接口时,会执行策略A;访问 `/execute/StrategyB` 接口时,会执行策略B。你可以根据实际需求进行调整和扩展。希望对你有帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值