****说起策略模式,我相信,只要学过JAVA的小伙伴都应该接触过,但是很少有同学能在实际开发中运用到策略模式,今天呢,我给大家讲讲用Springboot+DB去实现这个策略模式思想。 话不多说,直接上干货,请看代码:
public String toPayHtml2(String payCode){
if(payCode.equals("ali_pay")){
return "调用支付宝接口...";
}
if(payCode.equals("xiaomi_pay")){
return "调用小米支付接口";
}
if(payCode.equals("yinlian_pay")){
return "调用银联支付接口...";
}
return "未找到该接口...";
}
我相信大家在平时写代码过程中,肯定会遇到这种多重的if判断,这样写代码,是不是不利于维护,扩展性极差。一个高级开发是肯定不会这么写代码的,那么想要完成这个功能,又要写出优雅的代码,别无选择,只能运用设计模式喽。、
现在开始正式全面剖析设计模式之策略模式
第一步:大家想一个问题,支付宝,银联,微信等是不是都是结算这个行为?既然他们都要实现结算功能,只是实现代码逻辑不同,大家想一想,这。是不是就是OOP里面的接口和实现类呢?定义接口,写抽象方法,然后实现类去实现该接口,并且重写抽象方法,这不就是多态的表现形式嘛?是不是同学们?现在呢,我们讲了半天,话不多说,直接上码:
public interface PayStrategy {
String Payhtml();
}
这个就是支付的一个结算渠道。
下面呢就是他们的实现类,分别是,银联和支付宝
@Component
public class AliPayStrategy implements PayStrategy {
public String Payhtml(){
return "支付宝接口";
}
}
@Component
public class YinLianPayStrategy implements PayStrategy {
public String Payhtml(){
return "银联接口";
}
}
第二步:直接上数据库
(1)这是实体类:
@Data
public class payEntity {
/** ID */
private Integer id;
/** 渠道名称 */
private String channelName;
/** 渠道ID */
private String channelId;
/**
* 策略执行beanId
*/
private String strategyBeanId;
}
(2)这是对应的数据库
(3)这是Mapper接口以及Sql,我是通过传入payCode去数据库中获取对应的CHANNEL_ID
public interface PaymentChannelMapper {
@Select("\n" +
"SELECT id as id ,CHANNEL_NAME as CHANNELNAME ,CHANNEL_ID as CHANNELID,strategy_bean_id AS strategybeanid\n" +
"FROM payment_channel where CHANNEL_ID=#{payCode}")
public payEntity getPaymentChannel(String payCode);
}
第三步:创建SpringUtils用来获取对应的Bean对象,这个网上到处都是,没必要去理解,只要知道他是获取Bean对象就可以了。
**private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
//获取applicationContext
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
//通过name获取 Bean.
public static Object getBean(String name){
return getApplicationContext().getBean(name);
}
//通过class获取Bean.
public <T> T getBean(Class<T> clazz){
return getApplicationContext().getBean(clazz);
}
//通过name,以及Clazz返回指定的Bean
public static <T> T getBean(String name,Class<T> clazz){
return getApplicationContext().getBean(name, clazz);
}
第四步,这是最重要的一步,这里会有点绕,我会讲解的让你们都可以听懂
**
@Autowired
private PaymentChannelMapper channelMapper;
@Autowired
private SpringUtils springUtils;
public String Pay(String payCode){
payEntity entity =channelMapper.getPaymentChannel(payCode);
if (entity==null){
return "没有该支付渠道";
}
String beanId=entity.getStrategyBeanId();
if(springUtils.equals("")){
return "该渠道没有配置BeanId";
}
PayStrategy payStrategy=springUtils.getBean(beanId,PayStrategy.class);
return payStrategy.Payhtml();
}**
以上是整个的上下文代码。
分段讲解:
(1) payEntity entity =channelMapper.getPaymentChannel(payCode);
这段代码是通过mapper接口去获取对应的payCode,也就是数据库中的CHANNEL_ID这个字段。
(2) String beanId=entity.getStrategyBeanId();
这段代码是获取到这个这个数据库字段strategy_bean_id,他对应的是实体类中StrategyBeanId。
(3)PayStrategy payStrategy=springUtils.getBean(beanId,PayStrategy.class);
这段代码是通过springUtils这个获取bean对象的类去获取beanId,并且加载这个对象,我来画图解说吧
第五步:这是最简单的了,就是到controller层,直接上代码
@Autowired
private PayContextStrategy payContextStrategy;
@Autowired
private SpringUtils springUtils;
@RequestMapping("/payHtml")
public String Code(String payCode){
if(springUtils.equals("")){
return "渠道code不能为空";
}
return payContextStrategy.Pay(payCode);
}
**这个我相信大家都能看得懂吧,我就不用解释了吧。**
最后,我们来看最终运行效果,接下来,就是见证奇迹的时刻啦: