定义
它定义了算法家族,分别封装起来,让他们之间可以相互替换,此模式让算法的变化,不会影响到使用算法的客户。
允许用户从该算法族中任选一个算法解决某一问题,同时可以方便的更换算法或者新增算法。
本质:分离算法,选择实现。
结构图
- Strategy:策略类,定义所有支持算法的接口。
- ConcreteStrategy:具体的算法策略或行为,实现Strategy。
- Context:上下文,用一个ConcreteStrategy来配置,维护一个对Strategy的引用。
模拟场景
某一市场人员接到单价厚的报价策略(CRM系统中常见问题),实际中很复杂,现做如下分类:
- 普通用户小批量订单
- 普通用户大批量订单
- 老用户小批量订单
- 老用户大批量订单
具体选用那种报价策略,就看是什么用户了,此时采用策略模式来实现。
代码实现
- 创建策略接口Strategy
/**
* User:tumbler
* Desc:策略模式--策略接口:定义所有支持的算法的公共接口
*/
public interface Strategy {
/**
* 传入原价,通过算法后返回报价
* @param standardPrice
* @return
*/
double getPrice(double standardPrice);
}
- 创建具体策略算法类:普通客户小批量,普通客户大批量,老客户小批量,老客户大批量。
/**
* User:tumbler
* Desc:策略模式--具体算法类,实现策略Strategy接口
* 模拟普通用户小批量购物:原价卖出
*/
public class NewCustomerFewStrategy implements Strategy {
@Override
public double getPrice(double standardPrice) {
System.out.println("普通用户小批量:不打折,原价卖出!");
return standardPrice;
}
}
/**
* User:tumbler
* Desc:策略模式--具体算法类,实现策略Strategy接口
* 模拟普通用户大批量购物:打9折
*/
public class NewCustomerManyStrategy implements Strategy {
@Override
public double getPrice(double standardPrice) {
System.out.println("普通用户大批量:打9折!");
return standardPrice * 0.9;
}
}
/**
* User:tumbler
* Desc:策略模式--具体算法类,实现策略Strategy接口
* 模拟老客户小批量购物:打8折
*/
public class OldCustomerFewStrategy implements Strategy {
@Override
public double getPrice(double standardPrice) {
System.out.println("老客户小批量:打8折!");
return standardPrice * 0.8;
}
}
/**
* User:tumbler
* Desc:策略模式--具体算法类,实现策略Strategy接口
* 模拟老客户大批量购物:打7折
*/
public class OldCustomerManyStrategy implements Strategy {
@Override
public double getPrice(double standardPrice) {
System.out.println("老客户大批量:打7折!");
return standardPrice * 0.7;
}
}
- 上下文类Context
/**
* User:tumbler
* Desc:策略模式--上下文类
* 负责和具体的策略类交互
* 使具体的算法和客户端调用分离了,算法可以独立于客户端独立的变化
*
* 持有了策略类对象:可以通过构造方法,也可通过setter方法,如果使用Spring可用配置文件或者注解注入
*/
public class Context {
private Strategy strategy;
public Context(Strategy strategy) {
this.strategy = strategy;
}
public void setStrategy(Strategy strategy) {
this.strategy = strategy;
}
/**
* 打印报价
* @param standardPrice
*/
public void printPrice(double standardPrice) {
System.out.println("最终报价===" + strategy.getPrice(standardPrice));
}
}
- 测试类Client
/**
* User:tumbler
* Desc:策略模式--测试
*/
public class Client {
public static void main(String[] args) {
Strategy s1 = new OldCustomerManyStrategy();
Context context = new Context(s1);
context.printPrice(998);
}
}
运行结果:
老客户大批量:打7折!
最终报价===698.5999999999999
- UML图
开发中常见场景
- JavaSE中GUI编程中的布局管理
- Spring框架中Resource接口,资源访问策略
- javax.servlet.http.HttpServlet#service()