策略模式

定义

定义一组算法,将每个算法封装起来,并且它们之间可以互换

使用场景

  1. 多个类只有在算法或者行为上不同的场景
  2. 算法需要自由切换

实现方式

一般判断条件的代码,可以使用策略模式优化

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);
}

扩展与思考

  1. 使用Spring情况下,可以不用自己创建StrategyFactory,可以用ApplicationContext来获取Strategy的bean
  2. 多种判断条件的代码,可以考虑使用策略模式重构。
  3. 上述例子中在测试类暴露了具体的策略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);
}
posted @ 2019-08-09 15:56  fzsyw  阅读(112)  评论(0)    收藏  举报