策略(Strategy)模式:分离算法,选择实现
比如对象的某个行为,在不同场景有不同实现方式,可以将这些行为的具体实现定义为一组策略,每个实现类实现一种策略,在不同场景使用不同的实现,并且可以自由切换策略,但太多的策略会导致大量代码
如:电商活动打折,普通会员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 {@Overridepublic int getCode() {return ActivityStrategyEnum.MEMBER.getCode();}@Overridepublic BigDecimal calculate(BigDecimal money) {//普通会员9折return money.multiply(new BigDecimal(0.9)).setScale(2, RoundingMode.HALF_UP);}
}@Service("goldMemberService")
public class GoldMemberService implements IActivityStrategyService {@Overridepublic int getCode() {return ActivityStrategyEnum.GOLD_MEMBER.getCode();}@Overridepublic BigDecimal calculate(BigDecimal money) {//黄金会员8折return money.multiply(new BigDecimal(0.8)).setScale(2, RoundingMode.HALF_UP);}
}@Service("diamondMemberService")
public class DiamondMemberService implements IActivityStrategyService {@Overridepublic int getCode() {return ActivityStrategyEnum.DIAMOND_MEMBER.getCode();}@Overridepublic 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 serviceHashMap = new ConcurrentHashMap<>();/*** spring的上下文*/private ApplicationContext applicationContext;/*** 将StrategyService的类都按照定义好的规则(枚举code),放入strategyServiceMap中** @throws Exception*/@Overridepublic 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*/@Overridepublic 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 {@Autowiredprivate ActivityStrategyHandler activityHandler;@GetMapping("/acitivity")public BigDecimal acitivity(int code) throws JsonProcessingException {//会员类型codeActivityStrategyEnum strategyEnum = ActivityStrategyEnum.match(code);IActivityStrategyService activityService = activityHandler.getActivityService(strategyEnum);//获取商品金额BigDecimal amount = new BigDecimal(100);//调用具体的打折策略算法BigDecimal price = activityService.calculate(amount);return price ;}
}
下一篇:java中的接口