设计模式源码git地址:design-pattern-src: 设计模式源码 (gitee.com)

  1. 定义
  2. 使用场景
  3. 角色
  4. 场景举例

定义

该模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户

使用场景

有些问题存在一题多解的情况,这时候往往需要if结构去判断调用其行为,可以考虑使用该模式

角色

抽象策略(Strategy):定义了一个公共接口,各种不同的算法以不同的方式实现这个接口,环境角色使用这个接口调用不同的算法,一般使用接口或抽象类实现。

具体策略(Concrete Strategy):实现了抽象策略定义的接口,提供具体的算法实现。

环境(Context):持有一个策略类的引用,最终给客户端调用。

场景举例

王老板打算去约会,打算考虑一种出行方案,既省钱又快速,方案如下

1、公交:1块/km,用时30分钟

2、打车:3km起步价5块,超1km加2块

3、单车:2块/5km

传统写法是这么调用的

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
public static int fee(String way,int distance) {
int trafficFee = 0;
switch (way) {
case "bus":
trafficFee = 1 * distance;
break;
case "didi":
if(distance<=3)
trafficFee = 5;
else
trafficFee=5+(distance-3)*2;
break;
case "bicycle":
trafficFee = 2 * distance/5;
break;
default:
break;
}
return trafficFee;
}
public static void main(String[] args) {
int s1 = fee("bus",5);
int s2 = fee("didi",5);
int s3 = fee("bicycle",5);
System.out.println(s1 + ":" + s2 +":"+ s3);
}

策略模式调用

1
2
3
4
5
6
public static void main(String[] args) {
Context c = new Context();
System.out.println("坐公交花费" + c.fee(new ByBus(), 5));
System.out.println("打车花费" + c.fee(new ByTaxi(), 5));
System.out.println("骑单车花费" + c.fee(new ByBicycle(), 5));
}

输出

1
2
3
坐公交花费5
打车花费9
骑单车花费2

策略抽象

1
2
3
public interface Strategy {
int calFee(int distance);
}

具体策略

1
2
3
4
5
6
7
8
9
10
11
12
13
public class ByTaxi implements Strategy{
//超过起步价每公里价格
private final static int TAXI_FEE = 2;
//起步价格
private final static int TAXI_START = 5;
//起步距离
private final static int TAXI_DISTANCE = 3;
@Override
public int calFee(int distance) {
return distance <= TAXI_DISTANCE ? TAXI_START : TAXI_START + (distance-TAXI_DISTANCE) * TAXI_FEE;
}
}
//只贴打车代码,其余可查看git

上下文

1
2
3
4
5
public class Context {
public int fee(Strategy strategy, int distance) {
return strategy.calFee(distance);
}
}

王老板思来想去,还是骑上了心爱的小单车