顾名思义,策略模式就是在不同的条件下采取不同的策略,及不同的算法或业务规则。
策略模式是用来封装算法的,但在实践中,我们发现可以用它来封装几乎任何类型的规则。只要在分析过程中听到需要在不同时间应用不同的业务规则,就可以考虑用策略模式处理这种变化的可能性。 --《大话设计模式》
基本结构如下:
①、超类,或许可设计成抽象的abstract
一些公用的属性(被子类调用)
一些公用的方法(被子类覆写)
②、子类,个数较多,继承超类
得到超类公用方法,覆写
Ps:以上两点和工厂模式类似(实际上笔者直接复制的简单工厂的笔记)
③、配置类,作用类似于配置文件
属性:“超类”的引用
构造函数(传入关键数据,用以判断生成所需要的子类)
方法甲:调用“超类”的公用方法,实际调用的是具体一子类覆写后的方法
④、调用者
传实参给“配置类”
调用“配置类”里的“方法甲”
示例代码:模拟商场销售
①、超类#########################################
/**
* 超类,金额计算
*/
public abstract class CashSuper {
public abstract double calculate(double money); //param:原本的消费金额
}
②、子类#########################################
/**
* 子类1,正常销售
*/
public class CashNormal extends CashSuper {
@Override
public double calculate(double money) {
return money;
}
}
/**
* 子类2,打折销售
*/
public class CashRebate extends CashSuper {
private double moneyRebate;
//构造函数,要求必须传入折扣
public CashRebate(double moneyRebate){
this.moneyRebate = moneyRebate;
}
@Override
public double calculate(double money) {
return money*moneyRebate; //返还打折后的消费金额
}
}
/**
* 子类3,返还金额销售
*/
public class CashReturn extends CashSuper {
private double limitMoney; //需满足的现金额度
private double returnMoney; //返还的金额
//构造函数,要求必须传入既定金额及返还的现金数
public CashReturn(double limitMoney,double returnMoney){
this.limitMoney = limitMoney;
this.returnMoney = returnMoney;
}
@Override
public double calculate(double money) {
double result = money;
if(money>limitMoney){
result = money - Math.floor(money/limitMoney)*returnMoney;
}
return result;
}
}
③、配置类#########################################
/**
* 配置类,内含工厂模式
*/
public class CashContext {
private CashSuper cs;
public CashContext(int dealCode){ //param:交易类型编号
switch (dealCode) {
case 0:
cs = new CashNormal();
break;
case 1:
cs = new CashRebate(0.8);
break;
case 2:
cs = new CashReturn(200, 80);
break;
}
}
//输出消费金额
public void getResult(double money){
double result = cs.calculate(money);
System.out.println("消费的金额为:"+result);
}
}
④、调用者#########################################
public class Test {
public static void main(String[] args) throws Exception {
int code = 2;
CashContext context = new CashContext(2);
context.getResult(500);
}
}
备注:“配置类”部分用了switch判断,如果配合reflect(反射)的话,效果会更好