一、定义
该模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用
算法的客户。策略模式属于对象行为模式,它通过对算法进行封装,把使用算法的责任和算法的实现分
割开来,并委派给不同的对象对这些算法进行管理。
二、结构
抽象策略(Strategy)类:这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有
的具体策略类所需的接口。
具体策略(Concrete Strategy)类:实现了抽象策略定义的接口,提供具体的算法实现或行
为。
环境(Context)类:持有一个策略类的引用,最终给客户端调用。
三、案例
一个商店实行会员制,根据会员等级的不同对所购买的商品进行对应的打折
算法一:初级会员没有折扣
算法二:中级会员打8折
算法三:高级会员打5折
1、传统代码实现方式
public double getPreice(String type,double preice,int number){
//初级会员
if (type.equals("1")){
return preice*number;
}
//中级会员
if (type.equals("2")){
return preice*number*0.8;
}
//高级会员
if (type.equals("2"))
{
return preice*number*0.5;
}
return 0;
}
这样写后期维护比较困,而且也不符合设计模式中的开闭原则
2、策略模式
抽象策略(Strategy)类:
public interface AbstractStrgtegy {
//preice:价格 number:商品数量
public double countPreice(double preice,int number);
public String getKey();
}
具体策略(Concrete Strategy)类:
@Service
public class ordinaryMember implements AbstractStrgtegy{
//普通会员
@Override
public double countPreice(double preice, int number) {
return preice*number;
}
@Override
public String getKey() {
return MyEnum.ORDINARY.getCode();
}
}
@Service
public class intermediateMember implements AbstractStrgtegy{
//中级会员
@Override
public double countPreice(double preice, int number) {
return preice*number*0.8;
}
@Override
public String getKey() {
return MyEnum.INTERMEDIATE.getCode();
}
}
@Service
public class seniorMember implements AbstractStrgtegy{
//高级会员
@Override
public double countPreice(double preice, int number) {
return preice*number*0.5;
}
@Override
public String getKey() {
return MyEnum.SENIOR.getCode();
}
}
这里是用工厂模式去获取对象
@Component
public class HandleStrategy implements InitializingBean, ApplicationContextAware {
private ApplicationContext applicationContext;
private Map<String, AbstractStrgtegy> strategyServiceMap = new ConcurrentHashMap<>();
@Override
public void afterPropertiesSet() throws Exception {
//获取该接口下的所有实现类
Map<String, AbstractStrgtegy> beansOfType = applicationContext.getBeansOfType(AbstractStrgtegy.class);
beansOfType.forEach((key, value) -> {
strategyServiceMap.put(value.getKey(), value);
});
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
public AbstractStrgtegy getStrategy(Integer key) {
if (null == strategyServiceMap.get(key)) {
return strategyServiceMap.get(0);
}
return strategyServiceMap.get(key);
}
}
最后
public double getPreice(String type,double price,int number){
AbstractStrgtegy strategy = handleStrategy.getStrategy(type);
return strategy.countPreice(price, number);
}
枚举类
public enum MyEnum {
ORDINARY("1","普通会员"),
INTERMEDIATE("2","中级会员"),
SENIOR("3","高级会员");
private String code;
private String name;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
MyEnum(String code, String name) {
this.code = code;
this.name = name;
}
}
总结:策略模式符合开闭原则,在新增算法的情况下,不用对原有的代码进行修改。