美文网首页
Java 策略模式

Java 策略模式

作者: 索性流年 | 来源:发表于2021-02-09 09:19 被阅读0次

文集地址

一句话总结策略模式

  • 主要是一对多,要是一个API需要多种实现方法,便用策略模式

什么是策略模式?

  • 策略模式就是对算法的包装,是把使用算法的责任和算法本身分割开来,委派给不同的对象管理,最终可以实现解决多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>T getBean(Class<T> className){
        return getApplicationContext().getBean(className);
    }

    /*通过name,以及Class返回指定Bean*/
    public static <T>T getBean(String neme, Class<T> 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获取支付类的具体实现→使用接口调用相关方法测试

相关文章

  • java建造者模式

    其他设计模式java单例模式java建造者模式java策略模式java代理模式java观察者模式java适配器模式...

  • java单例模式

    其他设计模式java单例模式java建造者模式java策略模式java代理模式java观察者模式java适配器模式...

  • java外观模式

    其他设计模式java单例模式java建造者模式java策略模式java代理模式java观察者模式java适配器模式...

  • java适配器模式

    其他设计模式java单例模式java建造者模式java策略模式java代理模式java观察者模式java适配器模式...

  • java观察者模式

    其他设计模式java单例模式java建造者模式java策略模式java代理模式java观察者模式java适配器模式...

  • java代理模式

    其他设计模式java单例模式java建造者模式java策略模式java代理模式java观察者模式java适配器模式...

  • java策略模式

    其他设计模式java单例模式java建造者模式java策略模式java代理模式java观察者模式java适配器模式...

  • Java8之被简化的设计模式

    Java8命令模式简化 策略模式

  • Kotlin设计模式之策略模式

    简单介绍下用Kotlin写的策略模式,还有就是与Java版本的对比。 Kotlin Java 输出 实现策略模式时...

  • 设计模式 | 策略模式及典型应用

    本文的主要内容: 介绍策略模式 示例商场购物打折策略的实现 策略模式总结 源码分析策略模式的典型应用Java Co...

网友评论

      本文标题:Java 策略模式

      本文链接:https://www.haomeiwen.com/subject/acepactx.html