策略模式

是什么

策略模式是一种行为型设计模式,他定义了一系列算法来使用不同的策略完成同一件工作,并将每个算法封装起来,使他们可以相互替换,而算法的变化不影响算法的使用。

比如电商网站对于商品的折扣策略会有不同的算法,比如新用户满减优惠,不同等级会员的折扣情况也不同,这种情况下会有大量的if-else,如果修改优惠政策,还要修改原来的代码,不符合开闭原则。

于是可以将不同的优惠算法封装成独立的类来避免大量的条件语句,如果新增优惠算法,也只需要添加新的策略类来实现,不需要修改原来的代码,调用的时候直接用不同的类来选择不同的优惠策略;

基本结构

策略模式包含一下几个结构:

  • 策略接口Strategy:定义了所有支持的算法的各个接口
  • 具体策略类ConcreteStrategy:实现了策略接口,提供具体的算法实现
  • 上下文类Context:包含一个策略实例,并在需要的时候可以调用策略对象的方法

简单实现

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
41
42
43
44
45
46
47
48
49
50
51
// 1. 抽象策略抽象类
abstract class Strategy {
// 抽象方法
public abstract void algorithmInterface();
}

// 2. 具体策略类1
class ConcreteStrategyA extends Strategy {
@Override
public void algorithmInterface() {
System.out.println("Strategy A");
// 具体的策略1执行逻辑
}
}

// 3. 具体策略类2
class ConcreteStrategyB extends Strategy {
@Override
public void algorithmInterface() {
System.out.println("Strategy B");
// 具体的策略2执行逻辑
}
}

// 4. 上下文类
class Context {
private Strategy strategy;

// 设置具体的策略
public Context(Strategy strategy) {
this.strategy = strategy;
}

// 执行策略
public void contextInterface() {
strategy.algorithmlnterface();
}
}

// 5. 客户端代码
public class Main{
public static void main(String[] args) {
// 创建上下文对象,并设置具体的策略
Context contextA = new Context(new ConcreteStrategyA());
// 执行策略
contextA.contextInterface();

Context contextB = new Context(new ConcreteStrategyB());
contextB.contextInterface();u
}
}

使用场景

  • 当一个系统根据业务场景需要动态地在集中算法中选择一种的时候,可以采用策略模式,例如根据用户的行为选择不同的计费策略。
  • 代码中存在大量条件判断,条件判断的区别仅仅在于行为,也可以通过策略模式来消除这些条件语句。

在已有的工具库中,Java 标准库中的 Comparator 接口就使用了策略模式,通过实现这个接口,可以创建不同的比较器(指定不同的排序策略)来满足不同的排序需求。