1.概述
定义一系列的算法,把每一个算法封装起来,并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。也称为政策模式。
2.涉及到的角色
策略类(Stratege):定义所有支持的算法的公共接口。
具体策略类(Concrete Stratege):封装了具体的算法或行为,继承于Stratege类。
上下文类(Context):用一个ConcreteStratege来配置,维护一个对Stratege对象的引用。
3.适用性
1)对客户隐藏具体策略(算法)的实现细节,彼此完全独立。
2)针对同一类型问题的多种处理方式,仅仅是具体行为有差别时。
3)一个类定义了很多行为,而且这些行为在这个类里的操作以多个条件语句的形式出现。
策略模式将相关的条件分支移入它们各自的 Strategy类中以代替这些条件语句。
4.策略模式的优缺点
优点:
1)相关算法系列 Strategy类层次为Context定义了一系列的可供重用的算法或行为。 继承有助于析取出这些算法中的公共功能。
2)消除了一些if else条件语句 :Strategy模式提供了用条件语句选择所需的行为以外的另一种选择。当不同的行为堆砌在一个类中时
很难避免使用条件语句来选择合适的行为。将行为封装在一个个独立的Strategy类中消除了这些条件语句。含有许多条件语句的代码
3)策略模式每个算法都有自己的类,可以通过自己的接口单独测试。因而简化了单元测试。通常意味着需要使用Strategy模式。
缺点:
1)客户端必须知道所有的策略类,并自行决定使用哪一个策略类
2)策略模式将造成产生很多策略类组成
5.结构:
6.实例代码:(某项比赛时对选手进行打分)
抽象策略接口:
package com.strategy;
/**
* @author lxp
*
* @TODO
*
*/
// 定义抽象策略接口
public interface ComputableStrategy {
//计算分数
public abstract double computableScore(double[] a);//数组a中的元素表示被选手打的不同的分数
}
策略一:
package com.strategy;
/**
* @author lxp
*
* @TODO
*
*/
// 定义策略一实现策略接口
public class StrategyOne implements ComputableStrategy {
@Override
public double computableScore(double[] a) {//计算数组a的元素的代数平均值
// TODO Auto-generated method stub
double Score = 0, Sum = 0;
for (int i = 0; i < a.length; i++) {
Sum += a[i];
}
Score = Sum / a.length;
return Score;
}
}
具体策略二:
package com.strategy;
/**
* @author lxp
*
* @TODO
*
*/
// 定义策略二实现策略接口
public class StrategyTwo implements ComputableStrategy {
@Override
public double computableScore(double[] a) {// 计算数组a的元素的几何平均数
// TODO Auto-generated method stub
double Score = 0, Multi = 1;
for (int i = 0; i < a.length; i++) {
Multi = Multi * a[i];
}
Score = Math.pow(Multi, 1.0 / (a.length));
return Score;
}
}
具体策略三:
package com.strategy;
import java.util.Arrays;
/**
* @author lxp
*
* @TODO
*
*/
// 定义策略三实现策略接口
public class StrategyThree implements ComputableStrategy {
@Override
public double computableScore(double[] a) {// 计算数组a中去除最大值个最小值后的代数平均值
// TODO Auto-generated method stub
// 将数组a进行排序
Arrays.sort(a);
double Score = 0, Sum = 0;
if (a.length <= 2) {
return 0;
} else {
for (int i = 1; i < a.length - 1; i++) {
Sum += a[i];
}
Score = Sum / (a.length - 2);
}
return Score;
}
}
上下文类:(此实例中定义为该项比赛)
package com.strategy;
/**
* @author lxp
*
* @TODO
*
*/
// 定义上下文的环境类(Context)
public class Game {
private ComputableStrategy strategy;
double Score;
// 定义使用某种策略的方法
public void setStrategy(ComputableStrategy strategy) {
this.strategy = strategy;
}
// 获得最终的Score
public double getScore(double[] a) {
if (strategy == null) {
return 0;
} else {
Score = strategy.computableScore(a);
}
return Score;
}
}
测试类:
package com.strategy;
/**
* @author lxp
*
* @TODO
*
*/
//测试类
public class StrategyDemo {
public static void main(String[] args) {
double[] a={9,8,10,9,8,9,8,7,10};
Game game=new Game();
//使用StrategyOne
game.setStrategy(new StrategyOne());
System.out.println("使用策略一得到的分数是:"+"\r"+game.getScore(a));
System.out.println("----------------");
game.setStrategy(new StrategyTwo());
System.out.println("使用策略二得到的分数是:"+"\r"+game.getScore(a));
System.out.println("----------------");
game.setStrategy(new StrategyThree());
System.out.println("使用策略三得到的分数是:"+"\r"+game.getScore(a));
System.out.println("----------------");
}
}
试验结果: