• 设计模式:策略模式


    策略(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;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    //打折接口
    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);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    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 serviceHashMap = new ConcurrentHashMap<>();
        /**
         * spring的上下文
         */
        private ApplicationContext applicationContext;
    
        /**
         * 将StrategyService的类都按照定义好的规则(枚举code),放入strategyServiceMap中
         *
         * @throws Exception
         */
        @Override
        public void afterPropertiesSet() throws Exception {
            Map 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());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54

    客户端调用

    @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 ;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
  • 相关阅读:
    ASP.NET-框架分类与详解
    html里面的伪元素是什么?如何操作?
    OA办公软件篇(一)—组织架构
    JSP Servlet JDBC MySQL CRUD 示例教程
    web前端期末大作业——网页制作基础大二dw作业——动画漫展学习资料电影模板(6页)
    mysql忘记密码 -linux -centos
    Codeforces Round #814 (Div. 2)
    基于云的多因素身份认证在企业实施中遇到的问题
    陪你去看 Lodash.js 起步
    【Arduino】esp01 Relay 转接板自动ping ip断电重启
  • 原文地址:https://blog.csdn.net/zhuyu19911016520/article/details/127697644