目标:我们需要一个计算价格的类,有时候会打折
1.我们先设计一个接口
public interface PriceCalculationStrategy { public double calculatePrice(double price , double copies); public boolean match(double price , double copies); }2.我们有一些计算实现
public class DefaultDiscountPriceCalStrategy implements PriceCalculationStrategy{ public double rate = 0.1; public double calculatePrice(double price, double copies) { return price * copies * rate; } @Override public boolean match(double price, double copies) { return false; //这是不可能的 } }
public class NoDiscountPriceCalStrategy implements PriceCalculationStrategy{ public double calculatePrice(double price, double copies) { return price * copies; } public boolean match(double price, double copies) { return price < 300; } }
public class DiscountPriceCalStrategy implements PriceCalculationStrategy{ public double rate ; public double calculatePrice(double price, double copies) { return price * copies * rate; } public void setDiscount(double rate) { this.rate = rate; } public boolean match(double price, double copies) { boolean match = false; if(price >= 300 && price <1000){ setDiscount(0.9); match = true; }else if( price >=1000){ setDiscount(0.8); match = true; } return match; } }3.计算工具类,发现我们根本不要自己判断,每个策略自己判断执不执行
public class PriceCalculationUtil { public static List<PriceCalculationStrategy> priceCalculationStrategys = new ArrayList<PriceCalculationStrategy>(); static{ //等价于 容器内查找所有策略 PriceCalculationStrategy pcs = new NoDiscountPriceCalStrategy(); PriceCalculationStrategy pcs1 = new DiscountPriceCalStrategy(); DefaultDiscountPriceCalStrategy defaultD =new DefaultDiscountPriceCalStrategy(); priceCalculationStrategys.add(pcs); priceCalculationStrategys.add(pcs1); priceCalculationStrategys.add(defaultD); } public static double priceCalculation(double price , double copies) { for (PriceCalculationStrategy strategy : priceCalculationStrategys) { if( strategy.match(price, copies)){ return strategy.calculatePrice(price, copies); } } //优先其他策略,我不会告诉你我打的广告“ 1折 商品 ” 是假的,你看我有这个策略的 DefaultDiscountPriceCalStrategy defaultD = new DefaultDiscountPriceCalStrategy(); return defaultD.calculatePrice(price, copies); } }4.测试
public class PriceCalculationUtilTest { @Test public void testPriceCalculation(){ assertEquals(200,PriceCalculationUtil.priceCalculation(100, 2),0); assertEquals(360,PriceCalculationUtil.priceCalculation(400, 1),0); assertEquals(800,PriceCalculationUtil.priceCalculation(1000, 1),0); } }