一文告诉你策略模式(设计模式学习)

策略模式

定义一个算法家族,分别封装,让他们互相之间替换,解决if…else和switch语句

策略模式优缺点

优点:上下文和具体策略是松耦合关系
缺点: 1. 客户端必须知道有哪些策略,并且自行决定使用哪种策略
2. 增加许多类,增加维护难度

spring中的使用策略模式

方式一:使用注解
详见代码strategy模块 com.su.example.annotation.demo
支付注解-只要有这个注解则代表他是该策略

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface PayStrategyType {
    PayTypeEnum value();
}

支付类型枚举

public enum PayTypeEnum {
    ALI_PAY(1,"阿里支付"),
    WEIXIN_PAY(2,"微信支付"),
    UNION_PAY(3,"银联"),
    ;
    private Integer code;
    private String  msg;

    PayTypeEnum(Integer code, String msg) {
        this.code = code;
        this.msg = msg;
    }
}

扫描所有支付注解,将支付service放入一个map

@Component
@Order
public class HandlerPayMoneyStrategyProcessor implements ApplicationContextAware {

    /**
     * 获取所有的策略 加入HandlerOrderContext属性中
     * @param applicationContext
     */
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        //获取所有策略注解的Bean
        Map<String, Object> beanMap = applicationContext.getBeansWithAnnotation(PayStrategyType.class);
        PayMoneyStrategyContext bean = applicationContext.getBean(PayMoneyStrategyContext.class);
        beanMap.forEach((k,v)->{
            PayTypeEnum type = AopUtils.getTargetClass(v).getAnnotation(PayStrategyType.class).value();
            //将class加入map中,type作为key
            bean.getPayMoneyStrategyMap().put(type,(IPayMoneyStrategy) v);
        });
    }
}

策略的接口

public interface IPayMoneyStrategy {
    /**
     * 付钱
     * @param money
     */
    void payMoney(BigDecimal money);
}

策略的实现-阿里

@Component
@PayStrategyType(PayTypeEnum.ALI_PAY)
public class AliPayStrategyImpl implements IPayMoneyStrategy {

    @Override
    public void payMoney(BigDecimal money) {
        System.out.println("我是阿里支付生成金额为:"+ money +"流水开始支付");
    }
}

策略的实现-微信

@Component
@PayStrategyType(PayTypeEnum.WEIXIN_PAY)
public class WeixinPayStrategyImpl implements IPayMoneyStrategy {

    @Override
    public void payMoney(BigDecimal money) {
        System.out.println("我是微信支付生成金额为:"+ money +"流水开始支付");
    }
}

方式二:使用统一的config类注入
注入类

public class MapHandlerPayMoneyStrategyProcessor {

    @Resource
    IMapPayMoneyStrategy mapAliPayStrategyImpl;
    @Resource
    IMapPayMoneyStrategy mapUnionPayStrategyImpl;
    @Resource
    IMapPayMoneyStrategy mapWeixinPayStrategyImpl;

    @Bean("payMoneyStrategyMap")
    public Map<PayTypeEnum, IMapPayMoneyStrategy> createPayMoneyStrategyMap() throws BeansException {
        Map<PayTypeEnum, IMapPayMoneyStrategy> payTypeEnumIMapPayMoneyStrategyHashMap = new HashMap(8);
        payTypeEnumIMapPayMoneyStrategyHashMap.put(PayTypeEnum.ALI_PAY,mapAliPayStrategyImpl);
        payTypeEnumIMapPayMoneyStrategyHashMap.put(PayTypeEnum.UNION_PAY,mapUnionPayStrategyImpl);
        payTypeEnumIMapPayMoneyStrategyHashMap.put(PayTypeEnum.WEIXIN_PAY,mapWeixinPayStrategyImpl);
        return payTypeEnumIMapPayMoneyStrategyHashMap;
    }
}

方式三:工厂策略模式
工厂

@Component
public class FactoryPayMoneyStrategyContext {

    /**
     * 对外统一暴露服务
     */
    public void strategyManage(PayTypeEnum payType, BigDecimal money) {
        IFactoryPayMoneyStrategy iFactoryPayMoneyStrategy;
        switch (payType){
            case ALI_PAY:
                iFactoryPayMoneyStrategy =  new FactoryAliPayStrategyImpl();
                break;
            case WEIXIN_PAY:
                iFactoryPayMoneyStrategy = new FactoryWeixinPayStrategyImpl();
                break;
            case UNION_PAY:
                iFactoryPayMoneyStrategy = new FactoryUnionPayStrategyImpl();
                break;
            default: throw new RuntimeException("找不到的服务");
        }
        iFactoryPayMoneyStrategy.payMoney(money);
    }

}

其他大同小异

调用:

		ApplicationContext applicationContext = ApplicationHolder.getApplicationContext();
		PayMoneyStrategyContext bean = applicationContext.getBean(PayMoneyStrategyContext.class);
		System.out.println("注解模式---------------------------");
		bean.strategyManage(PayTypeEnum.ALI_PAY, BigDecimal.TEN);
		bean.strategyManage(PayTypeEnum.WEIXIN_PAY, BigDecimal.TEN);
		bean.strategyManage(PayTypeEnum.UNION_PAY, BigDecimal.TEN);
		System.out.println("map模式---------------------------");
		MapPayMoneyStrategyContext mapBean = applicationContext.getBean(MapPayMoneyStrategyContext.class);
		mapBean.strategyManage(PayTypeEnum.ALI_PAY, BigDecimal.TEN);
		mapBean.strategyManage(PayTypeEnum.WEIXIN_PAY, BigDecimal.TEN);
		mapBean.strategyManage(PayTypeEnum.UNION_PAY, BigDecimal.TEN);
		System.out.println("工厂策略模式---------------------------");
		FactoryPayMoneyStrategyContext factoryBean = applicationContext.getBean(FactoryPayMoneyStrategyContext.class);
		factoryBean.strategyManage(PayTypeEnum.ALI_PAY, BigDecimal.TEN);
		factoryBean.strategyManage(PayTypeEnum.WEIXIN_PAY, BigDecimal.TEN);
		factoryBean.strategyManage(PayTypeEnum.UNION_PAY, BigDecimal.TEN);

PS: git代码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值