策略模式一般用于封装系列算法或系情况而定选取某种方式进行处理,通常被封装在称为Context的类中,客户端可以自由的选取其中一种算法或处理方式。
场景:正在开发一个网上书店,需要进行各种促销,那么就需要各种打折的计算方法。
采用原始方式:
public double discount(double price) {
//针对不同情况采用不同的打折算法
swith(getDiscountType()) {
case VIP_DISCOUNT:
return vipDiscount(price);
break;
case OLD_DISCOUNT:
return oldDiscount(price);
break;
.......
}
}
从功能角度上,实现了根据打折类型类使用不同打折算法,但是将所有的打折算法均写入了discount方法中,当某天需要增加一种打折类型时,需要改动的地方至少是三处:打折类型,case,实现打折方法;在此可考虑使用策略模式来优化:
1.编写一个打折算法的接口:
public interface DiscountStrategy
{
//定义一个用于计算打折价的方法
double getDiscount(double originPrice);
}
2.实现俩个打折算法的实现类:
public class VipDiscount
implements DiscountStrategy
{
//重写getDiscount()方法,提供VIP打折算法
public double getDiscount(double originPrice)
{
System.out.println("使用VIP折扣...");
return originPrice * 0.5;
}
}
public class OldDiscount
implements DiscountStrategy
{
//重写getDiscount()方法,提供旧书打折算法
public double getDiscount(double originPrice)
{
System.out.println("使用旧书折扣...");
return originPrice * 0.7;
}
}
3.实现一个context类:
public class DiscountContext
{
//组合一个DiscountStrategy对象
private DiscountStrategy strategy;
//构造器,传入一个DiscountStrategy对象
public DiscountContext(DiscountStrategy strategy)
{
this.strategy = strategy;
}
//根据实际所使用的DiscountStrategy对象得到折扣价
public double getDiscountPrice(double price)
{
//如果strategy为null,系统自动选择OldDiscount类
if (strategy == null)
{
strategy = new OldDiscount();
}
return this.strategy.getDiscount(price);
}
//提供切换算法的方法
public void changeDiscount(DiscountStrategy strategy)
{
this.strategy = strategy;
}
}
4.测试类:
public class StrategyTest
{
public static void main(String[] args)
{
//客户端没有选择打折策略类
DiscountContext dc = new DiscountContext(null);
double price1 = 79;
//使用默认的打折策略
System.out.println("79元的书默认打折后的价格是:"
+ dc.getDiscountPrice(price1));
//客户端选择合适的VIP打折策略
dc.changeDiscount(new VipDiscount());
double price2 = 89;
//使用VIP打折得到打折价格
System.out.println("89元的书对VIP用户的价格是:"
+ dc.getDiscountPrice(price2));
}
}
这样,在需要新增一个算法时,仅需要实现打折算法,然后在客户端代码选择使用即可。
但是打折算法的实现类将与客户端耦合,此可以使用配置文件来解耦。