定义
定义一组算法,将每个算法封装起来,并且它们之间可以互换
使用场景
- 多个类只有在算法或者行为上不同的场景
- 算法需要自由切换
实现方式
一般判断条件的代码,可以使用策略模式优化
public double getPrice(String type, double price) {
if (type.equals("gerneral")) {
System.out.println("打九折");
return price * 0.9;
} else if (type.equals("vip")) {
System.out.println("打八五折");
return price * 0.85;
} else if (type.equals("superVip")) {
System.out.println("打八折");
return price * 0.8;
}
return price;
}
策略的接口
public interface Strategy {
public double getPrice(double standardPrice);
}
策略的实现类
public class GeneralCustomerStrategy implements Strategy {
@Override
public double getPrice(double standardPrice) {
System.out.println("打九折");
return standardPrice*0.9;
}
}
public class VipCustomerStrategy implements Strategy {
@Override
public double getPrice(double standardPrice) {
System.out.println("打八五折");
return standardPrice*0.85;
}
}
public class SuperVipCustomerStrategy implements Strategy {
@Override
public double getPrice(double standardPrice) {
System.out.println("打八折");
return standardPrice*0.8;
}
}
对外的入口
public class Context {
private Strategy strategy;
public void setStrategy(Strategy strategy) {
this.strategy = strategy;
}
public double getPrice(double s){
double result = strategy.getPrice(s);
System.out.println("您需要付款:" + result);
return result;
}
}
测试类
public static void main(String[] args) {
Strategy s1 = new VipCustomerStrategy();
Context ctx = new Context(s1);
ctx.pringPrice(998);
}
扩展与思考
- 使用Spring情况下,可以不用自己创建
StrategyFactory
,可以用ApplicationContext
来获取Strategy的bean - 多种判断条件的代码,可以考虑使用策略模式重构。
- 上述例子中在测试类暴露了具体的策略Strategy,这不太合适,一般会反射或者工厂模式来获取策略类。
public class StrategyFactory {
public static Map<String, Strategy> map = new HashMap<>();
static {
map.put("gerneral", new GeneralCustomerStrategy());
map.put("vip", new VipCustomerStrategy());
map.put("superVip", new SuperVipCustomerStrategy());
}
public static Strategy getStrategy(String type) {
return map.get(type);
}
}
public class Context {
private Strategy strategy;
public void setStrategyType(String type) {
this.strategy = StrategyFactory.getStrategy(type);
}
public double getPrice(double s){
double result = strategy.getPrice(s);
System.out.println("您需要付款:" + result);
return result;
}
}
则最初的if-else的代码可以改为
public double getPrice(String type, double price) {
Context ctx = new Context();
ctx.setStrategyType(type);
return ctx.getPrice(price);
}