设计模式GOF23--策略模式

场景

  • 某个市场人员接到单后的报价策略(CRM系统中常见问题)。报价策略很复杂,可以简单作如下分类:
    • 普通客户小批量报价
    • 普通客户大批量报价
    • 老客户小批量报价
    • 老客户大批量报价
  • 具体选用哪个报价策略,这需要根据实际情况来确定。这时候,我们采用策略模式即可。

普通代码实现

缺点:如果类型特别多,算法比较复杂时,整个条件控制代码会变得很长,难于维护

策略模式

  • 策略模式对应于解决某个问题的一个算法族,允许用户从该算法族中任选一个算法解决某一问题,同时可以方便的更换算法或者增加新的算法。并且由客户端解决调用哪个算法。

代码解析

通过策略模式实现以上场景

接口

1
2
3
public interface Strategy {
public double getPrice(double standarPrice);
}

具体算法包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
/**
* 普通客户小批量
*/
public class NewCustomerFewStrategy implements Strategy{
@Override
public double getPrice(double standarPrice) {
System.out.println("不打折,原价");
return standarPrice;
}
}
/**
* 普通客户大批量
*/
public class NewCustomerManyStrategy implements Strategy{
@Override
public double getPrice(double standarPrice) {
System.out.println("打9折");
return standarPrice*0.9;
}
}
/**
* 老客户小批量
*/
public class OldCustomerFewStrategy implements Strategy{
@Override
public double getPrice(double standarPrice) {
System.out.println("打8.5折");
return standarPrice*0.85;
}
}
/**
* 老客户大批量
*/
public class OldCustomerManyStrategy implements Strategy{
@Override
public double getPrice(double standarPrice) {
System.out.println("打8折");
return standarPrice*0.8;
}
}

上下文类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
* 上下文类
* 负责和具体的策略交互
*/
public class Context {
private Strategy strategy; //当前采用算法

public Context() {
}

//可以通过构造器注入
public Context(Strategy strategy) {
this.strategy = strategy;
}
//可以通过set方法注入
public void setStrategy(Strategy strategy) {
this.strategy = strategy;
}

public void printPrice(double s){
System.out.println("您该报价:"+strategy.getPrice(s));
}

}

调用

1
2
3
4
5
6
7
8
9
10
11
12
/**
* 策略模式
*/
public class Client {
public static void main(String[] args) {
//老客户
Strategy s1 = new OldCustomerManyStrategy();
Context context = new Context(s1);

context.printPrice(998);
}
}

本质

  • 分离算法,选择实现

开发中常见的场景

  • JAVASE中GUI编程中,布局管理
  • Spring框架中,Resource接口,资源访问策略
  • javax.servlet.http.HttpServlet#service()
注:该博文为学习总结,视频来源为高淇java300集