策略工厂模式
1. 需求背景
现在需要你创建一个策略工厂类,来根据策略实现各种排序功能
2. 代码实现
2.1 定义基类接口
首先定义基类接口BaseStrategy
,获取策略名称
public interface BaseStrategy {
/**
* 获取策略名称
*/
String getStrategyName();
}
2.2 排序策略接口定义
其次,定义排序策略接口 SortStrategy
:
public interface SortStrategy extends BaseStrategy {
/**
* 对数组进行排序
* @param array 待排序的数组
*/
void sort(int[] array);
}
2.3 定义抽象类,实现策略接口
定义一个抽象类 AbstractSortStrategy,它实现了部分 SortStrategy 接口的功能,并留出 sort 方法需要被具体策略实现类实现
@Service
@Slf4j
public abstract class AbstractSortStrategy implements SortStrategy {
@Override
public abstract void sort(int[] array);
@Override
public abstract String getStrategyName();
protected void printStrategyUsed() {
log.info("使用 " + getStrategyName() + " 排序策略对数组排序");
}
}
2.4 具体的排序策略实现类
实现四种不同的排序算法作为具体策略:
冒泡排序:
@Component
public class BubbleSortStrategy extends AbstractSortStrategy {
@Override
public void sort(int[] array) {
int n = array.length;
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (array[j] > array[j + 1]) {
// 交换 array[j] 和 array[j + 1]
int temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
}
}
printStrategyUsed();
}
@Override
public String getStrategyName() {
return "冒泡排序";
}
}
插入排序:
@Component
public class InsertionSortStrategy extends AbstractSortStrategy {
@Override
public void sort(int[] array) {
int n = array.length;
for (int i = 1; i < n; i++) {
int key = array[i];
int j = i - 1;
while (j >= 0 && array[j] > key) {
array[j + 1] = array[j];
j--;
}
array[j + 1] = key;
}
printStrategyUsed();
}
@Override
public String getStrategyName() {
return "插入排序";
}
}
快速排序:
@Component
public class QuickSortStrategy extends AbstractSortStrategy {
@Override
public void sort(int[] array) {
quickSort(array, 0, array.length - 1);
printStrategyUsed();
}
private void quickSort(int[] array, int low, int high) {
if (low < high) {
int pi = partition(array, low, high);
quickSort(array, low, pi - 1);
quickSort(array, pi + 1, high);
}
}
private int partition(int[] array, int low, int high) {
int pivot = array[high];
int i = low - 1;
for (int j = low; j < high; j++) {
if (array[j] < pivot) {
i++;
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
int temp = array[i + 1];
array[i + 1] = array[high];
array[high] = temp;
return i + 1;
}
@Override
public String getStrategyName() {
return "快速排序";
}
}
选择排序:
@Component
public class SelectionSortStrategy extends AbstractSortStrategy {
@Override
public void sort(int[] array) {
int n = array.length;
for (int i = 0; i < n - 1; i++) {
int minIndex = i;
for (int j = i + 1; j < n; j++) {
if (array[j] < array[minIndex]) {
minIndex = j;
}
}
// 交换 array[i] 和 array[minIndex]
int temp = array[i];
array[i] = array[minIndex];
array[minIndex] = temp;
}
printStrategyUsed();
}
@Override
public String getStrategyName() {
return "选择排序";
}
}
2.5 实现策略工厂类
实现策略工厂类 SearchStrategyFactory
,用于管理和获取不同策略的实例:
@Component
@Slf4j
public class SortStrategyFactory implements ApplicationContextAware {
private static Map<String, SortStrategy> strategyMap = new HashMap<>();
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
Map<String, SortStrategy> map = applicationContext.getBeansOfType(SortStrategy.class);
log.info("初始化排序策略工厂,共找到 {} 个排序策略:", map.size());
map.forEach((key, value) -> {
strategyMap.put(value.getStrategyName(), value);
log.info("策略名称:{},策略类:{}", key, value.getClass().getSimpleName());
});
}
public <T extends SortStrategy> T getStrategy(String strategyName) {
SortStrategy strategy = strategyMap.get(strategyName);
if (strategy == null) {
log.error("获取策略失败,策略名称:{}",strategyName);
throw new BaseException(CommonErrorEnum.SYSTEM_ERROR);
}
return (T) strategy;
}
}
2.6 控制类
@RestController
@RequestMapping("/sort")
@Slf4j
public class SortController {
@Autowired
private SortStrategyFactory strategyFactory;
@GetMapping("/array")
public ResponseEntity<Map<String,String>> sortArray(@RequestParam String strategyName, @RequestParam int[] array) {
Map<String,String> result = new HashMap<>();
SortStrategy strategy = strategyFactory.getStrategy(strategyName);
strategy.sort(array);
// 返回排序后的数组
String sortedArray = Arrays.toString(array);
log.info("排序后的数组:{}", sortedArray);
result.put("排序结果", sortedArray);
result.put("排序策略", strategy.getStrategyName());
return ResponseEntity.ok(result);
}
}
项目完整目录结构
3. 启动测试
请求接口:
运行代码,打断点,结果如下:
结果如下:
4. 总结
ApplicationContextAware 接口实现: SortStrategyFactory
类实现了ApplicationContextAware
接口,并重写了 setApplicationContext
方法。在这个方法中,它获取了所有类型为 SortStrategy
的 Bean,并将它们存储在 strategyMap
中,以策略名称作为键,策略实例作为值。
getStrategy 方法: getStrategy
方法用于根据传入的策略名称 strategyName
,从 strategyMap
中获取对应的策略实例。如果找不到对应的策略实例,则记录错误日志并抛出 BaseException
异常。
代码:GitHub