定义:用不同的方式策略解决一个问题
在遇到一种问题有多种解法的时候,我们可以根据环境或者条件的不同选择不同的算法或者策略来完成该功能。在解决某一问题的时候制定多种策略(算法),不同情况选择不同的策略;
定义一系列的算法,把每一个算法封装起来, 并且使它们可相互替换;
应用:
营销方案、促销方案等等
特点:
- 策略模式是对象行为型模式 ,它关注行为和算法的封装 。
- 策略模式只是条件选择方法,只执行一次方法;
- 我们之前在选择出行方式的时候,往往会使用if-else语句,也就是用户不选择A那么就选择B这样的一种情况。这种情况耦合性太高了,而且代码臃肿,有了策略模式我们就可以避免这种现象,策略模式遵循开闭原则,实现代码的解耦合。
- 客户端必须知道所有的策略类,并自行决定使用哪一个策略类。策略模式会出现很多的策略类。
工厂+策略模式(用lambda来简化代码)
为经常要变化,扩展性要求比较高,这种时候可以考虑使用策略模式,来抽象行为,
工厂类放置所有的策略类实现(),提供一个获取策略的方法供使用
促销业务实现:不同的促销形式
/**
* @author jimmy
* 策略的函数式接口
*/
@FunctionalInterface
public interface PromotionStrategy {
void doPromotion();
}
/**
* @author jimmy
* 策略的工厂类
*/
public class PromotionStrategyFactory {
private static Map<String,PromotionStrategy> PROMOTION_STRATEGY_MAP = new HashMap<String, PromotionStrategy>();
static {
PROMOTION_STRATEGY_MAP.put(PromotionKey.LIJIAN,()->System.out.println("立减促销,课程的价格直接减去配置的价格"));
PROMOTION_STRATEGY_MAP.put(PromotionKey.FANXIAN,()->System.out.println("返现促销,返回的金额存放到慕课网用户的余额中"));
PROMOTION_STRATEGY_MAP.put(PromotionKey.MANJIAN,()->System.out.println("满减促销,满200-20元"));
}
private PromotionStrategyFactory(){
}
public static PromotionStrategy getPromotionStrategy(String promotionKey){
PromotionStrategy promotionStrategy = PROMOTION_STRATEGY_MAP.get(promotionKey);
return promotionStrategy == null ? ()->System.out.println("无促销活动") : promotionStrategy;
}
private interface PromotionKey{
String LIJIAN = "LIJIAN";
String FANXIAN = "FANXIAN";
String MANJIAN = "MANJIAN";
}
}
public class Test {
public static void main(String[] args) {
String promotionKey = "MANJIAN";
PromotionStrategyFactory.getPromotionStrategy(promotionKey).doPromotion();
}
}
策略模式在JDK-arrays应用的源码解析
可以在工厂中维护所有的策略实现类,如果需要添加新的策略,只需要更新工厂即可,不用修改其他的代码逻辑,在以前的条件行为用if...else,会导致到码冗余,不易于维护,代码耦合度高;
查询用策略模式
/**
* ORM查询策略
*/
public interface IStrategy<T> {
/**
* 测试方法
* @param t 要测试的对象
* @return 返回测试结果
*/
Boolean test(T t);
}
Controller
/**
* 职员控制器
* @author 大牧
* @version 1.0.0
*/
@RestController
@RequestMapping("/emp")
public class EmpController {
@Autowired
private EmpService empService;
@GetMapping("/list")
public List<Employee> getAllEmployee() {
return empService.getAllEmployee();
}
@GetMapping("/{id}")
public Employee getEmployeeById(@PathVariable String id) {
return empService.getEmplyeeById(id);
}
@GetMapping("/nickname/{nickname}")
public List<Employee> getEmployeeByNickname(@PathVariable String nickname) {
// return empService.getEmployeeByNickname(nickname);
return empService.getEmployeeByLambda(employee->employee.getNickname().contains(nickname));
}
@GetMapping("/empname/{empname}")
public List<Employee> getEmployeeByName(@PathVariable("empname") String name) {
// return empService.getEmployeeByName(name);
return empService.getEmployeeByLambda(employee->employee.getEmpName().contains(name));
}
}
service
/**
* 按照条件查询职员数据的方法
* @param strategy 条件策略
* @return 符合条件的职员数据
*/
public List<Employee> getEmployeeByLambda(IStrategy<Employee> strategy) {
List<Employee> list = null;
try {
list = empDAO.findByStrategy(strategy);
} catch (SQLException e) {
e.printStackTrace();
}
return list;
}
Dao
@Override
public List<Employee> findByStrategy(IStrategy strategy) throws SQLException {
list = this.findAll();
List<Employee> tempList = new ArrayList<>();
for (Employee employee : list) {
if (strategy.test(employee)) {
tempList.add(employee);
}
}
return tempList;
}
策略模式让我们在实现一种方式多种策略,算法策略提出来了,后续的变动只需要关注策略的变化,我们只需要用我们需要的策略算法,没有了if--else
我们之前在选择出行方式的时候,往往会使用if-else语句,也就是用户不选择A那么就选择B这样的一种情况。这种情况耦合性太高了,而且代码臃肿,有了策略模式我们就可以避免这种现象,策略模式遵循开闭原则,实现代码的解耦合。