策略模式介绍
当我们的代码中出现好多if…else…或者case的时候,代码看起来会很多很臃肿,策略模式就能很好的解决这个问题.
使用场景:
1.针对同一类型问题的多种处理方式,仅仅是具体行为有差别时;
2.需要安全地封装多种同一类型的操作时;
3.出现同一抽象类有多个子类,而又需要使用 if-else 或者 switch-case 来选择具体子类时。
由图可看出此模式分为三个角色:
环境角色(Context): 持有抽象策略角色的引用.
抽象策略角色(Strategy): 具体策略角色的接口.
具体策略角色(ConcreteStrategy): 包装了算法和行为.
策略模式的实现
环境角色(Context)
public class Context {
Strategy strategy;
public Context(Strategy strategy) {
this.strategy = strategy;
}
//上下文接口
public void contextInterface() {
strategy.algorithmInterface();
}
}
抽象策略角色(Strategy)
public abstract class Strategy {
//算法方法
public abstract void algorithmInterface();
}
具体策略角色(ConcreteStrategy)
public class ConcreteStrategyA extends Strategy {
@Override
public void algorithmInterface() {
System.out.println("算法A实现");
}
}
public class ConcreteStrategyB extends Strategy {
@Override
public void algorithmInterface() {
System.out.println("算法B实现");
}
}
public class ConcreteStrategyC extends Strategy {
@Override
public void algorithmInterface() {
System.out.println("算法C实现");
}
}
测试类
public class Client {
public static void main(String[] args) {
Context context;
context = new Context(new ConcreteStrategyA());
context.contextInterface();
context = new Context(new ConcreteStrategyB());
context.contextInterface();
context = new Context(new ConcreteStrategyC());
context.contextInterface();
}
}
算法A实现
算法B实现
算法C实现
策略模式的实现
context环境角色
public class CashContext {
private CashSuper cashSuper;
public CashContext(CashSuper cashSuper) {
this.cashSuper = cashSuper;
}
public double getResult(double money) {
return cashSuper.acceptCash(money);
}
}
现金收费抽象类
public abstract class CashSuper {
public abstract double acceptCash(double money);
}
具体策略角色
正常收费子类
public class CashNormal extends CashSuper {
@Override
public double acceptCash(double money) {
return money;
}
}
打折收费子类
public class CashRebate extends CashSuper {
private double moneyRebate = 1; //折扣
public CashRebate(double moneyRebate) {
this.moneyRebate = moneyRebate;
}
@Override
public double acceptCash(double money) {
return money * moneyRebate;
}
}
返利收费子类
public class CashReturn extends CashSuper {
private double moneyConditation = 0.0; //返利条件
private double moneyReturn = 0.0d; //返利值
public CashReturn(double moneyConditation, double moneyReturn) {
this.moneyConditation = moneyConditation;
this.moneyReturn = moneyReturn;
}
@Override
public double acceptCash(double money) {
double result = money;
if (money >= moneyConditation) {
result = money - Math.floor(money / moneyConditation) * moneyReturn;
}
return result;
}
}
client客户端
public class Client {
public static void main(String[] args) {
CashContext cashContext = null;
Scanner scanner = new Scanner(System.in);
System.out.print("请输入打折方式(1/2/3):");
int in = scanner.nextInt();
String type = "";
switch (in) {
case 1:
cashContext = new CashContext(new CashNormal());
type += "正常收费";
break;
case 2:
cashContext = new CashContext(new CashReturn(300, 100));
type += "满300返100";
break;
case 3:
cashContext = new CashContext(new CashRebate(0.8));
type += "打8折";
break;
default:
System.out.println("请输入1/2/3");
break;
}
double totalPrices = 0;
System.out.print("请输入单价:");
double price = scanner.nextDouble();
System.out.print("请输入数量:");
double num = scanner.nextDouble();
totalPrices = cashContext.getResult(price * num);
System.out.println("单价:" + price + ",数量:" + num + ",类型:" + type + ",合计:" + totalPrices);
scanner.close();
}
}
请输入打折方式(1/2/3):1
请输入单价:100
请输入数量:5
单价:100,数量:5,类型:正常计费,合计:500.0
请输入打折方式(1/2/3):1
请输入单价:100
请输入数量:5
单价:100,数量:5,类型:满300反100,合计:400.0
请输入打折方式(1/2/3):1
请输入单价:100
请输入数量:5
单价:100,数量:5,类型:打八折,合计:400.0