开发者

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

目录
  • Java的策略模式
  • 策略模式与Spring结合
    • 客户端调用

Java的策略模式

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

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

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

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

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

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

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

策略模式与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(BigDecima编程客栈l 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 DiamondMemberTGzcvrcService implements IActivityStrategyService {
    @Overridwww.devze.come
    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的策略模式内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)!

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新开发

开发排行榜