java策略模式 动态_Java 策略模式

什么是策略模式?

策略模式就是对算法的包装,是把使用算法的责任和算法本身分割开来,委派给不同的对象管理,最终可以实现解决多if重判断问题。

实现过程

定义策略接口->实现不同的策略类->利用多态或其他方式调用策略. .

1.环境(Context)角色:持有一个Strategy的引用。。

2.抽象策略(Strategy)角色:这是一个抽象角色,通常由一个接口或抽象类实现。此

出所有的具体策略类所需的接口。。

3.具体策略(ConcreteStrategy)角色:包装了相关的算法或行为。。

优点

维护性增强,扩展性增强,提高可读性。

缺点

后期维护不通的策略类非常多、代码量增大

总结

优点大于缺点。

案例聚合支付

前提

如若正常聚合支付,一个接口方法中会有多重判断,调用支付宝,调用微信,调用银联。。。。

如若想要扩展内容首先就要更改这些判断,而这里面的每一个方法都有大量逻辑,一不小心就会牵一发而动全身,而使用策略模式的目的就是增强接口扩展性

定义支付算法共同骨架,PayStrategy

/*

* 共同算法定义骨架

*

* */

public interface PayStrategy {

/*共同算法骨架*/

public String toPayhtml();

}

定义对应实现类这里只是简单模拟返回

/*阿里支付算法*/

@Component

public class AliPayStrategy implements PayStrategy {

@Override

public String toPayhtml() {

return "调用支付宝支付方法";

}

}

/*银联支付算法*/

@Component

public class YinLianPayStrategy implements PayStrategy {

@Override

public String toPayhtml() {

return "调用银联支付方式";

}

}

新建数据库用于存储支付方式以及对应实现类,创建Dao层获取数据这里是用Mybatis实现Dao层

@Component

@Mapper

public interface PaymentChannelMapper {

@Select("SELECT * FROM payment_channel AS pay WHERE pay.payId = #{payCode}")

PaymentChannelEntity getPaymentChannel(String payCode);

}

//实体类

public class PaymentChannelEntity {

private String id;

private String payId;

private String payType;

public String getId() {

return id;

}

public void setId(String id) {

this.id = id;

}

public String getPayId() {

return payId;

}

public void setPayId(String payId) {

this.payId = payId;

}

public String getPayType() {

return payType;

}

public void setPayType(String payType) {

this.payType = payType;

}

}

获取SpringIOC容器工具类

/*使用Bend对象获取Spring容器中对应的类*/

@Component

public class SpringUtils implements ApplicationContextAware {

private static ApplicationContext context;

@Override

public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {

context = applicationContext;

}

/*获取context上下文*/

public static ApplicationContext getApplicationContext(){

return context;

}

/*通过name获取Bean*/

public static Object getBean(String name){

return getApplicationContext().getBean(name);

}

/*通过类名获取Bean*/

public static T getBean(Class className){

return getApplicationContext().getBean(className);

}

/*通过name,以及Class返回指定Bean*/

public static T getBean(String neme, Class className){

return getApplicationContext().getBean(neme,className);

}

}

新建.class作用于获取对象实现类

@Component

public class PayContextStrategy {

@Autowired

public PaymentChannelMapper paymentChannelMapper;

@Autowired

public SpringUtils springUtils;

public PayContextStrategy() {

super();

}

public String toPayHtml(String payCode){

System.err.println(payCode);

// 使用PayCode查询数据库获取Bendid

PaymentChannelEntity paymentChannel = paymentChannelMapper.getPaymentChannel(payCode);

// 获取bindid,使用spring容器获取实例方法

if (paymentChannel == null){

return "没有该渠道信息";

}

String strategyBeanId = paymentChannel.getPayType();

System.err.println(strategyBeanId);

if (StringUtils.isEmpty(strategyBeanId)){

return "该渠道配置ben配置";

}

PayStrategy payStrategy = springUtils.getBean(strategyBeanId,PayStrategy.class);

return payStrategy.toPayhtml();

};

}

新建.class 控制器作用于接口测试

@RestController

public class PayController {

@Autowired

private PayContextStrategy contextStrategy;

@GetMapping("/toPayHtml")

public String toPayHtml(String payCode){

if (StringUtils.isEmpty(payCode)){

return "渠道code不能为空";

}

return contextStrategy.toPayHtml(payCode);

}

}

总结

如若需要接入其他支付方式,则直接创建该支付的实现类存入数据库中,无需改动其他逻辑,这个使用数据库只是例子,可以使用枚举

案例思路

首先建立支付接口公共骨架,用于后期动态获取实现类→使用数据库存储实现类对象以及类型→查询数据库动态获取实现类→使用Spring获取支付类的具体实现→使用接口调用相关方法测试

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值