简介

策略模式:策略模式是一种行为型模式,它将对象和行为分开,将行为定义为 一个行为接口 和 具体行为的实现。策略模式最大的特点是行为的变化,行为之间可以相互替换。每个if判断都可以理解为就是一个策略。本模式使得算法可独立于使用它的用户而变化

案例

假设现在要设计一个贩卖各类书籍的电子商务网站的购物车系统。一个最简单的情况就是把所有货品的单价乘上数量,但是实际情况肯定比这要复杂。比如,本网站可能对所有的高级会员提供每本20%的促销折扣;对中级会员提供每本10%的促销折扣;对初级会员没有折扣。

算法一:对初级会员没有折扣。
算法二:对中级会员提供10%的促销折扣。
算法三:对高级会员提供20%的促销折扣。

常规实现方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public Double calculationPrice(String type, Double originalPrice, int n) {

//中级会员计费
if (type.equals("intermediateMember")) {
return originalPrice * n - originalPrice * 0.1;
}
//高级会员计费
if (type.equals("advancePrimaryMember")) {
return originalPrice * n - originalPrice * 0.2;
}
//普通会员计费
return originalPrice;
}

策略模式实现

抽象类

1
2
3
4
public interface MemberStrategy {
public double calcPrice(double price, int n);

}

具体实现

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 PrimaryMemberStrategy implements MemberStrategy { // 实现策略
//重写策略方法具体实现功能
@Override
public double calcPrice(double price, int n) {
return price * n;
}
}
// 中级会员 打百分之10的折扣
public class IntermediateMemberStrategy implements MemberStrategy{
@Override
public double calcPrice(double price, int n) {
double money = (price * n) - price * n * 0.1;
return money;
}
}
// 高级会员类 20%折扣
public class AdvanceMemberStrategy implements MemberStrategy{
@Override
public double calcPrice(double price, int n) {
double money = price * n - price * n * 0.2;
return money;
}
}

上下文类(承上启下)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
* 负责和具体的策略类交互
* 这样的话,具体的算法和直接的客户端调用分离了,使得算法可以独立于客户端独立的变化。
*/

// 上下文类/环境类
public class MemberContext {
// 用户折扣策略接口
private MemberStrategy memberStrategy;

// 注入构造方法
public MemberContext(MemberStrategy memberStrategy) {
this.memberStrategy = memberStrategy;
}
// 计算价格
public double qoutePrice(double goodsPrice, int n){
// 通过接口变量调用对应的具体策略
return memberStrategy.calcPrice(goodsPrice, n);
}
}

测试类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 测试类
public class Application {
public static void main(String[] args) {

// 具体行为策略
MemberStrategy primaryMemberStrategy = new PrimaryMemberStrategy();
MemberStrategy intermediateMemberStrategy = new IntermediateMemberStrategy();
MemberStrategy advanceMemberStrategy = new AdvanceMemberStrategy();

// 用户选择不同策略
MemberContext primaryContext = new MemberContext(primaryMemberStrategy);
MemberContext intermediateContext = new MemberContext(intermediateMemberStrategy);
MemberContext advanceContext = new MemberContext(advanceMemberStrategy);

//计算一本300块钱的书
System.out.println("普通会员的价格:"+ primaryContext.qoutePrice(300,1));
System.out.println("中级会员的价格:"+ intermediateContext.qoutePrice(300,1));
System.out.println("高级会员的价格:"+ advanceContext.qoutePrice(300,1));
}
}

使用场景

  • 如果在一个系统里面有许多类,它们之间的区别仅在于它们 的行为,那么使用策略模式可以动态地让一个对象在许多行 为中选择一种行为。
  • 一个系统需要动态地在几种算法中选择一种。
  • 如果一个对象有很多的行为,如果不用恰当的模式,这些行 为就只好使用多重的条件选择语句来实现。
  • 不希望客户端知道复杂的、与算法相关的数据结构,在具体 策略类中封装算法和相关的数据结构,提高算法的保密性与 安全性。

常见的应用:

  1. 电商网站支付方式,一般分为银联、微信、支付宝
  2. 网站登录可以选择,微信,qq,邮箱等