1.策略模式的定义
定义一系列算法,并将它们封装起来,并且使他们可以相互替换。改模式定义的算法可以独立于客户而改变。
2.策略模式的使用场景
考虑如下场景:假如正在开发一个网上书店,该书店为了更好地促销,经常需要对图书进行打折促销,程序需要考虑各种打折促销的计算方法。需要能够灵活的增加新的打折算法。
3.策略模式的UML类图
4.策略模式的实现
/**
* 算法接口
* @author Administrator
*
*/
public interface DiscountStrategy {
//定义一个用于计算打折价的方法
double getDiscount(double originPrice);
}
/**
* 实现DiscountStrategy接口,实现对VIP的打折算法
* @author Administrator
*
*/
public class VipDiscount implements DiscountStrategy{
//重写getDiscount方法,提供VIP打折算法
@Override
public double getDiscount(double originPrice) {
// TODO Auto-generated method stub
System.out.println("使用VIP折扣...");
return originPrice*0.5;
}
}
/**
* 实现DiscountStrategy接口,实现对旧书的打折算法
* @author Administrator
*
*/
public class OldDiscount implements DiscountStrategy{
//重写getDiscount方法,提供旧书打折算法
@Override
public double getDiscount(double originPrice) {
// TODO Auto-generated method stub
System.out.println("使用旧书折扣...");
return originPrice*0.7;
}
}
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(null == strategy) {
strategy = new OldDiscount();
}
return this.strategy.getDiscount(price);
}
//提供切换算法的方法
public void setDiscount(DiscountStrategy strategy) {
this.strategy = strategy;
}
}
/**
* 入口程序,测试策略模式
* @author Administrator
*
*/
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.setDiscount(new VipDiscount());
double price2 = 89;
System.out.println("89元的书对VIP用户的价格是:"+dc.getDiscountPrice(price2));
}
}
5.总结
策略模式主要用来分离算法,在相同的抽象下有不同的具体实现策略。这个模式很好的演示了开闭原则,也就是定义抽象,注入不同的实现,从而达到很好的可扩展性。
优点
- 结构清晰明了、使用简单直观;
- 耦合度相对而言较低、扩展方便;
- 操作封装也更为彻底,数据更为安全。
缺点
随着错略的增加,子类也会变得繁多。
备注:读《Android源码设计模式解析与实践》笔记。