1. 概念
The Strategy Pattern defines a family of algorithms,encapsulates each one,and makes them interchangeable. Strategy lets the algorithm vary independently from clients that use it.
策略模式是指对一系列的算法定义,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。
2. 流程图
3. 代码部分
package Strategy;
public abstract class CashSuper {
public double acceptCash(double money) {
return money;
}
}
package Strategy;
public class CashNormal extends CashSuper{
@Override
public double acceptCash(double money) {
// TODO Auto-generated method stub
return money;
}
}
package Strategy;
public class CashRebate extends CashSuper {
private double moneyRebate=1;
public CashRebate(double moneyRebate) {
// TODO Auto-generated constructor stub
this.moneyRebate=moneyRebate;
}
@Override
public double acceptCash(double money) {
// TODO Auto-generated method stub
return money*moneyRebate;
}
}
package Strategy;
public class CashReturn extends CashSuper{
private double moneyCondition;
private double moneyReturn;
public CashReturn(double moneyCondition,double moneyReturn) {
// TODO Auto-generated constructor stub
this.moneyCondition=moneyCondition;
this.moneyReturn=moneyReturn;
}
@Override
public double acceptCash(double money) {
// TODO Auto-generated method stub
double result=money;
if (money>moneyCondition) {
result=money-Math.floor(money/moneyCondition)*moneyReturn;
}
return result;
}
}
package Strategy;
public class CashContext {
CashSuper cashSuper;
public CashContext(String type) {
// TODO Auto-generated constructor stub
switch (type) {
case "正常收费":
cashSuper = new CashNormal();
break;
case "满300减100":
cashSuper = new CashReturn(300, 100);
break;
case "打8折":
cashSuper = new CashRebate(0.8);
break;
default:
break;
}
}
public double GetResult(double money) {
return cashSuper.acceptCash(money);
}
}
package Strategy;
import org.junit.Test;
public class Client {
@Test
public void testStrategy() {
String type="满300减100";//正常收费 ,打8折 ,满300减100
CashContext cashContext = new CashContext(type);
System.out.println(cashContext.GetResult(1800));
}
}
4. 模式分析
策略模式提供了管理相关的算法族的办法、策略模式提供了可以替换继承关系的办法、使用策略模式可以避免使用多重条件转移语句。
策略模式提供了可以替换继承关系的办法。继承可以处理多种算法或行为。如果不是用策略模式,那么使用算法或行为的环境类就可能会有一些子类,每一个子类提供一个不同的算法或行为。但是,这样一来算法或行为的使用者就和算法或行为本身混在一起。决定使用哪一种算法或采取哪一种行为的逻辑就和算法或行为的逻辑混合在一起,从而不可能再独立演化。继承使得动态改变算法或行为变得不可能。。
使用策略模式可以避免使用多重条件转移语句。多重转移语句不易维护,它把采取哪一种算法或采取哪一种行为的逻辑与算法或行为的逻辑混合在一起,统统列在一个多重转移语句里面,比使用继承的办法还要原始和落后。
客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法类。换言之,策略模式只适用于客户端知道所有的算法或行为的情况。
策略模式造成很多的策略类,每个具体策略类都会产生一个新类。有时候可以通过把依赖于环境的状态保存到客户端里面,而将策略类设计成可共享的,这样策略类实例可以被不同客户端使用。换言之,可以使用享元模式来减少对象的数量。