Java设计模式中的策略(Strategy)模式解读

 更新时间:2023年10月09日 10:19:19   作者:闪耀的瞬间  
这篇文章主要介绍了Java设计模式中的策略(Strategy)模式解读,对象的某个行为,在不同场景有不同实现方式,可以将这些行为的具体实现定义为一组策略,每个实现类实现一种策略,在不同场景使用不同的实现,并且可以自由切换策略,需要的朋友可以参考下

Java的策略模式

策略(Strategy)模式:分离算法,选择实现 比如对象的某个行为,在不同场景有不同实现方式,可以将这些行为的具体实现定义为一组策略,每个实现类实现一种策略,在不同场景使用不同的实现,并且可以自由切换策略,但太多的策略会导致大量代码

  • 优点:
    • 不用太多if else
    • 代码优雅、简单
    • 符合开闭原则,扩展性好、便于维护
  • 缺点:
    • 策略如果很多的话,会造成策略类膨胀
    • 使用者必须清楚所有的策略类及其用途

如:电商活动打折,普通会员9折,黄金会员8折,钻石会员7折

1.定义一个Strategy接口,只有打折方法

2.增加3个打折类,对应9折、8折、7折

3.客户端根据会员类型,获取具体的策略算法实现类,再执行打折方法

在这里插入图片描述

策略模式与Spring结合

/**
 * 打折策略枚举
 */
public enum ActivityStrategyEnum {
    MEMBER(1, "普通会员"),
    GOLD_MEMBER(2, "黄金会员"),
    DIAMOND_MEMBER(3, "钻石会员"),
    ;
    private int code;
    private String name;
    ActivityStrategyEnum (int code, String name) {
        this.code = code;
        this.name = name;
    }
    /**
     * 通过code匹配对应枚举
     * @param code
     * @return
     */
    public static ActivityStrategyEnum match(int code){
        ActivityStrategyEnum strategyEnum = null;
        for (ActivityStrategyEnum item : values()){
            if(item.getCode() == code){
                strategyEnum = item;
                break;
            }
        }
        return strategyEnum;
    }
    public int getCode() {
        return code;
    }
    public String getName() {
        return name;
    }
}
//打折接口
public interface IActivityStrategyService {
    //策略code    
    int getCode();
	/**
	 * 打折
	 * @param money
	 * @return 应付金额
	 */
	BigDecimal calculate(BigDecimal money);
}
@Service("memberService ")
public class MemberService implements IActivityStrategyService {
    @Override
    public int getCode() {
        return ActivityStrategyEnum.MEMBER.getCode();
    }
	@Override
	public BigDecimal calculate(BigDecimal money) {
		//普通会员9折
		return money.multiply(new BigDecimal(0.9)).setScale(2, RoundingMode.HALF_UP);
	}
}
@Service("goldMemberService")
public class GoldMemberService implements IActivityStrategyService {
    @Override
    public int getCode() {
        return ActivityStrategyEnum.GOLD_MEMBER.getCode();
    }
	@Override
	public BigDecimal calculate(BigDecimal money) {
		//黄金会员8折
		return money.multiply(new BigDecimal(0.8)).setScale(2, RoundingMode.HALF_UP);
	}
}
@Service("diamondMemberService")
public class DiamondMemberService implements IActivityStrategyService {
    @Override
    public int getCode() {
        return ActivityStrategyEnum.DIAMOND_MEMBER.getCode();
    }
	@Override
	public BigDecimal calculate(BigDecimal money) {
		//钻石会员7折
		return money.multiply(new BigDecimal(0.7)).setScale(2, RoundingMode.HALF_UP);
	}
}
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@Component
public class ActivityStrategyHandler implements InitializingBean, ApplicationContextAware {
    /**
     * 存放策略的map,可以理解为策略的注册中心
     */
    private final Map<Integer, IActivityStrategyService> serviceHashMap = new ConcurrentHashMap<>();
    /**
     * spring的上下文
     */
    private ApplicationContext applicationContext;
    /**
     * 将StrategyService的类都按照定义好的规则(枚举code),放入strategyServiceMap中
     *
     * @throws Exception
     */
    @Override
    public void afterPropertiesSet() throws Exception {
        Map<String, IActivityStrategyService> matchBeans = applicationContext.getBeansOfType(IActivityStrategyService.class);
        for (IActivityStrategyService strategyService : matchBeans.values()) {
            serviceHashMap.put(strategyService.getCode(), strategyService);
            System.out.println("初始化策略模式的键值对 code =" + strategyService.getCode() + " ,value=" + strategyService);
        }
    }
    /**
     * 注入applicationContext
     *
     * @param applicationContext
     * @throws BeansException
     */
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
    /**
     * 通过枚举code获取对应对更新服务
     * @param strategyEnum
     * @return
     */
    public IActivityStrategyService getActivityService(ActivityStrategyEnum strategyEnum){
        return serviceHashMap.get(strategyEnum.getCode());
    }
}

客户端调用

@RestController
public class IndexController {
    @Autowired
    private ActivityStrategyHandler activityHandler;
    @GetMapping("/acitivity")
    public BigDecimal acitivity(int code) throws JsonProcessingException {
        //会员类型code
        ActivityStrategyEnum strategyEnum = ActivityStrategyEnum.match(code);
        IActivityStrategyService activityService = activityHandler.getActivityService(strategyEnum);
        //获取商品金额
        BigDecimal amount = new BigDecimal(100);
        //调用具体的打折策略算法
        BigDecimal price = activityService.calculate(amount);
        return price ;
    }
}

到此这篇关于Java设计模式中的策略(Strategy)模式解读的文章就介绍到这了,更多相关Java的策略模式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Spring Boot与ActiveMQ整合的步骤

    Spring Boot与ActiveMQ整合的步骤

    今天小编就为大家分享一篇关于Spring Boot与ActiveMQ整合的步骤,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-01-01
  • Java设计模式之建造者模式的示例详解

    Java设计模式之建造者模式的示例详解

    建造者模式,是一种对象构建模式 它可以将复杂对象的建造过程抽象出来,使这个抽象过程的不同实现方法可以构造出不同表现的对象。本文将通过示例讲解建造者模式,需要的可以参考一下
    2022-10-10
  • SpringBoot Application的exclude不生效问题及排查

    SpringBoot Application的exclude不生效问题及排查

    这篇文章主要介绍了SpringBoot Application的exclude不生效问题及排查,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-11-11
  • Java中字符编码问题的解决方法详解

    Java中字符编码问题的解决方法详解

    在日常 Java 开发中,字符编码问题是一个非常常见却又特别容易踩坑的地方,这篇文章就带你一步一步看清楚字符编码的来龙去脉,并结合可运行的代码,看看如何在 Java 项目里彻底解决编码不一致的问题
    2025-09-09
  • java工具类static静态方法读取yml配置过程

    java工具类static静态方法读取yml配置过程

    文章介绍了在工具类中获取YAML配置时遇到的问题,由于变量是静态的,而Spring加载静态方法比IOC容器早,导致无法直接使用@Value注解读取YAML配置,从而读取结果为null
    2024-11-11
  • springboot整合Sa-Token实现登录认证和权限校验的详细流程

    springboot整合Sa-Token实现登录认证和权限校验的详细流程

    Sa-Token是国产轻量级权限认证框架,支持登录、权限校验、单点登录及分布式会话,配置简便且API设计直观,相比Spring Security更易上手,适合快速实现安全功能,助力国产开源发展,感兴趣的朋友跟随小编一起看看吧
    2025-09-09
  • 使用spring boot 整合kafka,延迟启动消费者

    使用spring boot 整合kafka,延迟启动消费者

    这篇文章主要介绍了使用spring boot 整合kafka,延迟启动消费者的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-08-08
  • java: 无效的目标发行版: 20问题解决办法

    java: 无效的目标发行版: 20问题解决办法

    这篇文章主要给大家介绍了关于java: 无效的目标发行版: 20问题的解决办法,出现这个问题大多数是因为自己安装的jdk版本和你在运行项目时的所选的jdk版本不一致所导致的,需要的朋友可以参考下
    2024-03-03
  • Java-String类最全汇总(上篇)

    Java-String类最全汇总(上篇)

    这篇文章主要介绍了Java-String类最全汇总(上篇),本文章内容详细,本模块分为了两部分,本次为上篇,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2023-01-01
  • SpringBoot跨域问题的五种解决方式

    SpringBoot跨域问题的五种解决方式

    前后端分离开发中,跨域问题是很常见的一种问题,下面这篇文章主要给大家介绍了关于SpringBoot跨域问题的五种解决方式,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2021-12-12

最新评论