1.1 定义:
原文:Define a family of algorithms, encapsulate each one, and make them interchangeable.
翻译:定义一系列算法,将它们一个个封装起来,并且使它们之间可以相互替换。
策略模式也称为政策模式(Policy),让算法独立于使用它的客户而变化,且算法的变化不会影响到使用算法的客户。
1.2 开闭原则(OCP,Open Closed Principle):
原文:Software entities like classes,modules and functions should be open for extension but closed for modifications.
翻译:一个软件实体,如类,,模块,,函数等应该对扩展开放,对修改封闭。
可以通过创建新的策略类来扩展系统的功能,而不需要修改现有的代码。即对扩展开放,对修改关闭。
1.3 单一职责原则(SRP,Single Responsibility Principle):
原文: A class should have only one reason to change.
翻译:类发生更改的原因应该只有一个。
策略模式将不同的算法逻辑分离到不同的策略类中,每个策略类负责实现一种具体的算法。
1.4 理解、使用场景、优缺点
2.1 功能需求:
餐厅在付费的时候,会按照不同的角色类型,给予不同的优惠:
①学生在周末的时候可以享受88折优惠;学生且周末→88折
②学生在工作日的时候可以享受69折优惠;学生且工作日→69折
③非学生不享受优惠;非学生→无优惠
2.2 使用策略模式进行功能实现:

2.2.1 定义一个不同类型的枚举
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 支付类型枚举
*/
@Getter
@AllArgsConstructor
public enum PayTypeEnum {
/** 学生且周末 */
STUDENT_WEEKEND(1, "studentWeekendStrategy"),
/** 学生但工作日 */
STUDENT_WORKDAY(2, "studentWorkdayStrategy"),
/** 非学生 */
NOT_STUDENT(3, "notStudentStrategy")
;
/** 支付类型Code */
private final Integer payTypeCode;
/** 策略名称 */
private final String strategyName;
}
2.2.2 编写策略接口,给每一种策略都建立对应的策略类
①策略接口,IPayTypeStrategy
/**
* 支付策略接口
*/
public interface IPayTypeStrategy {
/**
* 执行支付逻辑
*/
void pay();
}
②学生且周末→88折策略实现,StudentWeekendStrategy
/**
* 学生且周末的支付策略
*/
@Component
public class StudentWeekendStrategy implements IPayTypeStrategy {
@Override
public void pay() {
// TODO
System.out.println("执行88折优惠");
}
}
③学生且工作日→69折策略实现,StudentWorkdayStrategy
/**
* 学生工作日的支付策略
*/
@Component
public class StudentWorkdayStrategy implements IPayTypeStrategy {
@Override
public void pay() {
// TODO
System.out.println("执行69折优惠");
}
}
④非学生→无优惠策略实现,NotStudentStrategy
/**
* 非学生的支付策略
*/
@Component
public class NotStudentStrategy implements IPayTypeStrategy {
@Override
public void pay() {
// TODO
System.out.println("没有优惠");
}
}
2.2.3 编写支付策略上下文对象管理类,PayTypeStrategyContext
/**
* @description 管理支付策略上下文对象
*/
@Component
public class PayTypeStrategyContext {
@Autowired
private Map<String, IPayTypeStrategy> payTypeStrategyMap = new HashMap<>();
public IPayTypeStrategy getType(PayTypeEnum payTypeEnum) {
return payTypeStrategyMap.get(payTypeEnum.getStrategyName());
}
}
2.2.4 功能测试
①策略模式业务层接口,IStrategyService
/**
* @description 策略模式业务接口
*/
public interface IStrategyService {
/**
* 使用策略模式支付
*/
void useStrategy(PayTypeEnum payTypeEnum);
}
②策略模式业务层接口实现类,StrategyServiceImpl
/**
* 策略模式业务层接口实现类
*/
@Service
public class StrategyServiceImpl implements IStrategyService {
@Autowired
private PayTypeStrategyContext payTypeStrategyContext;
@Override
public void useStrategy(PayTypeEnum payTypeEnum) {
IPayTypeStrategy strategy = payTypeStrategyContext.getType(payTypeEnum);
strategy.pay();
}
}
③编写策略模式测试接口,StrategyController
/**
* 策略模式测试接口
*/
@RestController
@RequestMapping("/test")
public class StrategyController {
@Autowired
private IStrategyService strategyService;
// http://localhost:8080/test/pay?payTypeEnum=STUDENT_WEEKEND
@GetMapping("/pay")
public void pay(@RequestParam PayTypeEnum payTypeEnum) {
strategyService.useStrategy(payTypeEnum);
}
}