模式定义
策略模式(Strategy Pattern):定义一系列的算法,将每一种算法封装起来并可以相互替换使用,策略模式让算法独立于使用它的客户应用而独立变化。
概念解析:意思就是我们解决一个可能有多种解决方法(即算法)的问题的时候,我们可以先把不同的解决方法实现,然后根据具体的情况选用不同的解决方法。
模式类图:
使用场合:
(1)、当多个类的表现行为不同,需要在运行时动态的选择具体要执行的行为的时候。
(2)、需要在不同的情况下使用不同的策略,或者还可能在未来用其他方式实现的时候。
(3)、需要隐藏具体策略的实现细节,各个具体策略彼此独立的时候。
(4)、当一个类有多种行为,而且要在执行的时候用判断语句选择具体的行为的时候,可以运用策略模式将各个条件里面的动作,用具体的策略类来实现。
实例分析:商场打折促销的例子。促销方式:
1、打八折促销商品。
2、满1000元减200促销商品。
3、满200元,高于200元的部分打8折促销商品。
在商场促销活动中,用户可以根据自己的实际情况选择具体的打折方式。如有的商品打八折促销,有的商品满1000减200,有的商品满200高于200的部分打八折。用户则根据自己的具体需求选择不同的商品,然后结账的时候跟据不同的商品的促销方式的不同来计算具体消费费用。
策略模式实现过程应注意以下几点内容:
(1)、需要一个总体结构负责保存当前的具体策略,然后在具体的使用方法中调用具体策略实现相应的算法。
(2)、可以在适当的时候改变当前策略。
(3)、每一种条件分支作为一个具体策略算法单独实现。
代码实现(java):
//策略接口
public interface Istrategy {
//计算实际价格的方法
public double realPrice(double consumePrice);
}
//8折促销
public class RebateStrategy implements Istrategy {
private final double rate;
public RebateStrategy(){
this.rate=0.8;
}
public double realPrice(double consumePrice){
return consumePrice *this.rate;
}
}
//满1000减200促销策略
public class ReduceStrategy implements Istrategy {
public double realPrice(double consumePrice){
if(consumePrice>=10000){
return consumePrice-200;
}
else{
return consumePrice;
}
}
}
//200以上部分打8折促销策略
public class PromotionalStrategy implements Istrategy {
public double realPrice(double consumePrice){
if(consumePrice>200){
return 200+(consumePrice-200)*0.8;
}
else{
return consumePrice;
}
}
}
//上下文环境
import java.math.BigDecimal;
public class Context {
//当前策略
private Istrategy strategy;
//设置当前策略
public void setStrategy(Istrategy strategy){
this.strategy=strategy;
}
//使用策略计算当前价格
public double cul(double consumePrice){
double realPrice=this.strategy.realPrice(consumePrice);
//-----以下内容对数字的格式进行转换,不懂的可以看javaAPI文档里的java.util.math.BigDecimal
BigDecimal bd=new BigDecimal(realPrice);
bd=bd.setScale(1,BigDecimal.ROUND_DOWN);
return bd.doubleValue();
//----------------
}
}
//客户端测试用例
import java.util.Random; //产生随机数
public class Client {
public static void main(String args[]){
//创建上下文环境对象实例
Context context=new Context();
Random random=new Random();
for(int i=0;i<10;i++){
int x=random.nextInt(3);
double consumePrice=0;
while((consumePrice=random.nextInt(2000))==0){//产生2000以内随机的价格
}
//调用不同的策略
switch(x){
case 0:
context.setStrategy(new RebateStrategy());
break;
case 1:
context.setStrategy(new PromotionalStrategy());
break;
case 2:
context.setStrategy(new ReduceStrategy());
break;
}
System.out.println("原价:"+consumePrice+" 优惠后价格:"+context.cul(consumePrice));
}
}
}
文章内容来源:
软件秘笈——设计模式那点事