目录

[TOC]

参考

文档

廖雪峰的官方网站:https://www.liaoxuefeng.com/wiki/1252599548343744/1281319170474017

代码

https://gitee.com/xiao-i-fei/xiaofei-design-mode

https://github.com/xiao-i-fei/xiaofei-design-mode

应用场景

  • 食谱中的不同烹饪方法:在做菜时,可以使用不同的烹饪方法来制作美食。比如煮、炒、烤、蒸等。这些烹饪方法可以看作是不同的算法,使用策略模式可以让用户选择不同的烹饪方法来制作不同的菜品。
  • 购物清单中的不同购买策略:在购物时,可以使用不同的购买策略来获取更好的优惠和商品。比如打折、满减、团购等。这些购买策略可以看作是不同的算法,使用策略模式可以让用户选择不同的购买策略来获取更好的购物体验。
  • 旅游路线规划中的不同交通方式:在旅游时,可以选择不同的交通方式,比如飞机、火车、汽车、自驾等。这些交通方式可以看作是不同的算法,使用策略模式可以让用户选择不同的交通方式来规划旅游路线。
  • 健身计划中的不同训练方式:在健身时,可以选择不同的训练方式来达到锻炼效果。比如有氧运动、力量训练、瑜伽等。这些训练方式可以看作是不同的算法,使用策略模式可以让用户选择不同的训练方式来制定自己的健身计划。
  • 音乐推荐系统中的不同歌曲推荐策略:在听歌时,可以使用不同的歌曲推荐策略来发现新的音乐。比如基于相似度、基于热度、基于时间等。这些推荐策略可以看作是不同的算法,使用策略模式可以让用户选择不同的歌曲推荐策略来发现更多的好歌。
  • 社交网络中的不同好友推荐算法:在社交网络中,可以使用不同的好友推荐算法来发现新的朋友。比如基于兴趣、基于共同好友、基于地理位置等。这些推荐算法可以看作是不同的算法,使用策略模式可以让用户选择不同的好友推荐算法来扩大自己的社交圈。
  • 人脸识别中的不同特征提取算法:在人脸识别中,可以使用不同的特征提取算法来识别人脸。比如LBP、HOG、Eigenface等。这些特征提取算法可以看作是不同的算法,使用策略模式可以让系统选择不同的特征提取算法来提高人脸识别的准确性。
  • 自然语言处理中的不同文本清洗算法:在自然语言处理中,可以使用不同的文本清洗算法来处理文本数据。比如去除HTML标签、去除特殊字符、分词等。这些文本清洗算法可以看作是不同的算法,使用策略模式可以让系统选择不同的文本清洗算法来提高自然语言处理的效率和准确性。
  • 资源管理中的不同权限控制策略:在资源管理中,可以使用不同的权限控制策略来限制不同用户的操作权限。比如管理员拥有最高权限,普通用户只有部分权限。这些权限控制策略可以看作是不同的算法,使用策略模式可以让系统选择不同的权限控制策略来保护系统的安全性和稳定性。
  • 游戏AI中的不同行为策略:在游戏中,角色的行为可以看作是不同的算法,使用策略模式可以让游戏开发者封装不同的行为策略,让玩家可以选择自己喜欢的角色行为。
  • 游戏开发中的不同游戏难度设置:策略模式可以用于定义一系列的游戏难度选项,比如简单、普通、困难等。每个难度选项都有不同的游戏规则和操作方式,玩家可以根据自己的喜好选择不同的难度等级来体验游戏。
  • 数据库查询优化策略:在大型数据库中进行查询时,可以使用策略模式来封装不同的查询算法,比如全表扫描、索引扫描、分区查询等。这样可以让客户端代码与具体的查询算法解耦,同时提高查询效率。
  • 图像处理中的不同滤镜效果:滤镜是图像处理中常用的一种效果,比如模糊、锐化、色彩调整等。策略模式可以将这些滤镜算法封装起来,让客户端可以选择不同的滤镜效果,而不用关心具体的实现细节。
  • 网络通信中的数据压缩算法:在网络通信中,数据传输的效率非常重要。可以使用策略模式来封装不同的压缩算法,比如gzip、deflate等。这样可以让客户端根据需要选择不同的压缩算法来提高传输效率。
  • 机器学习中的不同分类器算法:在机器学习中,分类器是一种常用的模型。可以使用策略模式来封装不同的分类器算法,比如决策树、支持向量机、神经网络等。这样可以让客户端选择不同的分类器算法来适应不同的数据集和任务需求。
  • 自然语言处理中的不同文本解析算法:自然语言处理是一项复杂的任务,需要使用多种文本解析算法来实现。可以使用策略模式来封装这些算法,如正则表达式、词性标注、命名实体识别等。这样可以让客户端选择不同的解析算法来适应不同的文本格式和任务需求。
  • 操作系统中的进程调度策略:在操作系统中,进程调度是一个重要的任务。可以使用策略模式来封装不同的调度算法,如先来先服务(FCFS)、最短作业优先(SJF)、优先级调度等。这样可以让客户端选择不同的调度策略来适应不同的系统负载和任务需求。
  • 安全加密中的不同加密算法:在安全加密中,可以使用不同的加密算法来保护数据的安全性。可以使用策略模式来封装这些算法,如对称加密、非对称加密、哈希算法等。这样可以让客户端选择不同的加密算法来适应不同的安全需求。
  • 资源管理中的不同分配策略:在资源管理中,可以使用策略模式来封装不同的分配算法,如公平分配、轮流分配、优先级分配等。这样可以让客户端选择不同的分配策略来适应不同的场景需求。
  • 决策树算法中不同的划分策略:在决策树算法中,可以使用不同的划分策略来确定树的结构和叶子节点的位置。可以使用策略模式来封装这些策略,如ID3、C4.5等常见的决策树算法。这样可以让客户端选择不同的划分策略来适应不同的数据集和任务需求。

策略模式

Spring Boot中使用策略模式

image-20221127223516181

application.yml

1
2
3
# 在配置文件中选择
strategy:
upload: ali-yun-oss

autoconfigure

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Data
@Component
@ConfigurationProperties(prefix = "strategy")
public class StrategyModelProperties {

/**
* 文件上传执行策列选择
*/
private String upload;

}

enums

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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import lombok.AllArgsConstructor;
import lombok.Getter;

@Getter
@AllArgsConstructor
public enum UploadModeEnum {
/**
* 阿里云oss
*/
OSS("ali-yun-oss", "aliYunOssUploadStrategyImpl"),
/**
* 本地
*/
LOCAL("local", "localUploadStrategyImpl");

/**
* 模式
*/
private final String mode;

/**
* 策略
*/
private final String strategy;

/**
* 获取策略
*
* @param mode 模式
* @return {@link String} 文件上传执行策略策略
*/
public static String getStrategy(String mode) {
for (UploadModeEnum value : UploadModeEnum.values()) {
if (value.getMode().equals(mode)) {
return value.getStrategy();
}
}
return null;
}

}

context

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
27
28
29
30
31
32
package com.xiaofei.policy.strategy.context;

import com.xiaofei.policy.autoconfigure.StrategyModelProperties;
import com.xiaofei.policy.strategy.UploadStrategy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Map;

import static com.xiaofei.policy.enums.UploadModeEnum.getStrategy;

@Component
public class UploadStrategyContext {
/**
* 上传模式
*/
@Autowired
private StrategyModelProperties modelProperties;

@Autowired
private Map<String, UploadStrategy> uploadStrategyMap;

/**
* 上传文件
*
* @return {@link String} 文件地址
*/
public String executeUploadStrategy() {
return uploadStrategyMap.get(getStrategy(modelProperties.getUpload())).uploadFile();
}
}

strategy-interface

1
2
3
4
5
6
7
8
9
public interface UploadStrategy {

/**
* 上传文件
*
* @return {@link String} 文件地址
*/
String uploadFile();
}

strategy-interface-impl

OSSImpl

1
2
3
4
5
6
7
8
9
10
11
12
13
import com.xiaofei.policy.strategy.UploadStrategy;
import org.springframework.stereotype.Service;

@Service
public class AliYunOssUploadStrategyImpl implements UploadStrategy {
/**
* 本地文件上传
*/
@Override
public String uploadFile() {
return "阿里云文件上传";
}
}

LocalImpl

1
2
3
4
5
6
7
8
9
10
@Service
public class LocalUploadStrategyImpl implements UploadStrategy {
/**
* 本地文件上传
*/
@Override
public String uploadFile() {
return "本地文件上传";
}
}

TestController

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import com.xiaofei.policy.strategy.context.UploadStrategyContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping
public class TestController {

@Autowired
private UploadStrategyContext uploadStrategyContext;

@GetMapping
public String test() {
return uploadStrategyContext.executeUploadStrategy();
}
}

总结

策略模式是一种行为型设计模式,它允许在运行时选择算法的行为方式。策略模式的优点包括:

  • 可扩展性:策略模式可以动态地增加、修改和删除不同算法的实现,而不需要修改客户端代码。这样可以使系统更加灵活,易于维护和扩展。
  • 高内聚性:策略模式将算法封装成独立的策略类,每个算法类都有自己的职责和功能,从而提高了代码的内聚性。
  • 可复用性:策略模式可以将不同的算法封装成独立的策略类,从而可以在不同的系统中重用这些算法。这样可以减少代码的重复性,提高代码的可维护性和可读性。
  • 易扩展性:策略模式可以让用户选择不同的算法来适应不同的场景需求,从而提高了系统的可扩展性。
  • 松耦合性:策略模式将算法与客户端解耦,从而实现了算法与客户端的松耦合。这样可以提高系统的稳定性和可维护性。

策略模式的缺点包括:

  • 实现复杂度:策略模式需要实现多个独立的策略类来封装不同的算法,从而增加了系统的实现复杂度。
  • 性能损失:由于策略模式需要在运行时选择算法的行为方式,因此可能会带来一定的性能损失。
  • 限制较多:策略模式要求系统中必须有多种算法可供选择,否则无法发挥其优势。
  • 难以调试:由于策略模式将算法封装成了独立的策略类,因此在出现问题时很难定位问题所在。