一、策略模式:
如果说简单工厂模式对对象分类,
那么策略模式就是对相似逻辑算法分类,
将算法的切换变成一个目标可变的行为,
由策略决定行为。
二、基本思路:
1.创建策略抽象类,定义所有支持的算法的公共接口;
2.继承抽象类,策略具体化;
3.定义Context类作为上下文承接的角色,是使用了某种策略的类,通过策略改变自身行为。
三、简单样例:
以简单收银软件为例,灵活解决原价、打折、返现、返积分等问题。
/**
* 策略抽象类
* 定义收费抽象方法
*/
abstract class CashSuper{
public abstract double acceptCash(double money);
}
/**
* 具体策略的实现
* 将收费方式具体化,例如按照原价,或者打折或者满价返现等等
*/
//正常收费
class CashNormal extends CashSuper{
@Override
public double acceptCash(double money) {
return money;
}
}
//打折收费
class CashRebate extends CashSuper{
private double cashRebate=1;
CashRebate(double moneyRebate){//传入折扣率,之前初始化为1
this.cashRebate=moneyRebate;
}
@Override
public double acceptCash(double money) {
return money*cashRebate;//折扣后
}
}
//收费返利
class CashReturn extends CashSuper{
private double cashCondition=0;
private double cashReturn=0;
//满cashCondition,送cashReturn
CashReturn(double cashCondition, double cashReturn){
this.cashCondition=cashCondition;
this.cashReturn=cashReturn;
}
@Override
public double acceptCash(double money) {
double result=money;
if (money>=cashCondition){
result=money-Math.floor(money/cashCondition)*cashReturn;
}
return result;
}
}
/**
* 接收具体策略,并产生不同的行为
* 根据收费策略,决定费用计算方法
*/
class Context{
private CashSuper cashSuper;
//通过构造方法传入具体的收费策略
public Context(CashSuper cashSuper){
this.cashSuper=cashSuper;
}
public double getResult(double price){
//根据收费策略的不同,用不同的计算方法获得具体收费金额。
return cashSuper.acceptCash(price);
}
}
/**
* 选择策略
* 客户端选择收费方法,即可得到响应的结果,
* 具体算法已经跟客户程序隔离
*/
class Main{
public static Context chooseStrategy(String type){
Context context=null;
//根据收费类型不同,将相应的策略对象传入Context中,
// 之后Context将产生对应行为,最终得出结果
switch (type) {
case "正常收费":
context = new Context(new CashNormal());
break;
case "打8折":
context = new Context(new CashRebate(0.8));
break;
case "满300返100":
context = new Context(new CashReturn(300, 100));
break;
default:
break;
}
return context;
}
public static void main(String[] args) {
double single=12;//单价
double num=3;//数量
double totalPrice=0;//总价
Context context=null;
String[] types={"正常收费","打8折","满300返100"};
context=chooseStrategy(types[1]);
//进行计算
totalPrice=context.getResult(single*num);
System.out.println("应收费:"+totalPrice);
}
}