一、场景
- 某个市场人员接到订单后的报价策略(CRM系统中常见的问题)。报价策略很复杂,可以简单作如下分类:
- 普通客户小批量报价
- 普通客户大批量报价
- 老客户小批量报价
- 老客户大批量报价
当然我们可以使用条件语句,但是这很显然不利于扩展,难以维护
- 具体选用哪个报价策略,这需要根据实际情况来确定。这时候,我们采用策略模式即可。
二、策略模式
策略模式对应于解决某一个问题的一个算法族,允许用户从该算法族中任选一个算法解决某一问题,同时可以方便的更换算法或者增加新的算法。并且由客户端决定调用哪个算法
Strategy.java
package cn.itcast.day248.strategy;
//策略算法接口
public interface Strategy {
public double getPrice(double standardPrice);
}
NewCustFewStrategy.java
package cn.itcast.day248.strategy;
//普通客户小批量
public class NewCustFewStrategy implements Strategy{
@Override
public double getPrice(double standardPrice) {
System.out.println("普通客户小批量不打折");
return standardPrice;
}
}
NewCustManyStrategy.java
package cn.itcast.day248.strategy;
//普通客户大批量
public class NewCustManyStrategy implements Strategy{
@Override
public double getPrice(double standardPrice) {
System.out.println("普通客户大批量打九折");
return standardPrice * 0.9;
}
}
OldCustFewStrategy.java
package cn.itcast.day248.strategy;
//老客户小批量
public class OldCustFewStrategy implements Strategy{
@Override
public double getPrice(double standardPrice) {
System.out.println("老客户小批量打八五着");
return standardPrice * 0.85;
}
}
OldCustManyStrategy.java
package cn.itcast.day248.strategy;
//老客户大批量
public class OldCustManyStrategy implements Strategy{
@Override
public double getPrice(double standardPrice) {
System.out.println("老客户大批量八折");
return standardPrice * 0.8;
}
}
Context.java
package cn.itcast.day248.strategy;
//上下文类:负责和具体的策略类交互,使得算法可以独立于客户端
public class Context {
private Strategy strategy;//当前采用的算法
//可以使用构造方法、set方法、配置文件(spring中)注入相关的策略算法
public Context(Strategy strategy) {
this.strategy = strategy;
}
public void printPrice(double s){
System.out.println("报价应该为:" + strategy.getPrice(s));
}
}
说明:这里我们给出了策略算法的四种实现方式,然后使用上下文类老保存当前我们使用的策略算法,当然前提是我们需要将我们要使用的算法注入进去。这样便于客户端和具体的算法实现进行解耦。
Client.java
package cn.itcast.day248.strategy;
public class Client {
public static void main(String[] args) {
Strategy s1 = new OldCustManyStrategy();
Context ctx = new Context(s1);
ctx.printPrice(998);
}
}
三、开发中常见的场景
-
javaSE
中GUI
编程中的布局管理 -
Spring
框架中,Resource
接口,资源访问策略 javax.servlet.http.HttpServlet#service()