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的策略模式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • java中幂指数值的运算代码解析

    java中幂指数值的运算代码解析

    这篇文章主要介绍了java中幂指数值的运算代码解析,具有一定借鉴价值,需要的朋友可以参考下。
    2017-12-12
  • 都9102年了,你还用for循环操作集合吗

    都9102年了,你还用for循环操作集合吗

    这篇文章主要给大家介绍了关于java中for循环操作集合使用的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者使用java具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-03-03
  • java占位符替换五种方式小结

    java占位符替换五种方式小结

    我们经常会遇到需要替换字符串中的占位符的情况,本文主要介绍了java占位符替换五种方式小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-06-06
  • Java简单计算器的实现

    Java简单计算器的实现

    这篇文章主要为大家详细介绍了Java简单计算器的实现,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-12-12
  • spring 注解如何开启声明式事务

    spring 注解如何开启声明式事务

    这篇文章主要介绍了spring 注解开启声明式事务问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-12-12
  • Java中的引用类型和使用场景详细

    Java中的引用类型和使用场景详细

    这篇文章介绍的是Java中的引用类型和使用场景,主要内容展开Java中的引用类型,有强引用、软引用 、弱引用、虚引用,需要的朋友可以参考一下
    2021-10-10
  • IntelliJ IDEA 部署 Web 项目,看这一篇够了!

    IntelliJ IDEA 部署 Web 项目,看这一篇够了!

    这篇文章主要介绍了IntelliJ IDEA 部署 Web 项目的图文教程,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-05-05
  • Spring Cloud 覆写远端的配置属性实例详解

    Spring Cloud 覆写远端的配置属性实例详解

    这篇文章主要介绍了Spring Cloud 覆写远端的配置属性的相关知识,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2018-01-01
  • Java启用Azure Linux虚拟机诊断设置

    Java启用Azure Linux虚拟机诊断设置

    这篇文章主要介绍了Java启用Azure Linux虚拟机诊断设置,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-05-05
  • Java调用第三方http接口的四种方式总结

    Java调用第三方http接口的四种方式总结

    这篇文章主要给大家介绍了关于Java调用第三方http接口的四种方式,在实际开发中我们经常会与第三方公司进行合作,接入第三方接口,文中给出了详细的代码实例,需要的朋友可以参考下
    2023-08-08

最新评论