您的位置:首页 > 编程语言 > Java开发

Java设计模式--策略模式(对象行为型)

2017-03-23 14:45 183 查看
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("----------------");
}
}


试验结果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息