设计模式之–策略模式
简介:
本篇文章是介绍 23 中设计模式中的行为型设计模式中的
策略模式
.使用的是 Java 代码.
目录:
1.什么是策略模式
定义:
在某些设计中,一个类的设计人员经常可能涉及这样的问题:由于用户需求的变化,导致经常需要修改类中某个方法的方法体,即需要不断地变化算法。在这样的情况下可以考虑使用策略模式。
定义一系列的算法, 把每一个算法封装起来, 并且使它们可相互替换. 策略模式使得算法可独立于使用它的客户而独立变化.
结构:
- Context(上下文角色)
用来操作策略的上下文环境. 起到承上启下的作用, 屏蔽高层模块对策略, 算法的直接访问.
- Stragety(抽象策略角色)
策略, 算法的抽象, 通常为接口.
- ConcreteStragety(具体的策略实现)
具体的策略实现.
2.策略模式的使用场景和优点
使用场景:
- 对客户隐藏具体策略(算法)的实现细节, 彼此完全独立.
- 针对同一问题的多种处理方式, 仅仅是具体行为有差别时.
- 在一个类中定义了很多行为, 而且这些行为在这个类里的操作以多个条件语句的形式出现. 策略模式将相关的条件分支移入它们各自的 Strategy 类中, 以代替这些条件语句.
优点:
- 使用策略模式可以避免使用多重条件语句.
- 易于拓展. 当添加一个策略时, 只需要实现接口就可以了.
缺点:
- 每一个策略都是一个类, 复用性小. 如果策略过多, 类的数量会增多,
- 上层模块必须知道有哪些策略, 才能够使用这些策略, 这与迪米特原则相违背.
3.策略模式的简单运用
上下文角色
public class GymnasticsGame {
ComputableStrategy strategy;
public void setStrategy(ComputableStrategy strategy){
this.strategy = strategy;
}
public double getPersonScore(double[] a){
if(strategy != null)
return strategy.computeScore(a);
else
return 0;
}
}
抽象策略角色
package com.liuzhen.four_strategy;
public interface ComputableStrategy {
public abstract double computeScore(double[] a);
}
具体策略实现
package com.liuzhen.four_strategy;
public class StrategyOne implements ComputableStrategy{
public double computeScore(double[] a){
double score = 0 , sum = 0;
for(int i = 0;i < a.length;i++){
sum += a[i];
}
score = sum/a.length;
return score;
}
}
public class StrategyTwo implements ComputableStrategy {
public double computeScore(double[] a) {
double score = 0 , multi = 1;
int n = a.length;
for(int i = 0;i < a.length;i++){
multi = multi*a[i];
}
score = Math.pow(multi,1.0/n);
return score;
}
}
public class StrategyThree implements ComputableStrategy{
public double computeScore(double[] a){
if(a.length <= 2)
return 0;
double score = 0,sum = 0;
Arrays.sort(a);
for(int i = 1;i < a.length-1;i++){
sum += a[i];
}
score = sum/(a.length-2);
return score;
}
}
客户端调用
public class FourApplication {
public static void main(String args[]){
GymnasticsGame game = new GymnasticsGame(); //上下文对象
game.setStrategy(new StrategyOne()); //上下文对象使用策略一
Person zhang = new Person();
zhang.setName("张三");
double[] a = {9.12,9.25,8.87,9.99,6.99,7.88};
Person li = new Person();
li.setName("李四");
double[] b = {9.15,9.26,8.97,9.89,6.97,7.89};
zhang.setScore(game.getPersonScore(a));
li.setScore(game.getPersonScore(b));
System.out.printf("%s最后得分:%5.3f%n",zhang.getName(),zhang.getScore());
System.out.printf("%s最后得分:%5.3f%n",li.getName(),li.getScore());
game.setStrategy(new StrategyTwo()); //上下文对象使用策略二
zhang.setScore(game.getPersonScore(a));
li.setScore(game.getPersonScore(b));
System.out.println("使用几何平均值方案:");
System.out.printf("%s最后得分:%5.3f%n",zhang.getName(),zhang.getScore());
System.out.printf("%s最后得分:%5.3f%n",li.getName(),li.getScore());
game.setStrategy(new StrategyThree()); //上下文对象使用策略三
zhang.setScore(game.getPersonScore(a));
li.setScore(game.getPersonScore(b));
System.out.println("使用(去掉最大值和最小值)算术平均值方案:");
System.out.printf("%s最后得分:%5.3f%n",zhang.getName(),zhang.getScore());
System.out.printf("%s最后得分:%5.3f%n",li.getName(),li.getScore());
}
}