什么是策略模式
策略模式是一种行为型模式,它将对象和行为分开,将行为定义为 一个行为接口
和 具体行为的实现.我的理解:就是将实现目标的方式多样化、代码化.用多种方式展现不同的处理方式.
策略模式的结构
Strategy(策略): 其实就是一个策略接口类,该接口可以定义很多目标(方法),就如下面实例中接口定义计算折扣的方法(calcPrice())
context: 上下文类,提供上下文和调用策略入口的作用.也就是在调用者和策略本身起到承上启下的作用
ConcreteStrategy:具体策略的实现类,如实例中的PrimaryMemberStrategy类、IntermediateMemberStrategy类、AdvanceMemberStrategy
实例
传统实现方式
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;
}
传统的实现方式,通过传统if代码判断。这样就会导致后期的维护性非常差。当后期需要新增计费方式,还需要在这里再加上if(),也不符合设计模式的开闭原则
// 普通会员——不打折
public class PrimaryMemberStrategy implements MemberStrategy { // 实现策略
//重写策略方法具体实现功能
@Override
public double calcPrice(double price, int n) {
return price * n;
}
}
策略实现方式
抽象类策略
package StrategyExercise;
public interface MemberStrategy {
// 一个计算价格的抽象方法
//price商品的价格 n商品的个数
public double calcPrice(double price, int n);
}
具体实现类
// 普通会员——不打折
public class PrimaryMemberStrategy implements MemberStrategy { // 实现策略
//重写策略方法具体实现功能
@Override
public double calcPrice(double price, int n) {
return price * n;
}
}
package StrategyExercise;
// 中级会员 打百分之10的折扣
public class IntermediateMemberStrategy implements MemberStrategy{
@Override
public double calcPrice(double price, int n) {
double money = (price * n) - price * n * 0.1;
return money;
}
}
package StrategyExercise;
// 高级会员类 20%折扣
public class AdvanceMemberStrategy implements MemberStrategy{
@Override
public double calcPrice(double price, int n) {
double money = price * n - price * n * 0.2;
return money;
}
}
上下文类
package StrategyExercise;
/**
* 负责和具体的策略类交互
* 这样的话,具体的算法和直接的客户端调用分离了,使得算法可以独立于客户端独立的变化。
*/
// 上下文类/环境类
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);
}
}
测试类
package StrategyExercise;
// 测试类
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));// 普通会员:300
System.out.println("中级会员的价格:"+ intermediateContext.qoutePrice(300,1));// 中级会员 270
System.out.println("高级会员的价格:"+ advanceContext.qoutePrice(300,1));// 高级会员240
}
}
运行结果
普通会员的价格:300.0
中级会员的价格:270.0
高级会员的价格:240.0
策略模式的优缺点
优点
- 策略模式提供了对“开闭原则”的完美支持,用户可以在不 修改原有系统的基础上选择算法或行为,也可以灵活地增加 新的算法或行为
- 策略模式提供了管理相关的算法族的办法
- 策略模式提供了可以替换继承关系的办法
- 使用策略模式可以避免使用多重条件转移语句
缺点
- 客户端必须知道所有的策略类,并自行决定使用哪一个策略类.
- 策略模式将造成产生很多策略类,可以通过使用享元模式在一 定程度上减少对象的数量