目标:我们需要一个计算价格的类,有时候会打折
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);
}
}
策略模式在Struts2中主要作用位置:
1.加载多配置,默认的,插件的,应用的;
2.用于插件模式,插件就好比如其中的一个策略。每个策略选择的地方,就是Struts2的一个扩展点。